Reputation: 1856
I'm building an Android app with gradle. Until now I used the Manifest file to increase the versionCode, but I would like to read the versionCode from an external file and depending if it is the release flavor or the debug flavor increase the versionCode. I tried the extra properties, but you can't save them, which means that next time I build it I'm getting the same versionCode. Any help would be very much appreciated!
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'
}
Upvotes: 163
Views: 145803
Reputation: 4677
Using Gradle Task Graph we can check/switch build type.
The basic idea is to increment the versionCode on each build. On Each build a counter stored in the version.properties file. It will be keep updated on every new APK build and replace versionCode string in the build.gradle file with this incremented counter value.
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'
}
Place the above script inside your build.gradle file of main module.
Upvotes: 0
Reputation: 17131
Create new file inside <yourProjectLocation>/app/version.properties
MAJOR=0
MINOR=0
PATCH=1
VERSION_CODE=1
Add following lines in build.gradle
(Module file) :
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
}
}
Output : 0.0.1(1)
Upvotes: 14
Reputation: 24712
Instead of specifying the new version in a properties file, I created a Gradle task that can update the current versionName
and versionCode
automatically and also can get the new version string from command line (by passing arguments to the task with -P
followed by <argName>=<argValue>).
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)
}
}
Usage:
gradlew incrementVersion [-P[mode=major|minor|patch]|[overrideVersion=x.y.z]]
Examples:
gradlew :app:incrementVersion -Pmode=major
gradlew :app:incrementVersion -PoverrideVersion=4.5.6
Upvotes: 2
Reputation: 4007
There are two solutions I really like. The first depends on the Play Store and the other depends on Git.
Using the Play Store, you can increment the version code by looking at the highest available uploaded version code. The benefit of this solution is that an APK upload will never fail since your version code is always one higher than whatever is on the Play Store. The downside is that distributing your APK outside of the Play Store becomes more difficult. You can set this up using Gradle Play Publisher by following the quickstart guide and telling the plugin to 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"
}
Using Git, you can increment the version code based on how many commits and tags your repository has. The benefit here is that your output is reproducible and doesn't depend on anything outside your repo. The downside is that you have to make a new commit or tag to bump your version code. You can set this up by adding the Version Master Gradle plugin:
plugins {
id 'com.android.application'
id 'com.supercilex.gradle.versions' version 'x.x.x'
}
android {
...
}
Upvotes: 1
Reputation: 522
Examples shown above don't work for different reasons
Here is my ready-to-use variant based on ideas from this article:
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)"
...
}
...
}
Upvotes: 4
Reputation: 359
in the Gradle 5.1.1 version on mac ive changed how the task names got retrieved, i althought tried to get build flavour / type from build but was to lazy to split the task name:
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!")
}
code is from @just_user this one
Upvotes: 0
Reputation: 116
The First Commented code will increment the number while each "Rebuild Project" and save the the value in the "Version Property" file.
The Second Commented code will generate new version name of APK file while "Build 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===============================================
}
}
}
Upvotes: 0
Reputation: 1007474
I would like to read the versionCode from an external file
I am sure that there are any number of possible solutions; here is one:
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
}
This code expects an existing version.properties
file, which you would create by hand before the first build to have VERSION_CODE=8
.
This code simply bumps the version code on each build -- you would need to extend the technique to handle your per-flavor version code.
You can see the Versioning sample project that demonstrates this code.
Upvotes: 240
Reputation: 12067
Here comes a modernization of my previous answer which can be seen below. This one is running with Gradle 4.4 and Android Studio 3.1.1.
What this script does:
projectDir/apk
to make it more accessible.This script will create a version number which looks like v1.3.4 (123)
and build an apk file like AppName-v1.3.4.apk.
Major version ⌄ ⌄ Build version
v1.3.4 (123)
Minor version ⌃|⌃ Patch version
Major version: Has to be changed manually for bigger changes.
Minor version: Has to be changed manually for slightly less big changes.
Patch version: Increases when running gradle assembleRelease
Build version: Increases every build
Version Number: Same as Patch version, this is for the version code which Play Store needs to have increased for each new apk upload.
Just change the content in the comments labeled 1 - 3 below and the script should do the rest. :)
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:
I want the versionName to increase automatically as well. So this is just an addition to the answer by CommonsWare which worked perfectly for me. This is what works for me
defaultConfig {
versionCode code
versionName "1.1." + code
minSdkVersion 14
targetSdkVersion 18
}
EDIT:
As I am a bit lazy I want my versioning to work as automatically as possible. What I want is to have a Build Version that increases with each build, while the Version Number and Version Name only increases when I make a release build.
This is what I have been using for the past year, the basics are from CommonsWare's answer and my previous answer, plus some more. This results in the following versioning:
Version Name: 1.0.5 (123) --> Major.Minor.Patch (Build), Major and Minor are changed manually.
In 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 and versionCode is increased if you assemble your project through the terminal with 'assemble', 'assembleRelease' or 'aR' which creates a new folder in your project root called apk/RELEASE so you don't have to look through build/outputs/more/more/more to find your apk.
Your version properties would need to look like this:
VERSION_NUMBER=1
VERSION_BUILD=645
VERSION_PATCH=1
Obviously start with 0. :)
Upvotes: 98
Reputation: 8680
Another way of getting a versionCode
automatically is setting versionCode
to the number of commits in the checked out git
branch. It accomplishes following objectives:
versionCode
is generated automatically and consistently on any machine (including a Continuous Integration
and/or Continuous Deployment
server).versionCode
is submittable to GooglePlay.Using gradle-git library to accomplish the above objectives. Add code below to your build.gradle
file the /app
directory:
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
}
NOTE: For this method to work, it's best to only deploy to Google Play Store from the same branch (ex. master
).
Upvotes: 22
Reputation: 100462
I looked at a few options to do this, and ultimately decided it was simpler to just use the current time for the versionCode instead of trying to automatically increment the versionCode and check it into my revision control system.
Add the following to your 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
}
}
However, if you expect to upload builds beyond year 2696, you may want to use a different solution.
Upvotes: 44
Reputation: 1253
Credits to CommonsWare (Accepted Answer) Paul Cantrell (Create file if it doesn't exist) ahmad aghazadeh (Version name and code)
So I mashed all their ideas together and came up with this. This is the drag and drop solution to exactly what the first post asked.
It will automatically update the versionCode and versionName according to release status. Of course you can move the variables around to suite your needs.
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
}
Upvotes: 1
Reputation: 15821
Define versionName in AndroidManifest.xml
android:versionName="5.1.5"
Inside android{...}
block in build.gradle
of app level :
defaultConfig {
applicationId "com.example.autoincrement"
minSdkVersion 18
targetSdkVersion 23
multiDexEnabled true
def version = getIncrementationVersionName()
versionName version
}
Outside android{...}
block in build.gradle
of app level :
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
}
After create singed APK :
android:versionName="5.1.6"
Note : If your versionName different from my, you need change regex and extract parts logic.
Upvotes: 2
Reputation: 12887
To increment versionCode only in release version do it:
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
}
expects an existing c://YourProject/app/version.properties
file, which you would create by hand before the first build to have VERSION_CODE=8
File
version.properties
:
VERSION_CODE=8
Upvotes: 11
Reputation: 1856
Another option, for incrementing the versionCode
and the versionName
, is using a timestamp.
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
}
Starting on January,1 2022 formattedDate = date.format('yyMMddHHmm') exceeds the capacity of Integers
Upvotes: 11
Reputation: 2467
Recently I was working on a gradle plugin for Android that makes generating versionCode and versionName automatically. there are lots of customization. here you can find more info about it https://github.com/moallemi/gradle-advanced-build-version
Upvotes: 14
Reputation: 9324
A slightly tightened-up version of CommonsWare's excellent answer creates the version file if it doesn't exist:
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
}
Upvotes: 43