Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

assembleRelease task dependency - Ask for keystore password

Tags:

android

gradle

To avoid writing the keystore password in plain text, I'm trying to add a dependency to the assembleRelease task created by the android Gradle plugin.

I've checked the Gradle documentation Manipulating existing tasks but I'm unable to place the dependency where it should

This is my task, defined in $root$/myApp/build.gradle above the android plugin.

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

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

apply plugin: 'android'

Then, I've tried the two possibilities offered by Gradle: task.dependsOn and task.doFirst, but none works. The latter appears to be ignored, while dependsOn does add the dependency, but too late in the dependency chain. Running ./gradlew tasks --all prints this

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

The problem is, the keystore password is needed in the task packageRelease

Just as a side note, this works as I want

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
        }
    }

but it asks for the password every single time you use gradlew, no matter if it's a clean or an assemble

Thanks!

EDIT

Thanks to @Intae Kim, here's my build.gradle version 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'

Then, the buildTypes

release {
    debuggable false

    signingConfig signingConfigs.release

    runProguard true
    proguardFile 'my-file.txt'
}

Gradle executes correctly, but it only generates a release-unsigned.apk

like image 605
Maragues Avatar asked Jun 17 '13 10:06

Maragues


1 Answers

try:

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

with your readPasswordFromInput task.

UPDATED:

In this way you can see that following code works.

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
}

and if you encounter build fail, it may be required to asign an empty keysign config on android.signingConfig:

android {
    ...
    signingConfigs {
        releaseSign
    }
    ...
like image 69
Intae Kim Avatar answered Oct 18 '22 14:10

Intae Kim