使用gradle额外属性自动增加VersionCode

时间:2014-01-28 12:16:34

标签: android gradle android-gradle build.gradle

我正在使用gradle构建Android应用。到目前为止,我使用Manifest文件来增加versionCode,但是我想从外部文件读取versionCode,并且取决于它是发布版本还是调试风格增加了versionCode。我尝试了额外的属性,但是你无法保存它们,这意味着下次我构建它时我得到了相同的versionCode。 非常感谢任何帮助!

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

17 个答案:

答案 0 :(得分:179)

  

我想从外部文件中读取versionCode

我确信有许多可能的解决方案;这是一个:

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
}

此代码需要一个现有的version.properties文件,您可以在第一次构建之前手动创建VERSION_CODE=8

这段代码只会破坏每个版本的版本代码 - 您需要扩展该技术来处理每个版本的代码。

您可以看到演示此代码的the Versioning sample project

答案 1 :(得分:69)

以下是我之前回答的现代化,可以在下面看到。这个是使用 Gradle 4.4 Android Studio 3.1.1 运行的。

此脚本的作用:

  • 如果不存在,则创建一个 version.properties 文件(上面的投票Paul Cantrell的答案,如果你喜欢这个答案我就是这个想法)
  • 对于每个版本,调试版本或在Android Studio中按下运行按钮的任何时候,VERSION_BUILD编号都会增加。
  • 每次发布​​版本时,Play商店的Android versionCode 都会增加,修补程序编号会增加。
  • 奖励:构建完成后,将apk复制到projectDir/apk以使其更易于访问。

此脚本将创建一个类似于v1.3.4 (123)的版本号,并构建一个类似 AppName-v1.3.4.apk 的apk文件。

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

主要版本必须手动更改才能进行更大的更改。

次要版本:必须手动更改,以便稍微改变一下。

修补程序版本:运行gradle assembleRelease

时增加

构建版本:增加每个构建

版本号:修补程序版本相同,这是针对每个新的apk上传需要增加Play商店的版本代码。

只需更改下面标有1 - 3的注释中的内容,脚本应该完成剩下的工作。 :)

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

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

INITIAL ANSWER:

我希望versionName也自动增加。所以这只是CommonsWare的答案的补充,它对我来说非常有用。这对我有用

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

修改

由于我有点懒,我希望我的版本控制能够尽可能自动地工作。我想要的是每次构建都会增加构建版本,而版本号版本名称仅在我发布时增加建立。

这是我过去一年所使用的,基础知识来自CommonsWare的答案和我以前的答案,以及更多。这导致以下版本控制:

版本名称: 1.0.5(123) - > Major.Minor.Patch(Build),Major和Minor都是手动更改的。

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

    ...
}

...

如果您通过终端使用'assemble''assembleRelease''aR'组装您的项目,则会增加Patch和versionCode在您的项目根目录中创建一个名为apk / RELEASE的新文件夹,这样您就不必查看构建/输出/更多/更多/更多来查找您的apk。

您的版本属性需要如下所示:

VERSION_NUMBER=1
VERSION_BUILD=645
VERSION_PATCH=1

显然从0开始。:)

答案 2 :(得分:34)

如果版本文件不存在,那么稍微收紧版本的CommonsWare的优秀答案会创建该文件:

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
}

答案 3 :(得分:23)

我查看了一些选项来做到这一点,最终决定只使用versionCode的当前时间而不是尝试自动增加versionCode并将其检入我的修订控制系统。

将以下内容添加到vagrant ssh

build.gradle

但是,如果您希望上传超过2696年的版本,则可能需要使用其他解决方案。

答案 4 :(得分:16)

自动获取versionCode的另一种方法是将versionCode设置为已签出git分支中的提交次数。它实现了以下目标:

  1. versionCode是在任何计算机(包括Continuous Integration和/或Continuous Deployment服务器)上自动生成的。
  2. 使用此versionCode的应用可提交给GooglePlay。
  3. 不依赖于repo之外的任何文件。
  4. 不会向repo推送任何东西
  5. 如果需要,可以手动覆盖
  6. 使用gradle-git库来实现上述目标。将以下代码添加到build.gradle目录中的/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
    }
    

    注意:要使此方法有效,最好只从同一分支部署到Google Play商店(例如master)。

答案 5 :(得分:12)

最近我正在开发Android的gradle插件,可以自动生成 versionCode versionName 。有很多定制。在这里你可以找到更多关于它的信息 https://github.com/moallemi/gradle-advanced-build-version

答案 6 :(得分:10)

另一个用于递增versionCodeversionName的选项是使用时间戳。

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
}

从2022年1月1日开始 formattedDate = date.format('yyMMddHHmm') 超过整数的容量

答案 7 :(得分:10)

仅在发布版本中增加versionCode:

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
    }

需要一个现有的c://YourProject/app/version.properties文件,您可以在第一次构建之前手动创建VERSION_CODE=8

文件 version.properties

VERSION_CODE=8

答案 8 :(得分:3)

创建文件version.properties

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

更改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
}

}

输出:1.1.3.6

答案 9 :(得分:1)

AndroidManifest.xml

中定义 versionName
android:versionName="5.1.5"

应用级android{...}内的build.gradle块内:

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

应用级别的android{...}内的build.gradle阻止:

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
}

创建烧焦后的APK:

android:versionName="5.1.6"

注意:如果 versionName 与我的不同,则需要更改正则表达式提取部件逻辑

答案 10 :(得分:0)

致信 CommonsWare(接受的答案) Paul Cantrell(创建文件,如果它不存在) ahmad aghazadeh(版本名称和代码)

所以我把他们所有的想法混合在一起并想出了这个。这是第一篇文章所要求的拖放解决方案。

它会根据发布状态自动更新versionCode和versionName。当然,您可以移动变量来满足您的需求。

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
}

答案 11 :(得分:0)

使用 Gradle任务图,我们可以检查/切换构建类型。

基本思想是在每个构建上增加 versionCode 。 On Each构建一个存储在 version.properties 文件中的计数器。它将在每个新的APK版本上保持更新,并使用此递增的计数器值替换 build.gradle 文件中的versionCode字符串。

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

将上述脚本放在main模块的build.gradle文件中。

参考网站: http://devdeeds.com/auto-increment-build-number-using-gradle-in-android/

谢谢&amp;此致!

答案 12 :(得分:0)

  

在每个“重建项目”时,“第一批注释”代码将递增该数字,并将其值保存在“版本属性”文件中。

     

“第二条注释”代码将在“构建APK”时生成APK文件的新版本名称。

dm=0

答案 13 :(得分:0)

在Mac ive上的Gradle 5.1.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.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!")
}

代码来自@just_user this one

答案 14 :(得分:0)

上面显示的示例由于不同的原因而无法工作

这是我根据这篇文章的思想准备的即用型:

android {
    compileSdkVersion 28

    // https://stackoverflow.com/questions/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)"

        ...
    }
...
}

答案 15 :(得分:0)

我真的很喜欢两种解决方案。第一个取决于Play商店,另一个取决于Git。

使用Play商店,您可以查看最高可用的上载的版本代码来增加版本代码。此解决方案的好处在于,APK的上传不会失败,因为您的版本代码总是比Play商店上的版本代码高一个。不利之处在于,在Play商店之外分发APK变得更加困难。您可以按照以下说明使用Gradle Play Publisher进行设置:quickstart guide,然后将插件告知resolve version codes automatically

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

android {
    ...
}

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

使用Git,您可以根据存储库中的提交和标记数量来增加版本代码。这样做的好处是您的输出是可复制的,并且不依赖于回购之外的任何东西。缺点是您必须进行新的提交或标记才能更改版本代码。您可以通过添加Version Master Gradle plugin

进行设置
plugins {
    id 'com.android.application'
    id 'com.supercilex.gradle.versions' version 'x.x.x'
}

android {
    ...
}

答案 16 :(得分:0)

我没有在属性文件中指定新版本,而是创建了一个 Gradle 任务,它可以自动更新当前的 versionNameversionCode,还可以从命令行获取新版本字符串(通过传递使用 -P 后跟 = 的任务参数。

app build.gradle.kts

project.version = "1.2.3"

tasks.create("incrementVersion") {
    group = "versioning"
    description = "Increments the version to make the app ready for next release."
    doLast {
        var (major, minor, patch) = project.version.toString().split(".")
        val mode = project.properties["mode"]?.toString()?.toLowerCaseAsciiOnly()
        if (mode == "major") {
            major = (major.toInt() + 1).toString()
            minor = "0"
            patch = "0"
        } else if (mode == "minor") {
            minor = (minor.toInt() + 1).toString()
            patch = "0"
        } else {
            patch = (patch.toInt() + 1).toString()
        }
        var newVersion = "$major.$minor.$patch"

        val overrideVersion = project.properties["overrideVersion"]?.toString()?.toLowerCaseAsciiOnly()
        overrideVersion?.let { newVersion = it }

        val newBuild = buildFile
            .readText()
            .replaceFirst(Regex("version = .+"), "version = \"$newVersion\"")
            .replaceFirst(Regex("versionName = .+\""), "versionName = \"$newVersion\"")
            .replaceFirst(Regex("versionCode = \\d+"), "versionCode = ${(android.defaultConfig.versionCode ?: 0) + 1}")
        buildFile.writeText(newBuild)
    }
}

用法:

gradlew incrementVersion [-P[mode=major|minor|patch]|[overrideVersion=x.y.z]]

示例:

gradlew :app:incrementVersion -Pmode=major
gradlew :app:incrementVersion -PoverrideVersion=4.5.6