thunderbird-android icon indicating copy to clipboard operation
thunderbird-android copied to clipboard

VersionCode should be autogenerated to ease release automation

Open wmontwe opened this issue 1 year ago • 8 comments

To streamline our release automation process, it would be beneficial to implement an automatic version code generation strategy rather than relying on manual updates.

Reviewing the Firefox for Android project, I found they use a date-based system for generating a unique and sequentially increasing versionCode. Their method utilizes the format yDDDHHmm, where:

  • y represents the last digit of the year minus 16 (e.g., 2017 becomes 1)
  • DDD is the zero-padded day of the year (e.g., September 6th is 249)
  • HH for the hour of the day (00-23)
  • mm for the minute within the hour

This approach stays within the maximum allowed versionCode of 2,100,000,000, typically producing a 9-digit code, ensuring each version is unique and sequentially higher than the last.

I propose we adopt a similar, date-based calculation for our version code, incorporating the same format yDDDHHmm:

  • y: The number of years since a base year, with 2024 as the starting point (e.g., 2024 is 0)
  • DDD: The day of the year in 3 digits, zero-padded
  • HH The hour of the day in 2 digits (00-23)
  • mm The minute of the hour in 2 digits

For example:

  • 2024-02-09 16:45 -> 0 | 040 | 16 | 45 -> 401_645 -> 6 digits
  • 2025-10-12 09:23 -> 1 | 285 | 09 | 23 -> 12_850_923 -> 8 digits
  • 2123-02-09 16:45 -> 99 | 040 | 16 | 45 -> 990_401_645 -> 9 digits

Alternatively the format ymmmmmm, with even more head room but harder to read:

  • y The number of years since a base year, with 2024 as the starting point (e.g., 2024 is 0)
  • mmmmmm Day of year in minutes + Hour in minutes + Minutes (6 digits)

This alternative approach would generate:

  • 2024-02-09 16:45 -> 0 | 057_165 -> 57_165 -> 5 digits
  • 2025-10-12 09:23 -> 1 | 409_523 -> 1_409_523 -> 7 digits
  • 2123-02-09 16:45 -> 99 | 057_165 -> 99_057_165 -> 8 digits
  • 3023-02-09 16:45 -> 999 | 057_165 -> 999_057_165 -> 9 digits

I welcome any feedback or suggestions on these proposed methods.

wmontwe avatar Feb 09 '24 17:02 wmontwe

I think this might cause problems with F-Droid releases. I think they parse gradle files manually and if it's not a constant, they can't do that.

ByteHamster avatar Feb 09 '24 17:02 ByteHamster

Right, F-Droid expects a static version code. So, if we write the version code to a file and the release build is picking that up, it should be fine. I guess we also need to commit this file for reproducible builds.

wmontwe avatar Feb 12 '24 07:02 wmontwe

We could also use prebuild to inject the desired date before building.

wmontwe avatar Feb 12 '24 08:02 wmontwe

Is it really necessary to have a versionCode scheme based on the date? Can't we just have a script increment the version code for every release?

cketti avatar Feb 12 '24 13:02 cketti

It eliminates the need to do manual versionCode changes. Otherwise any automation needs manual intervention or is self updating. I'm not a fan of allowing CI worklfows to commit code.

wmontwe avatar Feb 14 '24 14:02 wmontwe

A total different approach is to derive the version code from a git tag. But that is usually more complicated.

wmontwe avatar Feb 14 '24 14:02 wmontwe

Currently in F-Droid all the metadata and release notes/changelog have disappeared: https://f-droid.org/en/packages/com.fsck.k9/

EDIT: Found the deedicated issue here https://github.com/thunderbird/thunderbird-android/issues/7709#issue-2179118986

scollovati avatar Mar 18 '24 18:03 scollovati

If you wanted, rather than using a git tag, you can simply count the number of commits as the version code. Something like git rev-list --first-parent --count origin/main here's a sample you could add in the gradle file.

val getVersionCode: () -> Int = {
    try {
        val stdout = ByteArrayOutputStream()
        exec {
            commandLine("git", "rev-list", "--first-parent", "--count", "origin/main")
            standardOutput = stdout
        }
        stdout.toString().trim().toInt()
    } catch (ignored: Exception) {
        -1
    }
}

abdoughnut avatar Mar 20 '24 04:03 abdoughnut