Thoughts on life, work and the universe. Sometimes writing in English og noen ganger på norsk.

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:

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.