Automatic versionCode generation in Android Gradle

https://www.jayway.com/2015/03/11/automatic-versioncode-generation-in-android-gradle/


In this post I’ll show you how to setup Gradle for an Android project to automatically generate a usable versionCode from a standardized version number.

The problem

The Android Gradle build system is wonderful, with a good balance between sane defaults, readability and extensibility. However, handling of versionCode and versionName isn’t as automatic as one often would like. Thanks to the dynamic Groovy foundation of Gradle this issue is easy to remedy.

One problem is that you often want to implement a sane pattern of generating the versionCode value. This isn’t as easy as it might appear as there are a couple of things to take into consideration, many of which ties into how Google Play handles the versionCode.

  • The version code needs to increase for each release.
  • You can only upload one APK per version code, so it needs to be unique for each release.
  • Sometimes you want to use Release Candidates for alpha and beta testing, so these needs to have unique version codes.
  • The version codes of your Release Candidates must however be lesser than the version code of the final release.
  • You also want to be able to release point/patch releases of older apps, with lesser version codes than the latest version.

The last point is especially interesting due to the nature of the minSdkVersion value. To summarize this problem: you might have older version of your app active on Google Play, since these run on older devices than your latest version. If a bug appears, you want to be able to push out a fix even for these older versions, with a version code lower than the latest version.

The solution

The solution to all of this is to adapt a standardized versioning schema. There’s no need to use a too complex schema; we just want something that covers our use case. The chosen schema is therefore a simplified version of the Maven versioning schema. This schema uses Major, Minor and Patch versions, together with -SNAPSHOT and -RC suffixes. Versions will look like “1.0.1”, “1.2.0-SNAPSHOT”, “2.4.0-RC1” and so on.

  • The Major version denotes major changes to the app. If large parts are rewritten it warrants a Major version bump.
  • The Minor version denotes public releases. Each time a version has been released this number is bumped.
  • The Patch version denotes bug fixes and patches. It’s only ever used if an existing release needs to be amended.
  • “-SNAPSHOT” is used during development. These versions are never put on Google Play.
  • “-RC*” denotes Release Candidates. These are used during final testing, when the app is distributed externally, but not yet publicly. They lead up to the final release.
  • No suffix denotes a final release. The version code should always be higher than any Release Candidate.

The version name needs to be translated into a version code. We do this by allocating two digits to each version segment. That gives us 100 values for each one, with the Major version taking the highest numbers and the suffixes taking the lowest number.

So, version “1.2.3-SNAPSHOT” would then result in version code 1020300, whereas version “1.2.3-RC4” would result in version code 1020304. Final releases always gets assigned 99 as their last code, to make sure that they always have a higher version code than Release Candidates.

Example

Consider us working on our app, and that we’re currently working on version 1.2.0-SNAPSHOT. The version code is 1020000. As release nears we want to do a first test with a selection of users on Google Play, and we therefore change the version to 1.2.0-RC1, tag it, build it and put in on the alpha or beta channel on Google Play. Version code is now 1020001. Perhaps we need more fixes, so we do a 1.2.0-RC2 release. Version code is now 1020002.
Everything now looks good, so we change the version to 1.2.0, the final release, and pushes this to Google Play. Version code is now 1020099.

As soon as this is done we start on the next iteration, which is version 1.3.0-SNAPSHOT. Version code is 1030000. After some days a bug is found in the released version, and we need to push out a quick fix. We do this by creating a “1.2” branch from the latest release tag, fixing the bug, and set the version name to 1.2.1. Version code is 1020199.

Implementation

So, how to implement all of this in a smooth way? One approach is to do all of this manually. That’s of course doable, but we much rather make sure that as much as possible is automated. Gradle to the rescue then!

In our Android Gradle project we’ll start by seting the version in the gradle.properties file at the top level. Why? Well, because it’s a convention and there are existing Gradle tools which works with this approach. Thus, gradle.properties now contains

Gradle will automatically read from this file and make the version value available.

Now we have to add some code which can parse the version value and produce a versionCode value in accordance to the rules set up above. Create a file named versioning.gradle and put this code into it

This code isn’t activated by default, so we need to tell Gradle to do that. Alter the top level build.gradle file and add this line

Now for the final step; to configure the Android plugin. Edit the app/build.gradle file and change the android.defaultConfig section to read

And there you have it!
An example of this can be seen in this simple example project.

All code licensed under CC0.

Feel free to share this article:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值