J'essaie d'émuler le plugin de sortie Maven dans Android en utilisant une version personnalisée du plugin de sortie gradle: https://github.com/townsfolk/gradle-release =
Les étapes intéressantes sont:
Cependant, l'APK généré a toujours les versions précédentes (c'est-à-dire 1.0.0-SNAPSHOT au lieu de 1.0.0).
Les numéros de version sont stockés et correctement mis à jour dans gradle.properties, je suppose donc que je dois également mettre à jour les versions dans le modèle de données pour que les modifications prennent effet.
Ma Android:
defaultConfig {
versionCode versionCode as int // taken from gradle.properties
versionName versionName // taken from gradle.properties
minSdkVersion 10
targetSdkVersion 19
}
Choses que j'ai essayées:
preBuild << {
Android.applicationVariants.each { variant ->
variant.versionName = versionName
}
}
Mais il n'y a pas de versionName dans une 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 (types de version de débogage et de version simples uniquement).
Mon alternative est d'écrire un script bash/bat pour passer aux versions avant d'invoquer Gradle, ce qui va à peu près à l'encontre du but d'utiliser Groovy pour améliorer la personnalisation de la construction.
Comment puis-je mettre à jour les versions dynamiquement dans le Android plugin Gradle dans la phase d'exécution?
C'est à cela que servent buildTypes
. Ce que vous décrivez est une construction release
, IMO.
Voici un exemple: lors de l'exécution de assembleDebug
, il vous donnera une version instantanée, et l'exécution de assembleRelease
vous donnera une version propre sans suffixe et numéro de version incrémenté. La prochaine version de débogage utilisera également le numéro incrémenté.
Ce qui suit est une version entièrement fonctionnelle lorsque les fichiers sont créés dans un dossier. Cela devrait également fonctionner avec des saveurs, mais ce n'est qu'un produit secondaire :). Gradle 2.2.1, Android plugin 1.1.3
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()}"
<manifest package="com.example" />
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écutez gradle assembleDebug
pour construire normalement, gradle assembleRelease
pour incrémenter et construire, et gradle incrementVersion
pour simplement incrémenter. Remarque: soyez prudent avec gradle assemble
car l'ordre de assembleDebug
et assembleRelease
donnera des résultats différents.
Vérifiez les fichiers générés dans le répertoire build
pour voir si les valeurs vous conviennent.
Il est possible que vous ayez plusieurs versions, auquel cas la version est incrémentée plusieurs fois car plusieurs variantes correspondent au type de build de la version. La question d'origine était sans saveurs. Si vous souhaitez avoir plus de contrôle lorsque le numéro de version est incrémenté, supprimez simplement le bloc afterEvaluate
et appelez la tâche incrementVersion
quand vous le souhaitez:
gradle incrementVersion assembleFreeRelease assemblePaidRelease
(L'exécution manuelle ci-dessus est une idée non testée.)
Les "Vérifier les modifications non validées" ne sont pas couvertes dans cette réponse, c'est un autre jeu. Vous pouvez vous connecter à 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 en savoir plus!
J'avais besoin d'ajouter le décompte de validation git actuel de la révision de code au nom de la version. C'est vraiment pratique dans de nombreuses situations. Je me suis retrouvé avec un fichier gradle 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'
}
}
}
Semblable à gitCommitCount, vous pouvez générer vos propres variables pour personnaliser le nom de la version. Comme je suis juste en train d'exécuter une commande de terminal pour stocker son résultat dans une variable.
Cela ne répond pas directement à votre question de savoir comment modifier complètement le versionName, mais c'est ce que j'utilise pour ajouter un suffixe à mes buildTypes:
defaultConfig {
versionName "1.0"
}
buildTypes {
debug {
versionNameSuffix "-SNAPSHOT"
}
}
Je viens d'utiliser réponse de Javanator et de le modifier un peu pour que le nombre de validations aide non seulement à changer le nom, mais aussi à s'assurer que le code de version reste également unique. Voici un échantillon de ce que j'ai fait (Peut-être que deux choses peuvent être optimisées, mais font 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 aussi être comme
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é à un besoin similaire d'avoir une logique de génération distincte pour les versions publiées et non publiées. Mis à part les versions différentes, j'ai dû utiliser un ensemble différent de dépendances, même différents référentiels.
Aucun des plugins disponibles n'avait toutes les fonctionnalités dont j'avais besoin, j'ai donc développé ma propre solution, basée sur une approche simple - argument de ligne de commande.
Vous pouvez passer un paramètre de ligne de commande lors de l'appel du script de construction gradle comme ceci:
gradle build -PmyParameter = myValue
ou dans mon cas
gradle build -PisRelease = true
Gradle va l'analyser et il serait automatiquement disponible en tant que propriété de l'objet 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ée avec succès dans 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 au problème et une autre solution possible.