首页 文章

assembleRelease任务依赖 - 请求密钥库密码

提问于
浏览
11

为了避免以纯文本形式写入密钥库密码,我正在尝试为android Gradle插件创建的assembleRelease任务添加依赖项 .

我已经检查了Gradle文档Manipulating existing tasks但是我无法将依赖项放在应该的位置

这是我的任务,在android插件上方的$ root $ / myApp / build.gradle中定义 .

task readPasswordFromInput << {
    def console = System.console()

    ext.keystorePassword = console.readLine('\n\n\n> Enter keystore password: ')
}

apply plugin: 'android'

然后,我尝试了Gradle提供的两种可能性:task.dependsOn和task.doFirst,但没有一种可行 . 后者似乎被忽略了,而dependsOn确实添加了依赖,但在依赖链中却来得太晚了 . 运行./gradlew任务 - 都会打印出来

:assembleRelease - Assembles all Release builds [libs:ActionBarSherlock:bundleRelease, libs:DataDroid:bundleRelease, libs:SlidingMenu:bundleRelease]
    :compileRelease
    ...
    [SEVERAL TASKS]
    ...
    :packageRelease
    ...
    [SEVERAL TASKS]
    ...
    :readPasswordFromInput

问题是,任务packageRelease中需要密钥库密码

正如旁注,这是我想要的

buildTypes {
        release {
            def console = System.console()

            ext.keystorePassword = console.readLine('\n\n\n> IF building release apk, enter keystore password: ')

            debuggable false

            signingConfigs.release.storePassword = ext.keystorePassword
            signingConfigs.release.keyPassword = ext.keystorePassword

            signingConfig signingConfigs.release
        }
    }

但是每次使用gradlew它都要求输入密码,无论它是干净的还是组装的

谢谢!

EDIT

感谢@Intae Kim,这是我的build.gradle版本2.0

task readPasswordFromInput << {
    def console = System.console()

    ext.keystorePassword = console.readLine('\n\n\n> Enter keystore password: ')

    android.signingConfigs.release.storePassword = ext.keystorePassword
    android.signingConfigs.release.keyPassword = ext.keystorePassword
}

tasks.whenTaskAdded { task ->
    if (task.name == 'validateReleaseSigning') {
        task.dependsOn readPasswordFromInput
    }
}

apply plugin: 'android'

然后是buildTypes

release {
    debuggable false

    signingConfig signingConfigs.release

    runProguard true
    proguardFile 'my-file.txt'
}

Gradle正确执行,但它只生成release-unsigned.apk

5 回答

  • 0

    尝试:

    tasks.whenTaskAdded { task ->
        if (task.name == 'packageRelease') {
            task.dependsOn readPasswordFromInput
        }
    }
    

    与你的 readPasswordFromInput 任务 .

    UPDATED:

    通过这种方式,您可以看到以下代码的工作原理 .

    def runTasks = gradle.startParameter.taskNames
    if ('assemble' in runTasks || 'assembleRelease' in runTasks || 'a' in runTasks || 'aR' in runTasks) {
        android.signingConfigs.releaseSign.storeFile = file('/path/to/keystore')
        android.signingConfigs.releaseSign.storePassword = System.console().readLine('KeyStore Password: ')
        android.signingConfigs.releaseSign.keyAlias = ...
        android.signingConfigs.releaseSign.keyPassword = System.console().readLine('Alias Password: ')
        android.buildTypes.release.signingConfig = android.signingConfigs.releaseSign
    }
    

    如果遇到构建失败,可能需要在 android.signingConfig 上设置空的keyign配置:

    android {
        ...
        signingConfigs {
            releaseSign
        }
        ...
    
  • 0

    这是我发布密钥签名的完整解决方案 .

    • 它检测控制台在守护程序模式下是否不可用 .

    • 它隐藏密码 .

    如果您正在使用守护程序模式,请使用 gradle --no-daemon assembleRelease .

    buildscript {
        repositories {
            mavenCentral()
        }
    
        dependencies {
            classpath 'com.android.tools.build:gradle:0.5.+'
        }
    }
    
    tasks.whenTaskAdded { task ->
        if (task.name == 'validateReleaseSigning')
            task.dependsOn keystoreInfo
    }
    
    apply plugin: 'android'
    
    repositories {
        mavenCentral()
    }
    
    android {
        compileSdkVersion 18
        buildToolsVersion '18.0.1'
    
        defaultConfig {
            minSdkVersion 7
            targetSdkVersion 18
        }
    
        signingConfigs {
            release {
                release {
                    storeFile file('release.keystore')
                    storePassword ''
                    keyAlias ''
                    keyPassword ''
                }
            }
    
            buildTypes {
                release {
                    debuggable false
                    signingConfig signingConfigs.release
                }
            }
        }
    }
    
    task keystoreInfo << {
        def console = System.console()
        if (console == null)
            throw new IllegalStateException('no console available, use --no-daemon flag')
    
        def storeFile = console.readLine('Keystore: ')
        def storePassword = console.readPassword('Keystore password: ')
        def keyAlias = console.readLine('Key alias: ')
        def keyPassword = console.readPassword('Key password: ')
    
        android.signingConfigs.release.storeFile = file(storeFile)
        android.signingConfigs.release.storePassword = new String(storePassword)
        android.signingConfigs.release.keyAlias = keyAlias
        android.signingConfigs.release.keyPassword = new String(keyPassword)
    }
    

    Gist http://gist.github.com/grzegorz-zur/6416924

  • 5

    我已经创建了解决方案,对我来说很好,你可以测试一下

    android { 
        signingConfigs {
            release {
                storeFile = file('android.keystore')
                keyAlias = "my_key_alias"
            }
        }
    
        buildTypes {
            release {
                signingConfig signingConfigs.release
            }
        }
    }
    
    task readPasswordFromInput << {
        if(!project.hasProperty('keyStore') || !project.hasProperty('keyPass') || !project.hasProperty('storePass')) {
            println "\n\$ Enter signing details manually or run with \"-PkeyStore={key.store.name} -PstorePass={StoreSecretPassword} -PkeyPass={KeySecretPassword}\""   
        }
    
        if(!project.hasProperty('keyStore')) {
            def newKeyStore = System.console().readLine("\n\$ Enter keystore location or enter (default: android.keystore): ")
            if(newKeyStore != '') android.signingConfigs.release.storeFile = file('${newKeyStore}')
        } else {
            android.signingConfigs.release.storeFile = file(project.keyStore)
        }
    
        android.signingConfigs.release.storePassword = project.hasProperty('storePass') ? project.storePass : new String(System.console().readPassword("\$ Store password: "))
            android.signingConfigs.release.keyPassword = project.hasProperty('keyPass') ? project.keyPass : new String(System.console().readPassword("\$ Key password: "))
    }
    
    tasks.whenTaskAdded { task ->
        if (task.name == 'validateReleaseSigning') {
            task.dependsOn readPasswordFromInput
        }
    }
    

    然后你可以在CLI上传递来自CLI的所有参数(使用 readPassword ,因此它不可见)或者你可以将它们作为CLI参数传递给脚本

    gradle assemble
    gradle assemble -PkeyStore="~/.android/my.keystore"
    gradle assemble -PkeyStore="~/.android/my.keystore" -PstorePass="MyStorePass"
    gradle assemble -PkeyStore="~/.android/my.keystore" -PstorePass="MyStorePass" -PkeyPass="MyKeyPass"
    
  • 3

    这就是我的工作 .

    task('readPasswordFromInput') << {
        def console = System.console()
    
        ext.keystorePassword = console.readLine('\n\n\n> Enter keystore password: ')
    
        android.signingConfigs.release.storePassword = ext.keystorePassword
        android.signingConfigs.release.keyPassword = ext.keystorePassword
    }
    
    tasks.whenTaskAdded { task ->
        if (task.name.matches("validateReleaseSigning")) {
            task.dependsOn('readPasswordFromInput')
        }
    }
    
    
    signingConfigs {
        debug {
            storeFile file("my-debug-key.keystore")
        }
    
        release {
            storeFile file("my-release-key.keystore")
            storePassword ""
            keyAlias "release_key"
            keyPassword ""
        }
    }
    
  • 11

    Google最近添加了官方方法,请参阅https://developer.android.com/studio/publish/app-signing.html#secure-shared-keystore

    它可能无法回答我原来的问题(要求输入密码),但我认为这是简化部署和保证凭证安全的更好方法 .

相关问题