自动增量额外属性渐变版本代码

我正在用 gradle 开发一个 Android 应用程序。到目前为止,我一直使用 Manifest 文件来增加 versionCode,但是我希望从外部文件读取 versionCode,这取决于它是发布风格还是调试风格来增加 versionCode。我尝试了额外的属性,但是您无法保存它们,这意味着下次构建它时,我将得到相同的 version Code。 任何帮助都是非常感激的!

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'
}
130157 次浏览

我想从一个外部文件读取版本代码

我相信有许多可能的解决办法,这里有一个:

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之前需要手工创建该文件。

这段代码只是在每次构建时碰撞了版本代码——您需要扩展这项技术来处理各种版本代码。

您可以看到演示此代码的 版本控制示例项目

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

剧本的作用:

  • 创建一个 Version. properties文件,如果没有存在(向上投票保罗坎特雷尔的答案下面,这是我从哪里得到的想法,如果你喜欢这个答案)
  • 对于每个构建,调试版本或任何时候你按下运行按钮在 Android 工作室的 VERION _ BUILD 数量增加。
  • 每次你组装一个发行版,你的 Android 版本代码的播放商店增加和你的 电话号码增加。
  • 奖励: 在构建完成后,复制您的 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 Store 需要增加的版本代码。

只需更改下面标签为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 {
...
}
}

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

初步答案:

我希望 version Name 也自动增加。所以这只是对 CommsWare 给出的答案的一个补充,它对我来说非常有用。我就喜欢这样

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

编辑:

由于我有点懒,我希望我的版本尽可能自动地工作。我想要的是有一个 构建版本,随着每次构建增加,而 版本号码版本名称只增加,当我做一个发布版本。

这是我过去一年一直在使用的,基本内容来自于 CommonsWare 的答案和我之前的答案,还有其他一些。这导致了以下版本控制:

版本名称: 1.0.5(123)—— > 大。小。修补程序(构建) ,大和小手动更改。

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


...
}


...

如果你通过 “组装”“汇编发布”“ aR”终端组装你的项目,它会在你的项目根目录中创建一个名为 apk/RELEASE 的新文件夹,这样你就不必通过构建/输出/更多/更多来找到你的 apk。

您的版本属性应该是这样的:

VERSION_NUMBER=1
VERSION_BUILD=645
VERSION_PATCH=1

显然是从0开始。 :)

如果版本文件不存在,一个稍微紧凑一点的 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
}

最近我在为 Android 开发一个渐变插件,它可以自动生成 版本代码版本名称。有很多定制的。在这里你可以找到更多关于它的信息 Https://github.com/moallemi/gradle-advanced-build-version

另一个用于递增 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日开始 Format tedDate = date.format (‘ yMMddHHMM’) 超过整数的容量

要在发布版本中增加 version 代码,请执行以下操作:

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_CODE=8

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

  1. versionCode是在任何机器(包括 Continuous Integration和/或 Continuous Deployment服务器)上自动生成的。
  2. 具有这个 versionCode的应用程序可以提交到 GooglePlay。
  3. 不依赖回购之外的任何文件。
  4. 不会把任何东西推向回收站
  5. 如果需要,可以手动重写

使用 你这个饭桶库来实现上述目标。将下面的代码添加到 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 Store (例如。master).

Using 分级任务图 we can check/switch 建造型式。

基本思想是在每次构建时增加 版本代码。在每次生成时,在 Version. properties文件中存储一个计数器。它将随时更新每个新的 APK 构建,并用这个递增的计数器值替换 建造,分级文件中的 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/

谢谢!

AndroidManifest.xml中定义 版本名称

android:versionName="5.1.5"

在应用程序级别的 build.gradle中的 android{...}块内部:

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

应用程序级别的 build.gradleandroid{...}外部块:

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"

注意: 如果你的 版本名称和我的不同,你需要改变 正则表达式提取部件逻辑

<yourProjectLocation>/app/version.properties中创建新文件

MAJOR=0
MINOR=0
PATCH=1
VERSION_CODE=1

build.gradle(模块文件)中添加以下代码行:

android {
// other properties....
// add following lines...


def _versionCode=0
def _major=0
def _minor=0
def _patch=0


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==100) {
_patch=0
_minor=_minor+1
}
if(_minor == 10){
_minor = 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}.${_minor}.${_patch}(${_versionCode})"


defaultConfig {
// other properties...
// change only these two lines


versionCode _versionCode
versionName _versionName
}
}

输出: 0.0.1(1)

学分 通用软件(接受答案) 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
}

我查看了一些可以做到这一点的选项,最终决定只使用 version Code 的当前时间,而不是尝试自动增加 version Code 并将其签入到我的修订控制系统中,这样更简单。

在你的 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
}
}

但是,如果您希望在2696年之后上载构建,则可能需要使用不同的解决方案。

第一个注释的代码将递增的数字,而每个“重建项目”和保存的价值在“版本属性”文件。

第二个注释代码将生成新的版本名称的 APK 文件,而“建立 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===============================================
}
}
}

在 mac ive 的 Gradle 5.1.1版本中,改变了如何检索任务名称,我本来想从 build 中获取构建风味/类型,但懒得分割任务名称:

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 这个

上面显示的示例由于不同的原因不起作用

下面是我根据本文中的观点提出的一个可以随时使用的变体:

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


...
}
...
}

有两种解决方案我非常喜欢。第一种依赖于 Play Store,另一种依赖于 Git。

使用 Play Store,您可以通过查看最高可用的 已上传版本代码来增加版本代码。这个解决方案的好处是 APK 上传永远不会失败,因为您的版本代码总是比 Play Store 上的任何代码高一个版本。缺点是在 Play Store 之外分发 APK 变得更加困难。你可以使用 Gradle Play Publisher 设置这个,按照 快速启动指南快速启动指南并告诉插件 自动解析版本代码:

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


android {
...
}


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

使用 Git,您可以根据存储库中有多少提交和标记来增加版本代码。这里的好处是,您的输出是可重复的,并且不依赖于回购之外的任何东西。缺点是您必须做一个新的提交或标记来提升您的版本代码。您可以通过添加 版本主级插件来设置:

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


android {
...
}

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

应用程序 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