J'essaie de configurer le processus de signature de sorte que le mot de passe du fichier de clés et le mot de passe de la clé ne sont pas soient stockés dans le fichier build.gradle
Du projet.
Actuellement, j'ai les éléments suivants dans le build.gradle
:
Android {
...
signingConfigs {
release {
storeFile file("my.keystore")
storePassword "store_password"
keyAlias "my_key_alias"
keyPassword "key_password"
}
}
buildTypes {
release {
signingConfig signingConfigs.release
}
}
}
Cela fonctionne parfaitement bien mais je ne doit pas mettre les valeurs pour le storePassword
et le keyPassword
dans mon référentiel. Je préférerais ne pas y mettre storeFile
et keyAlias
.
Y a-t-il un moyen de modifier le build.gradle
Pour qu'il obtienne les mots de passe d'une source externe (comme un fichier résidant sur mon ordinateur uniquement)?
Et bien sûr, le build.gradle
Modifié devrait être utilisable sur tout autre ordinateur (même si l'ordinateur n'a pas accès aux mots de passe).
J'utilise Android Studio et Maverics sous Mac OS X, le cas échéant).
La bonne chose à propos de Groovy est que vous pouvez librement mélanger du code Java), et il est assez facile de lire un fichier clé/valeur en utilisant Java.util.Properties
. Il existe peut-être un moyen encore plus simple d’utiliser Groovy idiomatique, mais Java est encore assez simple.
Créer un keystore.properties
fichier (dans cet exemple, dans le répertoire racine de votre projet à côté de settings.gradle
, bien que vous puissiez le placer où bon vous semble:
storePassword=...
keyPassword=...
keyAlias=...
storeFile=...
Ajoutez ceci à votre build.gradle
:
allprojects {
afterEvaluate { project ->
def propsFile = rootProject.file('keystore.properties')
def configName = 'release'
if (propsFile.exists() && Android.signingConfigs.hasProperty(configName)) {
def props = new Properties()
props.load(new FileInputStream(propsFile))
Android.signingConfigs[configName].storeFile = file(props['storeFile'])
Android.signingConfigs[configName].storePassword = props['storePassword']
Android.signingConfigs[configName].keyAlias = props['keyAlias']
Android.signingConfigs[configName].keyPassword = props['keyPassword']
}
}
}
Sinon, si vous souhaitez appliquer la réponse de Scott Barta d'une manière plus similaire au code de gradation généré automatiquement, vous pouvez créer un keystore.properties
fichier dans le dossier racine de votre projet:
storePassword=my.keystore
keyPassword=key_password
keyAlias=my_key_alias
storeFile=store_file
et modifiez votre code de classement pour:
// Load keystore
def keystorePropertiesFile = rootProject.file("keystore.properties");
def keystoreProperties = new Properties()
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
...
Android{
...
signingConfigs {
release {
storeFile file(keystoreProperties['storeFile'])
storePassword keystoreProperties['storePassword']
keyAlias keystoreProperties['keyAlias']
keyPassword keystoreProperties['keyPassword']
}
}
...
}
Vous pouvez stocker ce fichier de propriétés à la racine de votre module, auquel cas il suffit d'omettre rootProject
, et vous pouvez également modifier ce code pour avoir plusieurs ensembles de propriétés pour différents magasins de clés et alias de clés.
Le moyen le plus simple consiste à créer un fichier ~/.gradle/gradle.properties
.
Android_STORE_PASSWORD=hunter2
Android_KEY_PASSWORD=hunter2
Votre fichier build.gradle
Peut alors ressembler à ceci:
Android {
signingConfigs {
release {
storeFile file('yourfile.keystore')
storePassword Android_STORE_PASSWORD
keyAlias 'youralias'
keyPassword Android_KEY_PASSWORD
}
}
buildTypes {
release {
signingConfig signingConfigs.release
}
}
}
Après avoir lu quelques liens:
http://blog.macromates.com/2006/keychain-access-from-Shell/http://www.thoughtworks.com/es/insights/blog/signing-open -source-applications-android-sans-divulgation-mots-de-passe
Puisque vous utilisez Mac OSX, vous pouvez utiliser le trousseau d'accès pour stocker vos mots de passe.
Ensuite, dans vos scripts Gradle:
/* Get password from Mac OSX Keychain */
def getPassword(String currentUser, String keyChain) {
def stdout = new ByteArrayOutputStream()
def stderr = new ByteArrayOutputStream()
exec {
commandLine 'security', '-q', 'find-generic-password', '-a', currentUser, '-gl', keyChain
standardOutput = stdout
errorOutput = stderr
ignoreExitValue true
}
//noinspection GroovyAssignabilityCheck
(stderr.toString().trim() =~ /password: '(.*)'/)[0][1]
}
Utilisez comme ceci:
getPassword (currentUser, "Android_Store_Password")
/* Plugins */
apply plugin: 'com.Android.application'
/* Variables */
ext.currentUser = System.getenv("USER")
ext.userHome = System.getProperty("user.home")
ext.keystorePath = 'KEY_STORE_PATH'
/* Signing Configs */
Android {
signingConfigs {
release {
storeFile file(userHome + keystorePath + project.name)
storePassword getPassword(currentUser, "Android_STORE_PASSWORD")
keyAlias 'jaredburrows'
keyPassword getPassword(currentUser, "Android_KEY_PASSWORD")
}
}
buildTypes {
release {
signingConfig signingConfigs.release
}
}
}
C'est comme ça que je le fais. Utiliser les variables d'environnement
signingConfigs {
release {
storeFile file(System.getenv("KEYSTORE"))
storePassword System.getenv("KEYSTORE_PASSWORD")
keyAlias System.getenv("KEY_ALIAS")
keyPassword System.getenv("KEY_PASSWORD")
}
La réponse acceptée utilise un fichier pour contrôler le magasin de clés à utiliser pour signer le fichier APK qui réside dans le même dossier racine du projet. Lorsque nous utilisons vcs comme Git , cela peut être une mauvaise chose d’oublier d’ajouter le fichier de propriétés à ignorer. Parce que nous allons divulguer notre mot de passe au monde. Les problèmes persistent encore.
Au lieu de créer un fichier de propriétés dans le même répertoire de notre projet, nous devrions le faire en dehors. Nous le faisons à l'extérieur en utilisant le fichier gradle.properties.
Voici les étapes:
1. Modifiez ou créez gradle.properties sur votre projet racine et ajoutez le code suivant. N'oubliez pas de modifier le chemin avec le vôtre:
AndroidProject.signing=/your/path/androidproject.properties
2.Créez androidproject.properties dans/votre/chemin/et ajoutez-y le code suivant, n'oubliez pas de changer le paramètre /your/path/to/Android.keystore en votre chemin de magasin de clés:
STORE_FILE=/your/path/to/Android.keystore
STORE_PASSWORD=yourstorepassword
KEY_ALIAS=yourkeyalias
KEY_PASSWORD=yourkeypassword
3.Dans votre module d'application build.gradle (pas votre build.gradle racine du projet), ajoutez le code suivant s'il n'existe pas ou ajustez-le:
signingConfigs {
release
}
buildTypes {
debug {
debuggable true
}
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-Android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
}
}
4.Ajoutez le code suivant sous le code de l'étape 3:
if (project.hasProperty("AndroidProject.signing")
&& new File(project.property("AndroidProject.signing").toString()).exists()) {
def Properties props = new Properties()
def propFile = new File(project.property("AndroidProject.signing").toString())
if(propFile.canRead()) {
props.load(new FileInputStream(propFile))
if (props!=null && props.containsKey('STORE_FILE') && props.containsKey('STORE_PASSWORD') &&
props.containsKey('KEY_ALIAS') && props.containsKey('KEY_PASSWORD')) {
Android.signingConfigs.release.storeFile = file(props['STORE_FILE'])
Android.signingConfigs.release.storePassword = props['STORE_PASSWORD']
Android.signingConfigs.release.keyAlias = props['KEY_ALIAS']
Android.signingConfigs.release.keyPassword = props['KEY_PASSWORD']
} else {
println 'androidproject.properties found but some entries are missing'
Android.buildTypes.release.signingConfig = null
}
} else {
println 'androidproject.properties file not found'
Android.buildTypes.release.signingConfig = null
}
}
Ce code va rechercher la propriété AndroidProject.signing dans gradle.properties à partir de étape 1. Si la propriété est trouvée, elle convertira la valeur de la propriété en chemin de fichier qui pointe vers androidproject.properties que nous créons dans étape 2. Ensuite, toute la valeur de la propriété sera utilisée comme configuration de signature pour notre build.gradle.
Désormais, nous n'avons plus besoin de craindre le risque de divulgation du mot de passe de notre magasin de clés.
En savoir plus sur Signature Android apk sans mettre les informations du magasin de clés dans le fichier build.gradle
Il est possible de prendre n'importe quel projet Android Studio Gradle et de le construire/le signer à partir de la ligne de commande sans éditer aucun fichier. Ceci le rend très pratique pour stocker votre projet dans le contrôle de version tout en conservant vos clés et les mots de passe sont séparés et non dans votre fichier build.gradle:
./gradlew assembleRelease -Pandroid.injected.signing.store.file=$KEYFILE -Pandroid.injected.signing.store.password=$STORE_PASSWORD -Pandroid.injected.signing.key.alias=$KEY_ALIAS -Pandroid.injected.signing.key.password=$KEY_PASSWORD
Pour ceux qui cherchent à mettre leurs identifiants dans un fichier JSON externe et à le lire dans le dégradé, voici ce que j'ai fait:
mon_projet/credentials.json:
{
"Android": {
"storeFile": "/path/to/acuity.jks",
"storePassword": "your_store_password",
"keyAlias": "your_Android_alias",
"keyPassword": "your_key_password"
}
}
mon_projet/Android/app/build.gradle
// ...
signingConfigs {
release {
def credsFilePath = file("../../credentials.json").toString()
def credsFile = new File(credsFilePath, "").getText('UTF-8')
def json = new groovy.json.JsonSlurper().parseText(credsFile)
storeFile file(json.Android.storeFile)
storePassword = json.Android.storePassword
keyAlias = json.Android.keyAlias
keyPassword = json.Android.keyPassword
}
...
buildTypes {
release {
signingConfig signingConfigs.release //I added this
// ...
}
}
}
// ...
}
La raison pour laquelle j'ai choisi un .json
type de fichier, et non un .properties
type de fichier (comme dans la réponse acceptée), c’est parce que je voulais également stocker d’autres données (autres propriétés personnalisées dont j'avais besoin) dans ce même fichier (my_project/credentials.json
), et demandez toujours à Gradle d’analyser également les informations de signature contenues dans ce fichier.
Cette question a reçu de nombreuses réponses valables, mais je voulais partager mon code qui pourrait être utile pour responsables de la bibliothèque, car laisse l'original build.gradle
assez propre.
J'ajoute un dossier au répertoire du module dans lequel je gitignore
. Cela ressemble à ceci:
/signing
/keystore.jks
/signing.gradle
/signing.properties
keystore.jks
et signing.properties
devrait être explicite. Et signing.gradle
ressemble à ça:
def propsFile = file('signing/signing.properties')
def buildType = "release"
if (!propsFile.exists()) throw new IllegalStateException("signing/signing.properties file missing")
def props = new Properties()
props.load(new FileInputStream(propsFile))
def keystoreFile = file("signing/keystore.jks")
if (!keystoreFile.exists()) throw new IllegalStateException("signing/keystore.jks file missing")
Android.signingConfigs.create(buildType, {
storeFile = keystoreFile
storePassword = props['storePassword']
keyAlias = props['keyAlias']
keyPassword = props['keyPassword']
})
Android.buildTypes[buildType].signingConfig = Android.signingConfigs[buildType]
Et l'original build.gradle
apply plugin: 'com.Android.application'
if (project.file('signing/signing.gradle').exists()) {
apply from: 'signing/signing.gradle'
}
Android {
compileSdkVersion 27
defaultConfig {
applicationId ...
}
}
dependencies {
implementation ...
}
Comme vous pouvez le constater, vous n'avez pas du tout besoin de spécifier les buildTypes. Si l'utilisateur a accès à un répertoire valide signing
, il le met simplement dans le module et peut créer une application valide signée, sinon cela fonctionne pour lui comme il le ferait normalement.
Vous pouvez demander des mots de passe à partir de la ligne de commande:
...
signingConfigs {
if (gradle.startParameter.taskNames.any {it.contains('Release') }) {
release {
storeFile file("your.keystore")
storePassword new String(System.console().readPassword("\n\$ Enter keystore password: "))
keyAlias "key-alias"
keyPassword new String(System.console().readPassword("\n\$ Enter keys password: "))
}
} else {
//Here be dragons: unreachable else-branch forces Gradle to create
//install...Release tasks.
release {
keyAlias 'dummy'
keyPassword 'dummy'
storeFile file('dummy')
storePassword 'dummy'
}
}
}
...
buildTypes {
release {
...
signingConfig signingConfigs.release
}
...
}
...
Cette réponse est apparue précédemment: https://stackoverflow.com/a/33765572/3664487