Android Gradle: changer de version dynamique au moment de la construction
j'essaie d'imiter Maven release plugin dans Android en utilisant une version personnalisée de gradle-release plugin: https://github.com/townsfolk/gradle-release
L'intéressant, les étapes sont les suivantes:
- vérifier les changements non engagés
- Etape code de version et retirez -INSTANTANÉ suffixe du nom de la version
- Construire
- Étape nom de la version et ajoutez -INSTANTANÉ suffixe pour le prochain développement version
cependant L'APK générée a toujours les versions précédentes (i.e. 1.0.0-SNAPSHOT au lieu de 1.0.0).
les numéros de Version sont stockés et correctement mis à jour dans gradle.propriétés, donc je suppose que je dois mettre à jour les versions dans le modèle de données aussi bien pour les changements à prendre effet.
Mon android plugin config:
defaultConfig {
versionCode versionCode as int // taken from gradle.properties
versionName versionName // taken from gradle.properties
minSdkVersion 10
targetSdkVersion 19
}
Choses que j'ai essayé:
preBuild << {
android.applicationVariants.each { variant ->
variant.versionName = versionName
}
}
mais il n'y a pas de versionName dans un variante.
preBuild << {
android.buildTypes.each { type ->
type.versionName = versionName
}
}
mais il n'y a pas de versionName dans un type.
preBuild << {
android.productFlavors.each { flavor ->
flavor.versionName = versionName
}
}
mais il n'y a pas de saveurs dans mon application (débogage simple et les types de construction de libération seulement).
mon alternative est d'écrire un script bash / bat pour faire avancer les versions avant d'invoquer Gradle, ce qui va à peu près à l'encontre du but de L'utilisation de Groovy pour améliorer la personnalisation de la construction.
Comment puis-je mettre à jour les versions dynamiquement dans le plugin Android Gradle dans la phase d'exécution?
5 réponses
c'est ce Que buildTypes
sont en pour les. Ce que vous décrivez est un release
construction, IMO.
voici un exemple: lors de l'exécution assembleDebug
il va vous donner un instantané construire, et l'exécution assembleRelease
vous donnera une construction propre sans suffixe et numéro de version incrémenté. La prochaine version de débogage utilisera également le nombre incrémenté.
ce qui suit est une construction entièrement fonctionnelle lorsque les fichiers sont créés dans un dossier. Ça devrait aussi marcher avec les saveurs, mais c'est juste d'un côté produit :). Gradle 2.2.1, Android plugin 1.1.3
construire.gradle
apply plugin: 'com.android.application'
apply from: 'auto-version.gradle'
buildscript {
repositories { jcenter() }
dependencies { classpath 'com.android.tools.build:gradle:1.1.3' }
}
android {
buildToolsVersion = "21.1.2"
compileSdkVersion = "android-21"
buildTypes {
debug {
versionNameSuffix "-SNAPSHOT"
}
}
}
println "config code: ${calculateVersionCode()}, name: ${calculateVersionName()}"
src/main / AndroidManifest.xml
<manifest package="com.example" />
auto-version.gradle
ext {
versionFile = new File(project.rootDir, 'version.properties')
calculateVersionName = {
def version = readVersion()
return "${version['major']}.${version['minor']}.${version['build']}"
}
calculateVersionCode = {
def version = readVersion()
def major = version['major'] as int // 1..∞
def minor = version['minor'] as int // 0..99
def build = version['build'] as int // 0..999
return (major * 100 + minor) * 1000 + build
}
}
Properties readVersion() {
def version = new Properties()
def stream
try {
stream = new FileInputStream(versionFile)
version.load(stream)
} catch (FileNotFoundException ignore) {
} finally {
if (stream != null) stream.close()
}
// safety defaults in case file is missing
if(!version['major']) version['major'] = "1"
if(!version['minor']) version['minor'] = "0"
if(!version['build']) version['build'] = "0"
return version
}
void incrementVersionNumber() {
def version = readVersion()
// careful with the types, culprits: "9"++ = ":", "9" + 1 = "91"
def build = version['build'] as int
build++
version['build'] = build.toString()
def stream = new FileOutputStream(versionFile)
try {
version.store(stream, null)
} finally {
stream.close()
}
}
task incrementVersion {
description "Increments build counter in ${versionFile}"
doFirst {
incrementVersionNumber()
}
}
if (plugins.hasPlugin('android') || plugins.hasPlugin('android-library')) {
android {
defaultConfig {
versionName = calculateVersionName()
versionCode = calculateVersionCode()
}
afterEvaluate {
def autoIncrementVariant = { variant ->
if (variant.buildType.name == buildTypes.release.name) { // don't increment on debug builds
variant.preBuild.dependsOn incrementVersion
incrementVersion.doLast {
variant.mergedFlavor.versionName = calculateVersionName()
variant.mergedFlavor.versionCode = calculateVersionCode()
}
}
}
if (plugins.hasPlugin('android')) {
applicationVariants.all { variant -> autoIncrementVariant(variant) }
}
if (plugins.hasPlugin('android-library')) {
libraryVariants.all { variant -> autoIncrementVariant(variant) }
}
}
}
}
Exécuter gradle assembleDebug
pour construire normalement, gradle assembleRelease
pour incrémenter et de construire, et gradle incrementVersion
pour incrémenter seulement.
Note: attention, avec gradle assemble
parce que l'ordre de assembleDebug
et assembleRelease
donnera des résultats différents.
Vérifier les fichiers générés dans le build
répertoire pour voir si les valeurs sont à votre goût.
Manuel d'exécution (de commentaires)
il est possible que vous ayez plusieurs saveurs, auquel cas la version est incrémentée plusieurs fois parce que plusieurs variantes correspondent au type de construction de la version. La question originale n'était pas pour les saveurs. Si vous voulez avoir plus de contrôle lorsque le numéro de version est incrémenté seulement de supprimer les afterEvaluate
bloc et appeler le incrementVersion
tâche chaque fois que vous veux:
gradle incrementVersion assembleFreeRelease assemblePaidRelease
(l'exécution manuelle ci-dessus est une idée non testée.)
vérifier les changements non engagés
les "Check uncommitted changes" ne sont pas couverts dans cette réponse, c'est un autre jeu. Vous pourriez crochet tasks.preBuild.doFirst { /*fail here if uncommited changes*/ }
si je comprends bien. Mais cela dépend fortement de votre contrôle de version. Posez une autre question pour plus!
ceci ne répond pas directement à votre question sur la façon de changer complètement le versionName, mais c'est ce que j'utilise pour ajouter un suffixe pour mes types de construction:
defaultConfig {
versionName "1.0"
}
buildTypes {
debug {
versionNameSuffix "-SNAPSHOT"
}
}
j'ai dû ajouter le compte de propagation git actuel de la révision du code au nom de la version. Son réel à portée de main dans de nombreuses situation. Je me suis retrouvé avec le fichier gradle simple ci-dessous
apply plugin: 'com.android.application'
android {
compileSdkVersion 21
buildToolsVersion "21.1.2"
def gitCommitCount = "git rev-list HEAD --count".execute().text.trim()
defaultConfig {
applicationId "my.app.package.name"
minSdkVersion 16
targetSdkVersion 21
versionCode 6
versionName "0.8"
}
buildTypes {
debug {
versionNameSuffix ".${gitCommitCount}"
}
release {
versionNameSuffix ".${gitCommitCount}"
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
similaire à gitCommitCount, vous pouvez générer vos propres variables pour personnaliser le nom de la version. Comme je suis en train d'exécuter une commande de terminal pour stocker son résultat dans une variable.
j'ai simplement utilisé réponse de Javanator et l'a modifié un peu de sorte que commit count aide non seulement à changer le nom mais aussi à s'assurer que le code de version reste aussi unique. Voici un exemple de ce que j'ai fait (peut-être quelques choses peuvent être optimisées, mais fait néanmoins le travail pour moi) :
android {
compileSdkVersion 25
buildToolsVersion "25.0.2"
def gitCommitCount = "git rev-list HEAD --count".execute().text.trim().toBigInteger()
project.ext.set("versionCode", gitCommitCount)
project.ext.set("versionNameSuffix", "(${gitCommitCount})")
defaultConfig {
applicationId "my.app.package.name"
minSdkVersion 15
targetSdkVersion 25
versionCode project.versionCode
versionName "1.0"
versionNameSuffix project.versionNameSuffix
setProperty("archivesBaseName", "MyProject-$versionName")
....
}
signingConfigs {
config {
.........
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.config
}
}
packagingOptions {
.....
}
applicationVariants.all { variant ->
variant.outputs.each { output ->
output.outputFile = new File(
output.outputFile.parent,
output.outputFile.name.replace(".apk", "-${variant.versionName}.apk"))
}
}
}
Edit : Le dernier bit pourrait également être de la forme
applicationVariants.all { variant ->
if (variant.name.contains('release')) {
variant.outputs.each { output ->
variant.outputs.all {
outputFileName = "MyProject-${variant.versionName}${variant.versionCode}.apk"
}
}
}
}
j'étais confronté au même besoin d'avoir une logique de construction séparée pour les constructions de version et de non-Version. En plus d'utiliser des versions différentes, j'ai dû utiliser un ensemble différent de dépendances, même des dépôts différents.
aucun des plugins disponibles n'avait toutes les fonctionnalités dont j'avais besoin, donc j'ai développé ma propre solution, basée sur un simple argument approche - ligne de commande.
vous pouvez passer un paramètre de ligne de commande en invoquant le script de construction de gradle comme ceci:
gradle build -PmyParameter=myValue
ou dans mon cas
gradle build -PisRelease=true
Grad le comparera, et il sera automatiquement disponible comme propriété de l'objet du projet. Vous pouvez ensuite l'utiliser comme ceci:
if (project.isRelease) {
// Here be the logic!
}
j'ai extrait cette logique dans un plugin séparé, et je l'ai utilisé avec succès à travers différents projets.
bien que cela ne réponde pas directement à votre question, j'espère que je vous ai donné un autre angle pour réfléchir sur le problème et un autre possible solution.