A new versionCode scheme for Android
This is a repost of the original from my previous blog at https://world.hey.com/jaran.flaath
The official Android documentation gives little in terms of best practices around versionCode, apart from that it has to be an ever increasing integer.
We have been using the Git commit count as the versionCode, on the projects where I have been involved. This has been a success in most cases, however there are a couple of issues with this approach:
- It requires external command line tools to generate the number
- It does not work well with Github Actions (even if the workflow can be configured to resolve this, if you really want to use the Git commit count), and we have increasingly been moving projects to Github Actions
- If you should deploy bundles from different branches with different commit counts you can run in to problems
The best would obviously be if we could have an automatically generated versionCode which require no external tools and no special configuration, that would be for ever increasing for every build.
The Proposal
The latest proposal on the table: The Time Based Semantic Version Code 2000 (TTBSV2K)
TTBSV2K attempts to turn the versionCode into something which can be decoded (relatively easy), is automatically generated and does not require any external tools.
TTBSV2K has the format:
YYDDDMMMM
where
YY is the current year (last two digits): 22, 23, 24
DDD is the day of the year, 0-padded: 001, 056, 366
MMMM is the minute of the day, 0-padded: 0001, 0790, 1440
This gives you a more easily decodable versionCode: 220590790
The Code
For your Kotlin DSL app/build.gradle.kts file, add these imports to the top:
import java.time.LocalDateTime
import java.time.ZoneId
and put this somewhere else in the file:
fun generateVersionCode(): Long {
val now = LocalDateTime.now(ZoneId.of("UTC"))
val versionCode = "${now.year - 2000}" +
now.dayOfYear.toString().padStart(3, '0') +
(now.hour * 60 + now.minute).toString().padStart(4, '0')
return versionCode.toLong()
}
If you're using the Groovy DSL, add the following snippet to your app/build.gradle file:
import java.time.LocalDateTime
import java.time.ZoneId
static Integer generateVersionCode() {
def now = LocalDateTime.now(ZoneId.of("UTC"))
def versionCode = "${now.year - 2000}" +
now.dayOfYear.toString().padLeft(3, '0') +
(now.hour * 60 + now.minute).toString().padLeft(4, '0')
return versionCode.toInteger()
}
The generateVersionCode function can then be called where you set the app's versionCode:
android {
defaultConfig {
versionCode generateVersionCode()
versionName "1.0"
...
}
}
✉️ Feel free to email me your thoughts on The Time Based Semantic Version Code 2000.
Disclaimer: This versionCode scheme will no longer work starting January 1st 2100 00:00:00. If you believe your app will still be in production and on the Play Store on that date, you might want to add some form of warning for your future team mates – so they can prepare.