Autoincrement VersionCode com propriedades extras gradle


121

Estou construindo um aplicativo Android com o gradle. Até agora usei o arquivo Manifest para aumentar o versionCode, mas gostaria de ler o versionCode de um arquivo externo e dependendo se é a versão de lançamento ou a versão de depuração, aumente o versionCode. Tentei as propriedades extras, mas você não consegue salvá-las, o que significa que da próxima vez que eu construir, estou obtendo o mesmo versionCode. Qualquer ajuda seria muito bem vinda!

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'
}

Veja minha resposta aqui: stackoverflow.com/a/33637600/348189
— TacB0sS

Outra opção (uma abordagem de definir e esquecer): medium.com/@passsy/…
— Simon B.

One-liner com sua escolha de plug-ins Gradle: stackoverflow.com/a/61718437/4548500
— SUPERCILEX

Respostas:


207

Eu gostaria de ler o versionCode de um arquivo externo

Estou certo de que existem inúmeras soluções possíveis; Aqui está um:

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
}

Este código espera um version.propertiesarquivo existente , que você criaria manualmente antes de ter o primeiro build VERSION_CODE=8.

Este código simplesmente altera o código de versão em cada compilação - você precisaria estender a técnica para lidar com seu código de versão por variação.

Você pode ver o projeto de amostra de controle de versão que demonstra esse código.


4
Como habilitar o incremento desta versão apenas ao fazer compilações de lançamento?
— Piotr

@Piotr: Se você quer dizer "apenas incrementar o número em uma compilação de lançamento", isso deveria ser possível, embora eu não saiba os detalhes. Pessoalmente, uma vez que existem cerca de 2 bilhões de códigos de versão disponíveis, estou assumindo que não vou acabar. :-)
— CommonsWare

3
@Piotr você criaria uma tarefa que incrementa separadamente o código de versão e então faria algo parecido assembleRelease.finalizedBy incrementVersionou semelhante. Vou postar meu código depois de arrumá-lo.
— Chris.Jenkins

Usando uma tarefa personalizada, você pode simplesmente fazer algo como ./gradlew incrementVersionCode build. As tarefas chamadas sequencialmente dessa maneira serão interrompidas assim que qualquer uma das tarefas falhar.
— Dori

3
Como @ chris.jenkins ainda está lendo seu código: p Aqui está o acima no formulário de tarefa e método gist.github.com/doridori/544c24509be236c11fd5 que pode ser usado dentro do DSL Android comversionCode getIncrementingVersionCode()
— Dori

83

Aí vem uma modernização da minha resposta anterior, que pode ser vista abaixo. Este está sendo executado com Gradle 4.4 e Android Studio 3.1.1 .

O que este script faz:

  • Cria um arquivo version.properties se não houver nenhum (vote na resposta de Paul Cantrell abaixo, que é de onde eu tirei a ideia se você gostar desta resposta)
  • Para cada versão, versão de depuração ou sempre que você pressiona o botão de execução no Android Studio, o número VERSION_BUILD aumenta.
  • Cada vez que você monta um lançamento, seu código de versão do Android para a play store aumenta e o número do patch aumenta.
  • Bônus: depois que a compilação for concluída, copie seu apk para projectDir/apkpara torná-lo mais acessível.

Este script criará um número de versão semelhante v1.3.4 (123)e construirá um arquivo apk como AppName-v1.3.4.apk .

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

Versão principal: deve ser alterado manualmente para alterações maiores.

Versão secundária: deve ser alterado manualmente para alterações um pouco menos grandes.

Versão do patch: aumenta durante a execuçãogradle assembleRelease

Versão de compilação: aumenta a cada compilação

Número da versão: igual à versão do patch , é para o código da versão que a Play Store precisa ter aumentado para cada novo upload do apk.

Basta alterar o conteúdo nos comentários marcados de 1 a 3 abaixo e o script fará o resto. :)

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 {
        ...
    }
}

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

RESPOSTA INICIAL:

Quero que o versionName aumente automaticamente também. Portanto, este é apenas um acréscimo à resposta do CommonsWare que funcionou perfeitamente para mim. Isto é o que funciona para mim

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

EDITAR:

Como sou um pouco preguiçoso, quero que meu controle de versão funcione da forma mais automática possível. O que eu quero é ter uma versão de compilação que aumente com cada compilação, enquanto o número da versão e o nome da versão só aumentam quando eu faço uma compilação de lançamento.

Isso é o que tenho usado no ano passado, o básico é da resposta de CommonsWare e minha resposta anterior, além de mais algumas. Isso resulta no seguinte controle de versão:

Nome da versão: 1.0.5 (123) -> Major.Minor.Patch (Build), Major e Minor são alterados manualmente.

Em 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 e versionCode aumentam se você montar seu projeto por meio do terminal com 'assemble' , 'assembleRelease' ou 'aR' que cria uma nova pasta na raiz do seu projeto chamada apk / RELEASE para que você não tenha que olhar para build / outputs / mais / mais / mais para encontrar seu apk.

As propriedades de sua versão precisam ser assim:

VERSION_NUMBER=1
VERSION_BUILD=645
VERSION_PATCH=1

Obviamente, comece com 0. :)


2
O segundo 'variant.outputs.each {output ->' pode ser removido, com o '}' correspondente.
— redocoder

Isso está fazendo com que todas as minhas compilações estejam apenas em código nativo x86_64
— Chisko

@Chisko Duvido que essa parte do código do Gradle seja a causa. Faça uma nova pergunta e compartilhe seu código do Gradle para que possamos tentar descobrir o que está errado. :)
— just_user

1
Agora posso confirmar que essa não foi a causa raiz. Me desculpe.
— Chisko,

1
@AlexanderGavriliuk é o código da versão usado pela play store que precisa aumentar constantemente a cada upload. O número do patch provavelmente será redefinido se você aumentar a versão principal ou secundária. O número da versão nunca deve ser redefinido se você carregar o aplicativo na Play Store com o mesmo nome de pacote.
— just_user

40

Uma versão um pouco mais restrita da excelente resposta do CommonsWare cria o arquivo de versão se ele não existir:

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
}

onde está a parte sobre como criar o arquivo de versão se ele não existir?
— portfólio

4
if(versionPropsFile.exists())garante que ele não exploda se o arquivo não estiver lá. versionProps.store(versionPropsFile.newWriter(), null) substitui o arquivo, independentemente de ele já existir.
— Paul Cantrell,

Tive que verificar o que ?:significava em Groovy. O operador Elvis é um encurtamento do operador ternário.
— Daniel

30

Observei algumas opções para fazer isso e, no final das contas, decidi que era mais simples usar apenas a hora atual para o versionCode em vez de tentar incrementar automaticamente o versionCode e fazer o check-in em meu sistema de controle de revisão.

Adicione o seguinte ao seu 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
    }
}

No entanto, se você espera fazer upload de compilações além do ano 2696, pode usar uma solução diferente.


2
Se você está lendo isso agora e começando com um novo aplicativo, você pode subtrair 1510351294:))
— Entreco

eu não entendo isso! você não usa análises ou crashlytics ou qualquer outro serviço que forneça dados com códigos de versão e nomes? e você está brincando com isso facilmente?
— Amir Ziarati de

Se você tiver nomes de versão razoáveis, acho que está tudo bem. O Crashalytics também fornece o nome da versão.
— netcyrax

@emmby de onde você tira o número '1451606400'? ou o '1510351294' da #Entreco que tenho tentado calcular em vão!
— Joseph Wambura

18

Outra maneira de obter um versionCodeautomaticamente é definir versionCodeo número de commits no gitbranch em check-out . Ele cumpre os seguintes objetivos:

  1. versionCodeé gerado automaticamente e de forma consistente em qualquer máquina (incluindo um Continuous Integratione / ou Continuous Deploymentservidor).
  2. O aplicativo pode versionCodeser submetido ao GooglePlay.
  3. Não depende de nenhum arquivo fora do repo.
  4. Não envia nada para o repo
  5. Pode ser substituído manualmente, se necessário

Usando a biblioteca gradle-git para cumprir os objetivos acima. Adicione o código abaixo ao diretório build.gradledo seu arquivo /app:

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
}

NOTA: Para que este método funcione, é melhor implantar apenas na Google Play Store da mesma filial (por exemplo, master ).


embora seja, em essência, uma solução elegante, posso imaginar que isso reduziria drasticamente o tempo de construção, dependendo do que exatamente está acontecendo nas 2 linhas do git. Alguma experiência nisso?
— Esperançosamente

1
Não noto nenhuma melhora de desempenho se esta etapa for desativada. Temos usado o método localmente e em nossas máquinas de construção por mais de um ano e o desempenho não tem sido um problema. Se você notar qualquer problema de desempenho, me avise!
— C0D3LIC1OU5

Embora sua solução seja elegante, ela pode trazer algumas surpresas inesperadas desagradáveis. É fundamental que versionCodes sejam sempre maiores do que na versão anterior. E se você tiver um branch com 50 commits, e então criar outro branch que é mais novo, mas tem apenas 40 commits, talvez devido a esmagar um número de commits de algum recurso mesclado. Eu posso ver muitos motivos pelos quais seu histórico de commits nem sempre seria um fluxo linear de commits incrementais.
— JHH

@JHH Esses resultados não são inesperados. Como mencionei em uma nota, esse método funciona melhor ao implantar a partir do mesmo branch.
— C0D3LIC1OU5


10

Outra opção, para incrementar o versionCodee o versionName, é usar um carimbo de data / hora.

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
}

A partir de 1 de janeiro de 2022 formattedDate = date.format ('yyMMddHHmm') excede a capacidade de inteiros


1
A pessoa queria um número de compilação de incremento automático
— peter_pilgrim

6
@peter_pilgrim Caro é o OP.
— Mateus leu

Eu acho que esta é uma solução elegante, ela não depende de arquivos que podem desaparecer ou não ou que irão aparecer constantemente no git. Também ajuda a identificar de forma única cada construção para, pelo menos, os próximos 22 anos.
— Esperançosamente

citando developer.android.com:"Warning: O maior valor Google Play permite versionCode é 2100000000. "Então, o corte é realmente 2021.
— ths

Correção para o limite interno: omite os minutos e use o formato de data 'aaMMddHH', o código da versão conterá pelo menos horas.
— Pointer Null

10

Para incrementar versionCode apenas na versão de lançamento, faça isso:

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
    }

espera um c://YourProject/app/version.propertiesarquivo existente , que você criaria manualmente antes da primeira construção para terVERSION_CODE=8

Arquivo version.properties:

VERSION_CODE=8


Em vez disso, coloque-o dentro de uma tarefa e faça com que generateReleaseBuildConfig dependa dessa tarefa.
— lagos

versionName "1.0." + getSvnRevision () causa um erro. Onde o método getSvnRevision () está se referindo? Tem certeza de que não deve ser versionName "1.0." + Code (o nome da versão aumentará com o seu código de versão)?
— portfólio

1
@portfoliobuilder, substitua getSvnRevision () pelo código
— NickUnuchek 01 de

4

Criar arquivo version.properties

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

Mudança 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
}

}

Resultado : 1.1.3.6


Obrigado. E por que você inseriu um versionCode em versionName? Mesmo na segunda posição.
— CoolMind 01 de

Mas será semelhante a 1.71.3.76, por exemplo. Acho que melhor é 1.3.76, separando-o do código da versão.
— CoolMind

Sim . você pode mudar para "$ {_ major} .. $ {_ minor}. $ {_ patch}. $ {_ versionCode}" ou remover o patch
— Ahmad Aghazadeh

if (_major == 99) deve ser if (_minor == 99) ??
— Anirudh Bagri

2

Defina versionName emAndroidManifest.xml

android:versionName="5.1.5"

android{...}Bloco interno no build.gradlenível do aplicativo:

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

android{...}Bloco externo dentro build.gradledo nível do aplicativo:

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
}

Depois de criar o APK marcado:

android:versionName="5.1.6"

Nota: Se o seu versionName for diferente do meu, você precisa alterar o regex e extrair a lógica das partes .


1

Os exemplos mostrados acima não funcionam por diferentes razões

Aqui está minha variante pronta para uso com base nas ideias deste artigo:

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)"

        ...
    }
...
}

0

Créditos para CommonsWare (resposta aceita) Paul Cantrell (Criar arquivo se ele não existir) ahmad aghazadeh (nome e código da versão)

Então eu juntei todas as suas ideias e cheguei a isso. Esta é a solução de arrastar e soltar exatamente para o que o primeiro post pediu.

Ele atualizará automaticamente o versionCode e versionName de acordo com o status da versão. Claro, você pode mover as variáveis ​​para atender às suas necessidades.

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
}

0

Usando o Gradle Task Graph , podemos verificar / alternar o tipo de compilação.

A ideia básica é incrementar o versionCode em cada construção. Em cada construção, um contador armazenado no arquivo version.properties . Ele será mantido atualizado a cada nova construção de APK e substituirá a string versionCode no arquivo build.gradle por este valor de contador incrementado.

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'
}

Coloque o script acima dentro do arquivo build.gradle do módulo principal.

Site de referência: http://devdeeds.com/auto-increment-build-number-using-gradle-in-android/

Obrigado e cumprimentos!


0

O código do primeiro comentário incrementará o número a cada "Reconstruir projeto" e salvará o valor no arquivo "Propriedade da versão".

O código do segundo comentário gerará um novo nome de versão do arquivo APK enquanto "Constrói APKs".

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===============================================
        }
    }
}

Adicione algum texto mostrando o que você mudou. e por quê
— Matthew Kerian

0

na versão Gradle 5.1.1 no mac ive mudou a forma como os nomes das tarefas são recuperados, eu embora tentei obter o tipo / tipo de compilação da compilação, mas estava com preguiça de dividir o nome da tarefa:

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!")
}

o código é de @just_user este aqui


0

Existem duas soluções de que gosto muito. O primeiro depende da Play Store e o outro depende do Git.

Usando a Play Store, você pode incrementar o código da versão observando o maior código de versão carregado disponível . O benefício desta solução é que o upload de um APK nunca falhará, pois o código da sua versão é sempre um maior do que o que está na Play Store. A desvantagem é que distribuir seu APK fora da Play Store se torna mais difícil. Você pode configurar isso usando o Gradle Play Publisher seguindo o guia de início rápido e dizendo ao plug-in para resolver os códigos de versão automaticamente :

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

android {
    ...
}

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

Usando Git, você pode incrementar o código da versão com base em quantos commits e tags seu repositório possui. O benefício aqui é que sua saída é reproduzível e não depende de nada fora do seu repo. A desvantagem é que você precisa fazer um novo commit ou tag para alterar seu código de versão. Você pode configurar isso adicionando o plug - in Version Master Gradle :

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

android {
    ...
}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.