2013-06-17 12 views
11

Aby uniknąć zapisywania hasła magazynu kluczy w postaci zwykłego tekstu, próbuję dodać zależność do zadania assembleRelease utworzonego przez wtyczkę Android Gradle.assembleRelease task dependence - Zapytaj o hasło magazynu kluczy

Sprawdziłem w dokumentacji Gradle Manipulating existing tasks ale jestem w stanie umieścić zależność gdzie powinien

To jest moje zadanie, zdefiniowane w $ korzeń $/myApp/build.gradle powyżej wtyczki android .

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

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

apply plugin: 'android' 

Następnie próbowałem dwie możliwości oferowanych przez Gradle: task.dependsOn i task.doFirst, ale nie działa. Ten ostatni wydaje się być ignorowany, podczas gdy dependOn dodaje zależność, ale zbyt późno w łańcuchu zależności. Uruchamianie ./gradlew zadania --all wydruki ten

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

Problemem jest hasło magazynu kluczy jest potrzebny w zadaniu packageRelease

Podobnie jak marginesie, to działa jak chcę

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

ale prosi o hasło za każdym razem, gdy korzystasz gradlew, bez względu na to czy jest to czysty lub montaż

Dzięki!

EDIT

Dzięki @Intae Kim, oto moja build.gradle wersja 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' 

Następnie buildTypes

release { 
    debuggable false 

    signingConfig signingConfigs.release 

    runProguard true 
    proguardFile 'my-file.txt' 
} 

Gradle wykona się poprawnie, ale to tylko generuje a release-unsigned.apk

Odpowiedz

11

spróbuj:

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

z zadaniem readPasswordFromInput.

AKTUALIZACJA:

W ten sposób można zobaczyć, że następujący kod działa.

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 
} 

i jeśli pojawią się budować nie, to może być zobowiązany do asign pusty keysign config na android.signingConfig:

android { 
    ... 
    signingConfigs { 
     releaseSign 
    } 
    ... 
+0

Dziękuję bardzo! Straciłem całą nadzieję na to^^. Zamierzam odpowiedzieć moim ostatecznym kodem, na razie zostawię twoją jako zaakceptowaną odpowiedź. – Maragues

+0

Dzięki Intae, jestem w stanie odczytać hasło, ale gradle wydaje się czytać go przy pierwszym przejściu i nie generuje podpisanego apk – Maragues

+1

[Ten link gist gint) (https://gist.github.com/jpeddicord/5710705) może ci pomóc. –

0

Oto, co robię.

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

Utworzyłem rozwiązanie, które działa dobrze dla mnie, można przetestować go

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

Następnie można przejść wszystkie argumenty z CLI na prompt (używa readPassword, więc nie będzie widoczny) lub można przekazać je jako argumenty CLI do skryptu

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" 
+0

skrypt jest ładny, ale myślę, że lepiej jest unikać używania haseł jako argumentów poleceń w powłoce - mogą one być później dostępne w historii powłoki. – snowdragon

+0

@snowdragon Myślę, że również dlatego skrypt pozwala na wpisanie ich w podpowiedziach, posiadanie ich w powłoce lub aliasie poleceń to tylko bonus –

5

to jest mój kompletne rozwiązanie do podpisywania klucza zwalniającego.

  1. Wykrywa, czy konsola nie jest dostępna w trybie demona.
  2. Ukrywa hasła.

Użyj gradle --no-daemon assembleRelease, jeśli używasz trybu demona.

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

Powiązane problemy