VersionCode auto-incrémentée avec des propriétés supplémentaires de gradle

121

Je crée une application Android avec gradle. Jusqu'à présent, j'utilisais le fichier Manifest pour augmenter le versionCode, mais j'aimerais lire le versionCode à partir d'un fichier externe et, selon qu'il s'agit de la version de version ou de la version de débogage, augmenter le versionCode. J'ai essayé les propriétés supplémentaires, mais vous ne pouvez pas les enregistrer, ce qui signifie que la prochaine fois que je le construis, j'obtiens le même versionCode. Toute aide serait très appréciée!

project.ext{
    devVersionCode = 13
    releaseVersionCode = 1
}

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:0.6.+'
    }
}

apply plugin: 'android'

repositories {
    mavenCentral()
}

dependencies {
    compile project(':Cropper')
    compile "com.android.support:appcompat-v7:18.0.+"
    compile "com.android.support:support-v4:18.0.+"
    compile fileTree(dir: 'libs', include: '*.jar')
}

def getReleaseVersionCode() {
    def version = project.releaseVersionCode + 1
    project.releaseVersionCode = version
    println sprintf("Returning version %d", version)
    return version
}

def getDevVersionCode() {
    def version = project.devVersionCode + 1
    project.devVersionCode = version
    println sprintf("Returning version %d", version)
    return version
}


def getLastVersioName(versionCode) {
    return "0.0." + versionCode
}

android {
    compileSdkVersion 19
    buildToolsVersion "19.0.0"

    defaultConfig {
        minSdkVersion 9
        targetSdkVersion 19
    }

    sourceSets {
        main {
            manifest.srcFile 'AndroidManifest.xml'
            java.srcDirs = ['src']
            resources.srcDirs = ['src']
            aidl.srcDirs = ['src']
            renderscript.srcDirs = ['src']
            res.srcDirs = ['res']
            assets.srcDirs = ['assets']
        }
    }

    buildTypes {
        release {
            runProguard true
            proguardFile getDefaultProguardFile('proguard-android-optimize.txt')
            proguardFile 'proguard.cfg'
            debuggable false
            signingConfig null
            zipAlign false
        }
        debug {
            versionNameSuffix "-DEBUG"
        }
    }
    productFlavors {
        dev {
            packageName = 'com.swisscom.docsafe.debug'
            versionCode getDevVersionCode()
            versionName getLastVersioName(project.devVersionCode)
        }
        prod {
            packageName = 'com.swisscom.docsafe'
            versionCode getReleaseVersionCode()
            versionName getLastVersioName(project.releaseVersionCode)
        }
    }
}

task wrapper(type: Wrapper) {
    gradleVersion = '1.8'
}
carvaq
la source
Voir ma réponse ici: stackoverflow.com/a/33637600/348189
TacB0sS
Une autre option (une approche set-and-forget): medium.com/@passsy/…
Simon B.
One-liner avec votre choix de plugins Gradle: stackoverflow.com/a/61718437/4548500
SUPERCILEX

Réponses:

207

Je souhaite lire le versionCode à partir d'un fichier externe

Je suis sûr qu'il existe un certain nombre de solutions possibles; en voici une:

android {
    compileSdkVersion 18
    buildToolsVersion "18.1.0"

    def versionPropsFile = file('version.properties')

    if (versionPropsFile.canRead()) {
        def Properties versionProps = new Properties()

        versionProps.load(new FileInputStream(versionPropsFile))

        def code = versionProps['VERSION_CODE'].toInteger() + 1

        versionProps['VERSION_CODE']=code.toString()
        versionProps.store(versionPropsFile.newWriter(), null)

        defaultConfig {
            versionCode code
            versionName "1.1"
            minSdkVersion 14
            targetSdkVersion 18
        }
    }
    else {
        throw new GradleException("Could not read version.properties!")
    }

    // rest of android block goes here
}

Ce code attend un version.propertiesfichier existant , que vous créeriez à la main avant la première compilation VERSION_CODE=8.

Ce code renverse simplement le code de version sur chaque build - vous devrez étendre la technique pour gérer votre code de version par saveur.

Vous pouvez voir l'exemple de projet de contrôle de version qui illustre ce code.

CommonsWare
la source
4
Comment activer cette version incrémentée uniquement lors de la création de versions de version?
Piotr
@Piotr: Si vous voulez dire "incrémenter uniquement le nombre sur une version de version", cela devrait être possible, bien que je ne connaisse pas les détails. Personnellement, puisqu'il y a environ 2 milliards de codes de version disponibles, je suppose que je ne manquerai pas. :-)
CommonsWare
3
@Piotr vous créeriez une tâche qui incrémenterait séparément le code de version puis feriez quelque chose comme assembleRelease.finalizedBy incrementVersionou quelque chose de similaire. Je publierai mon code une fois que je l'aurai rangé.
Chris.Jenkins
En utilisant une tâche personnalisée, vous pouvez simplement faire quelque chose comme ./gradlew incrementVersionCode build. Les tâches appelées séquentiellement de cette manière s'arrêteront dès que l'une des tâches échouera.
Dori
3
Comme @ chris.jenkins raconte toujours son code: p Voici ce qui précède sous forme de tâche et de méthode gist.github.com/doridori/544c24509be236c11fd5 qui peut être utilisé dans l'Android DSL avecversionCode getIncrementingVersionCode()
Dori
83

Voici une modernisation de ma réponse précédente qui peut être vue ci-dessous. Celui-ci fonctionne avec Gradle 4.4 et Android Studio 3.1.1 .

Ce que fait ce script:

  • Crée un fichier version.properties s'il n'en existe pas (vote plus haut la réponse de Paul Cantrell ci-dessous, d'où j'ai eu l'idée si vous aimez cette réponse)
  • Pour chaque build, version de débogage ou chaque fois que vous appuyez sur le bouton d'exécution dans Android Studio, le nombre VERSION_BUILD augmente.
  • Chaque fois que vous assemblez une version, votre version AndroidCode pour le Play Store augmente et votre numéro de patch augmente.
  • Bonus: une fois la construction terminée, copiez votre apk pour projectDir/apkle rendre plus accessible.

Ce script créera un numéro de version qui ressemble à v1.3.4 (123)et construira un fichier apk comme AppName-v1.3.4.apk .

Major version         Build version
             v1.3.4 (123)
  Minor version ⌃|⌃ Patch version

Version majeure: doit être modifiée manuellement pour des changements plus importants.

Version mineure: doit être modifiée manuellement pour des modifications légèrement moins importantes.

Version du correctif: augmente lors de l'exécutiongradle assembleRelease

Version de build: augmente chaque build

Numéro de version: identique à la version du correctif , il s'agit du code de version dont le Play Store doit avoir augmenté pour chaque nouveau téléchargement d'apk.

Changez simplement le contenu dans les commentaires étiquetés 1 à 3 ci-dessous et le script devrait faire le reste. :)

android {
    compileSdkVersion 27
    buildToolsVersion '27.0.3'

    def versionPropsFile = file('version.properties')
    def value = 0
    Properties versionProps = new Properties()
    if (!versionPropsFile.exists()) {
        versionProps['VERSION_PATCH'] = "0"
        versionProps['VERSION_NUMBER'] = "0"
        versionProps['VERSION_BUILD'] = "-1" // I set it to minus one so the first build is 0 which isn't super important. 
        versionProps.store(versionPropsFile.newWriter(), null)
    }

    def runTasks = gradle.startParameter.taskNames
    if ('assembleRelease' in runTasks) {
        value = 1
    }

    def mVersionName = ""
    def mFileName = ""

    if (versionPropsFile.canRead()) {
        versionProps.load(new FileInputStream(versionPropsFile))

        versionProps['VERSION_PATCH'] = (versionProps['VERSION_PATCH'].toInteger() + value).toString()
        versionProps['VERSION_NUMBER'] = (versionProps['VERSION_NUMBER'].toInteger() + value).toString()
        versionProps['VERSION_BUILD'] = (versionProps['VERSION_BUILD'].toInteger() + 1).toString()

        versionProps.store(versionPropsFile.newWriter(), null)

        // 1: change major and minor version here
        mVersionName = "v1.0.${versionProps['VERSION_PATCH']}"
        // 2: change AppName for your app name
        mFileName = "AppName-${mVersionName}.apk"

        defaultConfig {
            minSdkVersion 21
            targetSdkVersion 27
            applicationId "com.example.appname" // 3: change to your package name
            versionCode versionProps['VERSION_NUMBER'].toInteger()
            versionName "${mVersionName} Build: ${versionProps['VERSION_BUILD']}"
        }

    } else {
        throw new FileNotFoundException("Could not read version.properties!")
    }

    if ('assembleRelease' in runTasks) {
        applicationVariants.all { variant ->
            variant.outputs.all { output ->
                if (output.outputFile != null && output.outputFile.name.endsWith('.apk')) {
                    outputFileName = mFileName
                }
            }
        }
    }

    task copyApkFiles(type: Copy){
        from 'build/outputs/apk/release'
        into '../apk'
        include mFileName
    }

    afterEvaluate {
        assembleRelease.doLast {
            tasks.copyApkFiles.execute()
        }
    }

    signingConfigs {
        ...
    }

    buildTypes {
        ...
    }
}

=================================================== ==

RÉPONSE INITIALE:

Je veux que le nom de version augmente également automatiquement. Ce n'est donc qu'un ajout à la réponse de CommonsWare qui a parfaitement fonctionné pour moi. C'est ce qui fonctionne pour moi

defaultConfig {
    versionCode code
    versionName "1.1." + code
    minSdkVersion 14
    targetSdkVersion 18
}

ÉDITER:

Comme je suis un peu paresseux, je veux que ma gestion des versions fonctionne aussi automatiquement que possible. Ce que je veux, c'est avoir une version de build qui augmente avec chaque build, tandis que le numéro de version et le nom de la version augmentent uniquement lorsque je crée une version de version.

C'est ce que j'utilise depuis un an, les bases sont tirées de la réponse de CommonsWare et de ma réponse précédente, ainsi que d'autres. Cela entraîne le contrôle de version suivant:

Nom de la version: 1.0.5 (123) -> Major.Minor.Patch (Build), Major et Minor sont modifiés manuellement.

Dans build.gradle:

...
android {
    compileSdkVersion 23
    buildToolsVersion '23.0.1'
    def versionPropsFile = file('version.properties')
    if (versionPropsFile.canRead()) {
        def Properties versionProps = new Properties()

        versionProps.load(new FileInputStream(versionPropsFile))

        def value = 0

        def runTasks = gradle.startParameter.taskNames
        if ('assemble' in runTasks || 'assembleRelease' in runTasks || 'aR' in runTasks) {
            value = 1;
        }

        def versionMajor = 1
        def versionMinor = 0
        def versionPatch = versionProps['VERSION_PATCH'].toInteger() + value
        def versionBuild = versionProps['VERSION_BUILD'].toInteger() + 1
        def versionNumber = versionProps['VERSION_NUMBER'].toInteger() + value

        versionProps['VERSION_PATCH'] = versionPatch.toString()
        versionProps['VERSION_BUILD'] = versionBuild.toString()
        versionProps['VERSION_NUMBER'] = versionNumber.toString()

        versionProps.store(versionPropsFile.newWriter(), null)

        defaultConfig {
            versionCode versionNumber
            versionName "${versionMajor}.${versionMinor}.${versionPatch} (${versionBuild}) Release"
            minSdkVersion 14
            targetSdkVersion 23
        }

        applicationVariants.all { variant ->
            variant.outputs.each { output ->
                def fileNaming = "apk/RELEASES"
                variant.outputs.each { output ->
                    def outputFile = output.outputFile
                    if (outputFile != null && outputFile.name.endsWith('.apk')) {
                        output.outputFile = new File(getProject().getRootDir(), "${fileNaming}-${versionMajor}.${versionMinor}.${versionPatch}-${outputFile.name}")
                    }
                }
            }
        }

    } else {
        throw new GradleException("Could not read version.properties!")
    }

    ...
}

...

Patch et versionCode est augmenté si vous assemblez votre projet via le terminal avec 'assemble' , 'assembleRelease' ou 'aR' qui crée un nouveau dossier dans la racine de votre projet appelé apk / RELEASE afin que vous n'ayez pas à regarder à travers build / output / plus / plus / plus pour trouver votre apk.

Les propriétés de votre version devraient ressembler à ceci:

VERSION_NUMBER=1
VERSION_BUILD=645
VERSION_PATCH=1

Commencez évidemment par 0. :)

just_user
la source
2
Le deuxième 'variant.outputs.each {output ->' peut être supprimé, avec le '}' correspondant.
redocoder
Cela fait que toutes mes versions sont uniquement en code natif x86_64
Chisko
@Chisko Je doute que ce morceau du code gradle en soit la cause. Posez une nouvelle question et partagez votre code de note et nous pouvons essayer de comprendre ce qui ne va pas. :)
just_user
1
Je peux maintenant confirmer que ce n'était pas la cause première. Mes excuses.
Chisko le
1
@AlexanderGavriliuk c'est le code de version utilisé par le Play Store qui doit constamment augmenter à chaque téléchargement. Le numéro de patch sera probablement réinitialisé si vous augmentez la version majeure ou mineure. Le numéro de version ne devrait jamais, ne pourra jamais être réinitialisé si vous téléchargez l'application sur le Play Store avec le même nom de package.
just_user
40

Une version légèrement améliorée de l'excellente réponse de CommonsWare crée le fichier de version s'il n'existe pas:

def Properties versionProps = new Properties()
def versionPropsFile = file('version.properties')
if(versionPropsFile.exists())
    versionProps.load(new FileInputStream(versionPropsFile))
def code = (versionProps['VERSION_CODE'] ?: "0").toInteger() + 1
versionProps['VERSION_CODE'] = code.toString()
versionProps.store(versionPropsFile.newWriter(), null)

defaultConfig {
    versionCode code
    versionName "1.1"
    minSdkVersion 14
    targetSdkVersion 18
}
Paul Cantrell
la source
où est la partie sur la création du fichier de version s'il n'existe pas?
portfoliobuilder
4
if(versionPropsFile.exists())garantit qu'il n'explose pas si le fichier n'est pas là. versionProps.store(versionPropsFile.newWriter(), null) écrase le fichier, qu'il existe déjà ou non.
Paul Cantrell
J'ai dû vérifier ce que ?:signifiait Groovy. L' opérateur Elvis est un raccourcissement de l'opérateur ternaire.
Daniel
30

J'ai examiné quelques options pour ce faire, et j'ai finalement décidé qu'il était plus simple d'utiliser simplement l'heure actuelle pour le versionCode au lieu d'essayer d'incrémenter automatiquement le versionCode et de l'enregistrer dans mon système de contrôle de révision.

Ajoutez ce qui suit à votre build.gradle:

/**
 * Use the number of seconds/10 since Jan 1 2016 as the versionCode.
 * This lets us upload a new build at most every 10 seconds for the
 * next 680 years.
 */
def vcode = (int)(((new Date().getTime()/1000) - 1451606400) / 10)

android {
    defaultConfig {
        ...
        versionCode vcode
    }
}

Cependant, si vous prévoyez de télécharger des versions au-delà de l'année 2696, vous souhaiterez peut-être utiliser une solution différente.

emmby
la source
2
Si vous lisez ceci maintenant, et que vous commencez avec une nouvelle application, vous pouvez soustraire 1510351294:))
Entreco
je ne comprends pas ça !! n'utilisez-vous pas des analyses ou des crashlytics ou tout autre service qui donne des données avec des codes de version et des noms? et vous jouez avec cela facilement?
Amir Ziarati
Si vous avez des noms de version raisonnables, je pense que ça va. Crashalytics fournit également le nom de la version.
netcyrax le
@emmby d'où vient le numéro «1451606400»? ou le '1510351294' de #Entreco j'ai essayé de calculer en vain!
Joseph Wambura le
18

Une autre façon d'obtenir un versionCodeautomatiquement est de définir versionCodele nombre de commits dans la gitbranche extraite. Il atteint les objectifs suivants:

  1. versionCodeest généré automatiquement et de manière cohérente sur n'importe quelle machine (y compris un Continuous Integrationet / ouContinuous Deployment serveur ).
  2. App avec ça versionCode peut être soumise à GooglePlay.
  3. Ne repose sur aucun fichier en dehors du dépôt.
  4. Ne pousse rien vers le repo
  5. Peut être remplacé manuellement, si nécessaire

Utilisation de la bibliothèque gradle-git pour atteindre les objectifs ci-dessus. Ajoutez le code ci-dessous à votre build.gradlefichier le /apprépertoire:

import org.ajoberstar.grgit.Grgit

repositories {
    mavenCentral()
}

buildscript {
    repositories {
        mavenCentral()
    }

    dependencies {
        classpath 'org.ajoberstar:grgit:1.5.0'
    }
}

android {
/*
    if you need a build with a custom version, just add it here, but don't commit to repo,
    unless you'd like to disable versionCode to be the number of commits in the current branch.

    ex. project.ext.set("versionCodeManualOverride", 123)
*/
    project.ext.set("versionCodeManualOverride", null)

    defaultConfig {
        versionCode getCustomVersionCode()
    }
}

def getCustomVersionCode() {

    if (project.versionCodeManualOverride != null) {
        return project.versionCodeManualOverride
    }

    // current dir is <your proj>/app, so it's likely that all your git repo files are in the dir
    // above.
    ext.repo = Grgit.open(project.file('..'))

    // should result in the same value as running
    // git rev-list <checked out branch name> | wc -l
    def numOfCommits = ext.repo.log().size()
    return numOfCommits
}

REMARQUE: Pour que cette méthode fonctionne, il est préférable de ne déployer sur Google Play Store qu'à partir de la même branche (par exemple master).

C0D3LIC1OU5
la source
bien qu'essentiellement une solution élégante, je peux imaginer que cela ralentirait considérablement le temps de construction, en fonction de ce qui se passe exactement dans les 2 lignes git. Une expérience à ce sujet?
J'espère
1
Je ne remarque aucune amélioration des performances si cette étape est désactivée. J'utilise la méthode localement et sur nos machines de construction depuis plus d'un an et les performances n'ont pas du tout été un problème. Si vous remarquez des problèmes de performances, faites-le moi savoir!
C0D3LIC1OU5
Bien que votre solution soit élégante, elle pourrait donner de mauvaises surprises inattendues. Il est essentiel que versionCodes soit toujours plus volumineux que dans la version précédente. Que faire si vous avez une branche avec 50 commits, et que vous créez ensuite une autre branche qui est plus récente mais qui n'a que 40 commits, peut-être en raison de l'écrasement d'un certain nombre de commits à partir d'une fonctionnalité fusionnée. Je peux voir de nombreuses raisons pour lesquelles votre historique de commit ne serait pas toujours un flux linéaire de commits incrémentiels.
JHH
@JHH Ces résultats ne sont pas inattendus. Comme je l'ai mentionné dans une note, cette méthode fonctionne mieux lors du déploiement à partir de la même branche.
C0D3LIC1OU5
13

Récemment , je travaillais sur un plugin gradle pour Android qui rend la génération codeVersion et versionName automatiquement. il y a beaucoup de personnalisation. ici vous pouvez trouver plus d'informations à ce sujet https://github.com/moallemi/gradle-advanced-build-version

Moallemi
la source
C'est un excellent plugin! Merci d'avoir partagé 🙂
Cory Robinson
10

Une autre option, pour incrémenter le versionCodeet le versionName, consiste à utiliser un horodatage.

defaultConfig {
   versionName "${getVersionNameTimestamp()}"
   versionCode getVersionCodeTimestamp()
}


def getVersionNameTimestamp() {
    return new Date().format('yy.MM.ddHHmm')
}

def getVersionCodeTimestamp() {
    def date = new Date()
    def formattedDate = date.format('yyMMddHHmm')
    def code = formattedDate.toInteger()
    println sprintf("VersionCode: %d", code)
    return code
}

À partir du 1er janvier 2022, formattedDate = date.format ('aaMMddHHmm') dépasse la capacité des nombres entiers

carvaq
la source
1
La personne voulait un numéro de build auto-incrémenté
peter_pilgrim
6
@peter_pilgrim Caro est l'OP.
Matthieu a lu le
Je pense que c'est une solution élégante, elle ne repose pas sur des fichiers qui pourraient disparaître ou non ou qui apparaîtront constamment dans git. Il vous aide également à identifier de manière unique chaque build pour au moins les 12 prochaines années.
J'espère
citant developer.android.com:"Avertissement: La plus grande valeur que Google Play autorise pour versionCode est 2100000000. "Ainsi, la date limite est en fait 2021.
ths
Correction de la limite int: omettez les minutes et utilisez le format de date 'aaMMjjHH', le code de version contiendra au moins heures.
Pointer Null
10

Pour incrémenter versionCode uniquement dans la version commerciale, procédez comme suit:

android {
    compileSdkVersion 21
    buildToolsVersion "21.1.2"

    def versionPropsFile = file('version.properties')
    def code = 1;
    if (versionPropsFile.canRead()) {
        def Properties versionProps = new Properties()

        versionProps.load(new FileInputStream(versionPropsFile))
        List<String> runTasks = gradle.startParameter.getTaskNames();
        def value = 0
        for (String item : runTasks)
        if ( item.contains("assembleRelease")) {
            value = 1;
        }
        code = Integer.parseInt(versionProps['VERSION_CODE']).intValue() + value
        versionProps['VERSION_CODE']=code.toString()
        versionProps.store(versionPropsFile.newWriter(), null)
    }
    else {
        throw new GradleException("Could not read version.properties!")
    }

    defaultConfig {
        applicationId "com.pack"
        minSdkVersion 14
        targetSdkVersion 21
        versionName "1.0."+ code
        versionCode code
    }

attend un c://YourProject/app/version.propertiesfichier existant , que vous créeriez à la main avant la première compilationVERSION_CODE=8

Fichier version.properties:

VERSION_CODE=8

NickUnuchek
la source
Placez-le plutôt dans une tâche et faites en sorte que generateReleaseBuildConfig dépende de cette tâche.
lagos
versionName "1.0." + getSvnRevision () provoque une erreur. Où la méthode getSvnRevision () fait-elle référence? Êtes-vous sûr qu'il ne devrait pas être versionName "1.0" + code (le nom de la version augmentera avec votre code de version)?
portfoliobuilder
1
@portfoliobuilder, remplacez getSvnRevision () par le code
NickUnuchek
4

Créer un fichier version.properties

MAJOR=1
MINOR=3
PATCH=6
VERSION_CODE=1

Changement build.gradle:

android {
def _versionCode=0
def _major=0
def _minor=0
def _patch=0

def _applicationId = "com.example.test"

def versionPropsFile = file('version.properties')

if (versionPropsFile.canRead()) {
    def Properties versionProps = new Properties()

    versionProps.load(new FileInputStream(versionPropsFile))

    _patch = versionProps['PATCH'].toInteger() + 1
    _major = versionProps['MAJOR'].toInteger()
    _minor = versionProps['MINOR'].toInteger() 
    _versionCode= versionProps['VERSION_CODE'].toInteger()+1
    if(_patch==99)
    {
        _patch=0
        _minor=_minor+1
    }
    if(_major==99){
        _major=0
        _major=_major+1
    }

    versionProps['MAJOR']=_major.toString()
    versionProps['MINOR']=_minor.toString()
    versionProps['PATCH']=_patch.toString()
    versionProps['VERSION_CODE']=_versionCode.toString()
    versionProps.store(versionPropsFile.newWriter(), null)
}
else {
    throw new GradleException("Could not read version.properties!")
}
def _versionName = "${_major}.${_versionCode}.${_minor}.${_patch}"


compileSdkVersion 23
buildToolsVersion "23.0.3"

defaultConfig {
    applicationId _applicationId
    minSdkVersion 11
    targetSdkVersion 23
    versionCode _versionCode
    versionName _versionName
}

}

Production : 1.1.3.6

Ahmad Aghazadeh
la source
Merci. Et pourquoi avez-vous inséré un versionCode dans versionName? Même en deuxième position.
CoolMind
Mais cela ressemblera à 1.71.3.76, par exemple. Je pense que mieux vaut 1.3.76, en le séparant du code de version.
CoolMind
Oui . vous pouvez changer en "$ {_ major} .. $ {_ minor}. $ {_ patch}. $ {_ versionCode}" ou supprimer le correctif
Ahmad Aghazadeh
if (_major == 99) devrait être if (_minor == 99) ??
Anirudh Bagri
2

Définir versionName dansAndroidManifest.xml

android:versionName="5.1.5"

android{...}Blocage intérieur build.gradledu niveau de l'application:

defaultConfig {
        applicationId "com.example.autoincrement"
        minSdkVersion 18
        targetSdkVersion 23
        multiDexEnabled true
        def version = getIncrementationVersionName()
        versionName version
}

android{...}Blocage extérieur au build.gradleniveau de l'application:

def getIncrementedVersionName() {
    List<String> runTasks = gradle.startParameter.getTaskNames();

    //find version name in manifest
    def manifestFile = file('src/main/AndroidManifest.xml')
    def matcher = Pattern.compile('versionName=\"(\\d+)\\.(\\d+)\\.(\\d+)\"').matcher(manifestFile.getText())
    matcher.find()

    //extract versionName parts
    def firstPart = Integer.parseInt(matcher.group(1))
    def secondPart = Integer.parseInt(matcher.group(2))
    def thirdPart = Integer.parseInt(matcher.group(3))

    //check is runTask release or not
    // if release - increment version
    for (String item : runTasks) {
        if (item.contains("assemble") && item.contains("Release")) {
            thirdPart++
            if (thirdPart == 10) {
                thirdPart = 0;
                secondPart++
                if (secondPart == 10) {
                    secondPart = 0;
                    firstPart++
                }
            }
        }
    }

    def versionName = firstPart + "." + secondPart + "." + thirdPart

    // update manifest
    def manifestContent = matcher.replaceAll('versionName=\"' + versionName + '\"')
    manifestFile.write(manifestContent)

    println "incrementVersionName = " + versionName

    return versionName
}

Après avoir créé l'APK chanté:

android:versionName="5.1.6"

Remarque: Si votre versionName est différent de my, vous devez modifier l' expression régulière et extraire la logique des parties .

Sergey Shustikov
la source
1

Les exemples ci-dessus ne fonctionnent pas pour différentes raisons

Voici ma variante prête à l'emploi basée sur les idées de cet article:

android {
    compileSdkVersion 28

    // /programming/21405457

    def propsFile = file("version.properties")
    // Default values would be used if no file exist or no value defined
    def customAlias = "Alpha"
    def customMajor = "0"
    def customMinor = "1"
    def customBuild = "1" // To be incremented on release

    Properties props = new Properties()
    if (propsFile .exists())
        props.load(new FileInputStream(propsFile ))

    if (props['ALIAS'] == null) props['ALIAS'] = customAlias else customAlias = props['ALIAS']
    if (props['MAJOR'] == null) props['MAJOR'] = customMajor else customMajor = props['MAJOR']
    if (props['MINOR'] == null) props['MINOR'] = customMinor else customMinor = props['MINOR']
    if (props['BUILD'] == null) props['BUILD'] = customBuild else customBuild = props['BUILD']

    if (gradle.startParameter.taskNames.join(",").contains('assembleRelease')) {
        customBuild = "${customBuild.toInteger() + 1}"
        props['BUILD'] = "" + customBuild

        applicationVariants.all { variant ->
            variant.outputs.all { output ->
                if (output.outputFile != null && (output.outputFile.name == "app-release.apk"))
                    outputFileName = "app-${customMajor}-${customMinor}-${customBuild}.apk"
            }
        }
    }

    props.store(propsFile.newWriter(), "Incremental Build Version")

    defaultConfig {
        applicationId "org.example.app"
        minSdkVersion 21
        targetSdkVersion 28
        versionCode customBuild.toInteger()
        versionName "$customAlias $customMajor.$customMinor ($customBuild)"

        ...
    }
...
}
Alexandre Gavriliuk
la source
0

Crédits à CommonsWare (Réponse acceptée) Paul Cantrell (Créer un fichier s'il n'existe pas) ahmad aghazadeh (Nom et code de la version)

Alors j'ai écrasé toutes leurs idées ensemble et j'ai trouvé ça. C'est la solution de glisser-déposer pour exactement ce que le premier message a demandé.

Il mettra automatiquement à jour le versionCode et la versionName en fonction de l'état de la version. Bien sûr, vous pouvez déplacer les variables pour répondre à vos besoins.

def _versionCode=0
def versionPropsFile = file('version.properties')
def Properties versionProps = new Properties()
if(versionPropsFile.exists())
    versionProps.load(new FileInputStream(versionPropsFile))
    def _patch = (versionProps['PATCH'] ?: "0").toInteger() + 1
    def _major = (versionProps['MAJOR'] ?: "0").toInteger()
    def _minor = (versionProps['MINOR'] ?: "0").toInteger()
    List<String> runTasks = gradle.startParameter.getTaskNames();
    def value = 0
    for (String item : runTasks)
        if ( item.contains("assembleRelease")) {
            value = 1;
        }
    _versionCode = (versionProps['VERSION_CODE'] ?: "0").toInteger() + value
    if(_patch==99)
    {
        _patch=0
        _minor=_minor+1
    }
    if(_major==99){
        _major=0
        _major=_major+1
    }

versionProps['MAJOR']=_major.toString()
versionProps['MINOR']=_minor.toString()
versionProps['PATCH']=_patch.toString()
versionProps['VERSION_CODE']=_versionCode.toString()
versionProps.store(versionPropsFile.newWriter(), null)
def _versionName = "${_major}.${_versionCode}.${_minor}.${_patch}"

compileSdkVersion 24
buildToolsVersion "24.0.0"

defaultConfig {
    applicationId "com.yourhost.yourapp"
    minSdkVersion 16
    targetSdkVersion 24
    versionCode _versionCode
    versionName _versionName
}
Thunderstick
la source
0

En utilisant Gradle Task Graph, nous pouvons vérifier / changer type de construction.

L'idée de base est d'incrémenter le versionCode sur chaque build. Sur chaque build un compteur stocké dans le fichier version.properties . Il sera mis à jour à chaque nouvelle version d'APK et remplacera la chaîne versionCode dans le fichier build.gradle par cette valeur de compteur incrémentée.

apply plugin: 'com.android.application'

android {
compileSdkVersion 25
buildToolsVersion '25.0.2'

def versionPropsFile = file('version.properties')
def versionBuild

/*Setting default value for versionBuild which is the last incremented value stored in the file */
if (versionPropsFile.canRead()) {
    def Properties versionProps = new Properties()
    versionProps.load(new FileInputStream(versionPropsFile))
    versionBuild = versionProps['VERSION_BUILD'].toInteger()
} else {
    throw new FileNotFoundException("Could not read version.properties!")
}


/*Wrapping inside a method avoids auto incrementing on every gradle task run. Now it runs only when we build apk*/
ext.autoIncrementBuildNumber = {

    if (versionPropsFile.canRead()) {
        def Properties versionProps = new Properties()
        versionProps.load(new FileInputStream(versionPropsFile))
        versionBuild = versionProps['VERSION_BUILD'].toInteger() + 1
        versionProps['VERSION_BUILD'] = versionBuild.toString()
        versionProps.store(versionPropsFile.nminSdkVersion 14
        targetSdkVersion 21
        versionCode 1ewWriter(), null)
    } else {
        throw new FileNotFoundException("Could not read version.properties!")
    }
}


defaultConfig {
    minSdkVersion 16
    targetSdkVersion 21
    versionCode 1
    versionName "1.0.0." + versionBuild
}

buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}

// Hook to check if the release/debug task is among the tasks to be executed.
//Let's make use of it
gradle.taskGraph.whenReady {taskGraph ->
    if (taskGraph.hasTask(assembleDebug)) {  /* when run debug task */
        autoIncrementBuildNumber()
    } else if (taskGraph.hasTask(assembleRelease)) { /* when run release task */
        autoIncrementBuildNumber()
    }
  }
}

dependencies {
  compile fileTree(dir: 'libs', include: ['*.jar'])
  compile 'com.android.support:appcompat-v7:25.3.1'
}

Placez le script ci-dessus dans votre fichier build.gradle du module principal.

Site Web de référence: http://devdeeds.com/auto-increment-build-number-using-gradle-in-android/

Merci et salutations!

Jayakrishnan
la source
0

Le premier code commenté incrémentera le nombre à chaque "Rebuild Project" et enregistrera la valeur dans le fichier "Version Property".

Le deuxième code commenté générera un nouveau nom de version du fichier APK tandis que "Créer des APK".

android {
    compileSdkVersion 28
    buildToolsVersion "29.0.0"
    //==========================START==================================
    def Properties versionProps = new Properties()
    def versionPropsFile = file('version.properties')
    if(versionPropsFile.exists())
        versionProps.load(new FileInputStream(versionPropsFile))
    def code = (versionProps['VERSION_CODE'] ?: "0").toInteger() + 1
    versionProps['VERSION_CODE'] = code.toString()
    versionProps.store(versionPropsFile.newWriter(), null)
    //===========================END===================================
    defaultConfig {
        applicationId "com.example.myapp"
        minSdkVersion 15
        targetSdkVersion 28
        versionCode 1
        versionName "0.19"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
            //=======================================START===============================================
            android.applicationVariants.all { variant ->
                variant.outputs.all {
                    def appName = "MyAppSampleName"
                    outputFileName = appName+"_v${variant.versionName}.${versionProps['VERSION_CODE']}.apk"
                }
            }
            //=======================================END===============================================
        }
    }
}
Radha Krishna Eedulakanti
la source
Veuillez ajouter du texte montrant ce que vous avez changé. et pourquoi
Matthew Kerian
0

dans la version Gradle 5.1.1 sur mac, ive a changé la façon dont les noms de tâches ont été récupérés, j'ai bien essayé d'obtenir la saveur / le type de construction à partir de la construction mais j'étais trop paresseux pour diviser le nom de la tâche:

def versionPropsFile = file('version.properties')
if (versionPropsFile.canRead()) {
    def Properties versionProps = new Properties()

    versionProps.load(new FileInputStream(versionPropsFile))

    def value = 0

    def runTasks = gradle.getStartParameter().getTaskRequests().toString()

    if (runTasks.contains('assemble') || runTasks.contains('assembleRelease') || runTasks.contains('aR')) {
        value = 1
    }

    def versionMajor = 1
    def versionMinor = 0
    def versionPatch = versionProps['VERSION_PATCH'].toInteger() + value
    def versionBuild = versionProps['VERSION_BUILD'].toInteger() + 1
    def versionNumber = versionProps['VERSION_NUMBER'].toInteger() + value

    versionProps['VERSION_PATCH'] = versionPatch.toString()
    versionProps['VERSION_BUILD'] = versionBuild.toString()
    versionProps['VERSION_NUMBER'] = versionNumber.toString()

    versionProps.store(versionPropsFile.newWriter(), null)

    defaultConfig {
        applicationId "de.evomotion.ms10"
        minSdkVersion 21
        targetSdkVersion 28
        versionCode versionNumber
        versionName "${versionMajor}.${versionMinor}.${versionPatch} (${versionBuild})"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        signingConfig signingConfigs.debug
    }

} else {
    throw new GradleException("Could not read version.properties!")
}

le code provient de @just_user celui-ci

Basur
la source
0

Il y a deux solutions que j'aime vraiment. Le premier dépend du Play Store et l'autre dépend de Git.

En utilisant le Play Store, vous pouvez incrémenter le code de version en regardant le code de version téléchargé le plus élevé disponible . L'avantage de cette solution est qu'un téléchargement d'APK n'échouera jamais puisque votre code de version est toujours supérieur à ce qui se trouve sur le Play Store. L'inconvénient est que la distribution de votre APK en dehors du Play Store devient plus difficile. Vous pouvez configurer cela à l'aide de Gradle Play Publisher en suivant le guide de démarrage rapide et en demandant au plugin de résoudre automatiquement les codes de version :

plugins {
    id 'com.android.application'
    id 'com.github.triplet.play' version 'x.x.x'
}

android {
    ...
}

play {
    serviceAccountCredentials = file("your-credentials.json")
    resolutionStrategy = "auto"
}

À l'aide de Git, vous pouvez incrémenter le code de version en fonction du nombre de validations et de balises de votre référentiel. L'avantage ici est que votre sortie est reproductible et ne dépend de rien en dehors de votre dépôt. L'inconvénient est que vous devez créer un nouveau commit ou une nouvelle balise pour modifier votre code de version. Vous pouvez configurer cela en ajoutant le plugin Version Master Gradle :

plugins {
    id 'com.android.application'
    id 'com.supercilex.gradle.versions' version 'x.x.x'
}

android {
    ...
}
SUPERCILEX
la source