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! http://blog.danlew.net/2018/03/15/how-to-screw-over-your-beta-users-without-really-trying/
versionCode is more important than the
For keeping my sanity, I use the following formula:
First I define a Major, Minor and Build numbers in my
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) + "."
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.
Christopher Orr has a nice talk where he explains how to combine the Jenkins BUILD_NUMBER and a similar formula to the one presented here. Check it out!
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.