Keep sanity with your versionCode

Friday, Mar 16, 2018| Tags: android

Releasing Android apps is not a joke: Increase your version number, create a release build, sign the build, upload the APK, write nice release notes (in all supported languages!), roll to alpha, roll to beta, roll a 5% to Production, a 10%… until finally all your users get the update.

Thankfully we have learned to automate most of that. Your CI will take care of building and signing the release and upload it to the Play Store. But there are things you shouldn’t let your CI do: one of them is setting your versionCode. Let me show you why.

A thing you may be tempted to do is to let the versionCode to be the Jenkins build number. I remember BuddyBuild (RIP) gave that option as well, to set the versionCode based on their build number.

That’s a small mistake that can carry large consequences, since your versionCode and your versionName will be unrelated.

So for example if you have version 1.2.0 in production, with a versionCode of 42, and you decide to give to your beta users the release 1.3.0 with versionCode 43, the day you need to release a 1.2.1 you will be forced to provide a versionCode greater than 43, and you will force your beta users to “downgrade” from 1.3.0 to 1.2.1:

  • 1.2.0 → versionCode: 42 in Production
  • 1.3.0 → versionCode: 43 in Beta
  • 1.2.1 → versionCode: 44 (???) in Production and Beta

Dan Lew wrote recently an article where his team had a similar problem, check it out!

The **versionCode** is more important than the **versionName**.

For keeping my sanity, I use the following formula:

First I define a Major, Minor and Build numbers in my build.gradle file:

ext {
versionMajor = 1
versionMinor = 4
buildNum = 9

And then I calculate the versionCode using this formula:

Major * 1.000.000 + Minor * 1.000 + Build

versionCode versionMajor * 1000000 + versionMinor * 1000 + buildNum

versionName String.valueOf(versionMajor) + “.”
+ String.valueOf(versionMinor) + “.”
+ String.valueOf(buildNum)

With the example above the version codes would have been:

  • 1.2.0 → versionCode:1002000 in Production
  • 1.2.1 → versionCode:1002001 in Production
  • 1.3.0 → versionCode:1003000 in Beta

Then, the beta users would have stayed in version 1003000 and the production users would have been upgraded to 1002001.

When you create a new release, you only need to update the buildNum and maybe also the versionMinor or the versionMajor . And in our case, we increate the buildNum automatically with our release script.

Another trick: I use even numbers for release builds and odd numbers for development builds, so I can differentiate when QA reports an issue or a crash report comes.

  • 1.3.0 → Even, is a ready-to-release build
  • 1.3.1 → Odd, is a work-in-progress build

I got this idea from the version numbering for the Linux kernel.

To finish here’s a rule of thumb: Never repeat a version number! If a release goes wrong (thank you ProGuard) always increase the build number when preparing a new release.

Want to learn more Android and Flutter? Check my courses here.


Contact with me