78 votes

Comment auto-incrémenter le code de version dans Android Gradle ?

Je suis en train d'expérimenter un nouveau système de construction Android basé sur Gradle et je me demande quelle est la meilleure façon d'augmenter automatiquement le code de version avec ce système. Je pense à deux options

  1. créer le fichier versionCode, y lire le numéro, l'augmenter et le réécrire dans le fichier
  2. analyse le fichier AndroidManifest.xml, lit le code de version, l'augmente et le réécrit dans le fichier AndroidManifest.xml.

Existe-t-il une solution plus simple ou plus adaptée ?

Est-ce que quelqu'un a utilisé l'une de ces options et pourrait la partager avec moi ?

0 votes

Lecture d'un version.properties fichier stackoverflow.com/a/21405744

58voto

sealskej Points 2356

J'ai décidé de choisir la deuxième option - analyser AndroidManifest.xml . Voici un extrait de travail.

task('increaseVersionCode') << {
    def manifestFile = file("AndroidManifest.xml")
    def pattern = Pattern.compile("versionCode=\"(\\d+)\"")
    def manifestText = manifestFile.getText()
    def matcher = pattern.matcher(manifestText)
    matcher.find()
    def versionCode = Integer.parseInt(matcher.group(1))
    def manifestContent = matcher.replaceAll("versionCode=\"" + ++versionCode + "\"")
    manifestFile.write(manifestContent)
}

tasks.whenTaskAdded { task ->
    if (task.name == 'generateReleaseBuildConfig') {
        task.dependsOn 'increaseVersionCode'
    }
}

versionCode est validé pour les builds de version dans ce cas. Pour l'augmenter pour les builds de débogage, changez l'équation task.name en task.whenTaskAdded le rappel.

5 votes

Une question : comment intégrer ces codes dans le système de construction de Cradle ?

0 votes

De même, une réponse un peu plus propre ne modifie pas le XML en place, mais conserve le numéro de version dans un fichier props : stackoverflow.com/questions/21405457/

1 votes

Changez simplement le fichier("AndroidManifest.xml") en fichier("src/main/AndroidManifest.xml") si vous utilisez la nouvelle structure de projet.

39voto

Andres Points 303

J'utilise ce code pour mettre à jour à la fois le code de version et le nom de version, en utilisant un schéma "major.minor.patch.build".

import java.util.regex.Pattern

task('increaseVersionCode') << {
    def manifestFile = file("src/main/AndroidManifest.xml")
    def pattern = Pattern.compile("versionCode=\"(\\d+)\"")
    def manifestText = manifestFile.getText()
    def matcher = pattern.matcher(manifestText)
    matcher.find()
    def versionCode = Integer.parseInt(matcher.group(1))
    def manifestContent = matcher.replaceAll("versionCode=\"" + ++versionCode + "\"")
    manifestFile.write(manifestContent)
}

task('incrementVersionName') << {
    def manifestFile = file("src/main/AndroidManifest.xml")
    def patternVersionNumber = Pattern.compile("versionName=\"(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)\"")
    def manifestText = manifestFile.getText()
    def matcherVersionNumber = patternVersionNumber.matcher(manifestText)
    matcherVersionNumber.find()
    def majorVersion = Integer.parseInt(matcherVersionNumber.group(1))
    def minorVersion = Integer.parseInt(matcherVersionNumber.group(2))
    def pointVersion = Integer.parseInt(matcherVersionNumber.group(3))
    def buildVersion = Integer.parseInt(matcherVersionNumber.group(4))
    def mNextVersionName = majorVersion + "." + minorVersion + "." + pointVersion + "." + (buildVersion + 1)
    def manifestContent = matcherVersionNumber.replaceAll("versionName=\"" + mNextVersionName + "\"")
    manifestFile.write(manifestContent)
}

tasks.whenTaskAdded { task ->
    if (task.name == 'generateReleaseBuildConfig' || task.name == 'generateDebugBuildConfig') {
        task.dependsOn 'increaseVersionCode'
        task.dependsOn 'incrementVersionName'
    }
}

1 votes

Vous avez oublié d'importer Pattern en haut : import java.util.regex.Pattern

1 votes

Je sais que c'est un peu vieux mais ça ne fait pas de mal de demander mais j'ai essayé d'utiliser le snippet ci-dessus, j'obtiens cette erreur Error:(48) Execution failed for task ':app:incrementVersionName'. > No match found Des idées ?

1 votes

@acrichm : assurez-vous que vous mettez android:versionName="0.0.0.1" dans le manifeste sinon il n'y aura pas le nombre de correspondances attendues

36voto

user2399268 Points 126

Il ne semble pas que ce soit la configuration exacte que vous utilisez, mais dans mon cas, les constructions sont exécutées par Jenkins et je voulais utiliser son $BUILD_NUMBER en tant que code de version de l'application.

defaultConfig {
    ...
    versionCode System.getenv("BUILD_NUMBER") as Integer ?: 9999
    ...
}

0 votes

Qu'est-ce que System.genenv ?

0 votes

Cela m'a en fait beaucoup aidé lorsque j'ai utilisé Jenkins. Vous pouvez utiliser ceci ce plugin pour créer une variable environmt avec le numéro de build et la lire avec System.getenv() dans le gradle.

4voto

Max Ch Points 331

Pour prendre en compte à la fois les saveurs des produits et les types de construction et utiliser la logique de @sealskej pour analyser les manifestes :

android.applicationVariants.all { variant ->
    /* Generate task to increment version code for release */
    if (variant.name.contains("Release")) {
        def incrementVersionCodeTaskName = "increment${variant.name}VersionCode"
        task(incrementVersionCodeTaskName) << {
            if (android.defaultConfig.versionCode == -1) {
                def manifestFile = file(android.sourceSets.main.manifest.srcFile)
                def pattern = Pattern.compile("versionCode=\"(\\d+)\"")
                def manifestText = manifestFile.getText()
                def matcher = pattern.matcher(manifestText)
                matcher.find()
                def versionCode = Integer.parseInt(matcher.group(1))
                android.defaultConfig.versionCode = versionCode + 1
                def manifestContent = matcher.replaceAll("versionCode=\"" + android.defaultConfig.versionCode + "\"")
                manifestFile.write(manifestContent)
            }
        }
        def hookTask = variant.generateBuildConfig
        hookTask.dependsOn(incrementVersionCodeTaskName)
    }
}

1 votes

Où devons-nous écrire ceci... Je veux dire dans quelle classe/fichier ce code doit être ajouté.

0 votes

Cela fait partie de build.gradle comme cela fait partie du processus de construction

3voto

Jared Burrows Points 3932

Incrémenter le code de version Task(Integer) :

Cela fonctionne en incrémentant le code de la version par 1 par exemple :

  android:versionCode="1"
1 + 1 = 2
import java.util.regex.Pattern

task incrementVersionCode << {
    def manifestFile = file('AndroidManifest.xml')
    def matcher = Pattern.compile('versionCode=\"(\\d+)\"')
    .matcher(manifestFile.getText())
    matcher.find()
    def manifestContent = matcher.replaceAll('versionCode=\"' +
        ++Integer.parseInt(matcher.group(1)) + '\"')
    manifestFile.write(manifestContent)
}

Incrémenter le nom de la version Task(String) :

Avertissement : Doit contenir 1 période pour Regex

Cela fonctionne en incrémentant le nom de la version par 0.01 par exemple : Vous pouvez facilement modifier et changer votre incrément ou ajouter plus de chiffres.

android:versionName="1.0"
1.00 + 0.01 -> 1.01
1.01 + 0.01 -> 1.02
1.10 + 0.01 -> 1.11
1.99 + 0.01 -> 2.0
1.90 + 0.01 -> 1.91
import java.util.regex.Pattern

task incrementVersionName << {
    def manifestFile = file('AndroidManifest.xml')
    def matcher = Pattern.compile('versionName=\"(\\d+)\\.(\\d+)\"')
    .matcher(manifestFile.getText())
    matcher.find()
    def versionName = String.format("%.2f", Integer
        .parseInt(matcher.group(1)) + Double.parseDouble("." + matcher
            .group(2)) + 0.01)
    def manifestContent = matcher.replaceAll('versionName=\"' +
        versionName + '\"')
    manifestFile.write(manifestContent)
}

Avant :

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.exmaple.test"
    android:installLocation="auto"
    android:versionCode="1"
    android:versionName="1.0" >

Après :

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.exmaple.test"
    android:installLocation="auto"
    android:versionCode="2"
    android:versionName="1.01" >

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X