Write down how to cut a release

Six months from now none of this will be obvious: which of the two version
numbers has to go up, that the changelog file is named after the
versionCode rather than the version name, and that the tag has to keep its
v prefix — checkupdates takes the tag name verbatim as the commit to
build, so a tag named 1.1 would quietly break the automation.

Also records the two things that make the screenshots reproducible, both
of which cost time to find: a headless capture lands whenever the
virtual-time budget runs out rather than when the script finishes, and
CSS transitions don't advance under it, so a panel caught mid-transition
photographs in its old colour.

States the part that is easy to get wrong in the other direction too:
after the first submission there is nothing to do in fdroiddata. The bot
watches the tags here.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-11 21:44:27 +02:00
co-authored by Claude Opus 5
parent c27878b826
commit a672268a8f
2 changed files with 120 additions and 0 deletions
+4
View File
@@ -6,6 +6,10 @@ Backgammon Galaxy control. Defaults to 3:00 + 12s.
Plain HTML, CSS and JavaScript. No frameworks, no fonts, no images, no network. Plain HTML, CSS and JavaScript. No frameworks, no fonts, no images, no network.
There's an Android package too, in `android/` — a WebView around the same
`public_html/`, so the two can't drift. It declares no permissions at all. See
[RELEASING.md](RELEASING.md) for how to cut a new version for F-Droid.
## Getting it onto your phone ## Getting it onto your phone
Chrome will only offer a real install over HTTPS, so the file needs a host. Chrome will only offer a real install over HTTPS, so the file needs a host.
+116
View File
@@ -0,0 +1,116 @@
# Releasing a new version
The clock lives in two places: the web app in `public_html/`, which you host
yourself, and the Android app on F-Droid, which is built from a git tag.
**Everything F-Droid needs comes from a tag in this repository.** After the first
release was accepted there is nothing to do in F-Droid's own repo — their bot
watches the tags here and writes the build entry itself. Don't open a merge
request against `fdroiddata` for a new version.
Worked example below bumps 1.0 to 1.1. Substitute your own numbers.
## 1. Make the change
Both versions share one copy of the app. Edit `public_html/index.html` and the
Android build picks it up automatically — the Gradle build reads `public_html/`
directly rather than keeping a second copy, so the two can't drift.
If you changed anything visible, bump the service worker cache or installed web
users will keep the old page:
```
# public_html/sw.js
const CACHE = "bgclock-v18"; # any new value; it only has to differ
```
## 2. Bump the version
In `android/app/build.gradle.kts`:
```kotlin
versionCode = 2 // an integer, +1 every release, never reused
versionName = "1.1" // what people see
```
`versionCode` is what Android uses to decide one version is newer than another.
It must go up every single release, even for a one-character fix.
## 3. Write the changelog
A new file named after the **versionCode**, not the version name:
```
fastlane/metadata/android/en-US/changelogs/2.txt
```
Maximum 500 characters. This is what shows up in F-Droid's "What's New".
## 4. Build it and put it on your phone
```bash
export ANDROID_HOME="$HOME/Android/Sdk" # already in ~/.bashrc
cd android
./gradlew assembleDebug
adb install -r app/build/outputs/apk/debug/app-debug.apk
./gradlew --stop # the daemon holds ~500 MB otherwise
```
Play a real game before tagging. Worth checking specifically: start a match,
make some moves, force-quit from the task switcher and reopen — everything
should come back, paused. That is the check that proves the app's storage is
working, and it fails silently rather than loudly.
## 5. Commit, tag, push
```bash
git add -A
git commit -m "…"
git tag -a v1.1 -m "Backgammon Clock 1.1"
git push
git push origin v1.1
```
**The tag must keep the `v` prefix.** F-Droid's `checkupdates` takes the tag name
verbatim as the commit to build, so `v1.1` here means `commit: v1.1` in their
metadata. A tag named `1.1` would break the automation.
Never move or delete a tag that has been pushed — F-Droid may already have built
it. If a release is wrong, bump the version and release again.
## 6. Wait
Their bot notices the new tag, adds a build entry, and the build server picks it
up on its next cycle. Expect a day or two. Nothing to do.
## Deploying the web version
Separate from all of the above, and manual: upload the six files in
`public_html/``index.html`, `manifest.webmanifest`, `sw.js`, `icon-192.png`,
`icon-512.png`, `icon-maskable-512.png` — to the web host. `README.md` and
`RELEASING.md` stay out of it; they live in the repo root for that reason.
## If the screenshots need redoing
`fastlane/metadata/android/en-US/images/phoneScreenshots/` holds five shots at
1170×2532. They are generated from `public_html/index.html` itself with headless
Chromium, not taken on a phone, so they can be regenerated exactly. Two traps if
you do it by hand:
- The capture lands whenever the virtual-time budget runs out, not when your
script finishes — so freeze the render loop (`requestAnimationFrame = () => 0`)
once the frame you want is on screen.
- CSS transitions don't advance under `--virtual-time-budget`, so a panel caught
mid-transition photographs in its *old* colour. Disable transitions in the
screenshot build.
## Reference
- App ID: `nl.hansdezwart.bgclock` — fixed forever; changing it makes a new app.
- F-Droid listing text: `fastlane/metadata/android/en-US/` (title ≤50 chars,
summary ≤80, description ≤4000, changelog ≤500). Only these HTML tags work in
the description: `b big blockquote br cite em i li ol small strike strong sub
sup tt u ul`.
- The original submission: https://gitlab.com/fdroid/fdroiddata/-/merge_requests/45478
- F-Droid signs the APK with their key, not yours. Reproducible builds were
declined at submission and can't be enabled later for this app ID.