AssembleRelease task dependency - запросить пароль хранилища ключей
Чтобы избежать написания пароля хранилища ключей в текстовом формате, я пытаюсь добавить зависимость для задачи assembleRelease, созданной плагином android Gradle.
Я проверил документацию Gradle Манипулирование существующими задачами, но я не могу разместить зависимость там, где она должна
Это моя задача, определенная в $root $/myApp/build.gradle над плагином Android.
task readPasswordFromInput << {
def console = System.console()
ext.keystorePassword = console.readLine('\n\n\n> Enter keystore password: ')
}
apply plugin: 'android'
Затем я пробовал две возможности, предлагаемые Gradle: task.dependsOn и task.doFirst, но никто не работает. Последнее, по-видимому, игнорируется, а dependOn добавляет зависимость, но слишком поздно в цепочке зависимостей. Выполнение задач. /gradlew - all выводит этот
:assembleRelease - Assembles all Release builds [libs:ActionBarSherlock:bundleRelease, libs:DataDroid:bundleRelease, libs:SlidingMenu:bundleRelease]
:compileRelease
...
[SEVERAL TASKS]
...
:packageRelease
...
[SEVERAL TASKS]
...
:readPasswordFromInput
Проблема заключается в том, что в пакете задач необходим пароль хранилища ключейRelease
Как примечание, это работает так, как я хочу
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, независимо от того, является ли он чистым или собираемым
Спасибо!
ИЗМЕНИТЬ
Благодаря @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
Ответы
Ответ 1
Недавно Google добавил официальный способ сделать это, см. https://developer.android.com/studio/publish/app-signing.html#secure-shared-keystore
Он может не отвечать на мой первоначальный вопрос (запрашивать пароль), но я считаю, что это лучший способ упростить развертывание и сохранить учетные данные в безопасности.
Ответ 2
попробовать:
tasks.whenTaskAdded { task ->
if (task.name == 'packageRelease') {
task.dependsOn readPasswordFromInput
}
}
с вашей задачей readPasswordFromInput
.
ОБНОВЛЕНО:
Таким образом вы можете видеть, что работает следующий код.
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
:
android {
...
signingConfigs {
releaseSign
}
...
Ответ 3
Это мое полное решение для подписания ключа выпуска.
- Он обнаруживает, что консоль недоступна в режиме демона.
- Он скрывает пароли.
Используйте 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
Ответ 4
Я создал решение, которое отлично работает для меня, вы можете проверить его
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 (использует readPassword
, поэтому он не будет виден), или вы можете передать их в качестве аргументов CLI для script
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"
Ответ 5
Вот что я делаю.
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 ""
}
}