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/
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.