# 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 ``` Keep tags in the `v1.1` shape for consistency, but nothing depends on it: `UpdateCheckMode: Tags` with no pattern matches every tag whatever it's called, and F-Droid's bot resolves whichever tag it finds to a commit hash before it writes the build entry. 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. (The recipe pins a hash, so a moved tag can't retroactively change a version they already built; it would just leave your repo disagreeing with what's on people's phones.) **If you ever write a build entry by hand**, its `commit:` must be a full 40-char commit hash — never a tag, never a branch. Tags are mutable, so a tag there means the thing F-Droid builds and signs can change under them, and they reject it on sight. This came up on the very first submission and is easy to get wrong, because `fdroid lint` doesn't check it under `UpdateCheckMode: Tags` — the pipeline goes green and a human catches it days later. Get the hash with: ```bash git rev-parse v1.1^{commit} # ^{commit}, or an annotated tag gives you the # tag object's hash instead of the commit's ``` This doesn't come up in a normal release: the bot writes the entry, and the bot writes hashes. ## 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 ```bash python3 tools/screenshots.py ``` That rewrites all five in `fastlane/metadata/android/en-US/images/phoneScreenshots/` at 1170×2532. They are rendered from `public_html/index.html` with headless Chromium, not taken on a phone, so they reproduce exactly — anything that changes the look of the app is a reason to re-run it. The script sets each scene by seeding `localStorage` before the app boots, so the app renders its own saved state rather than having the DOM poked from outside. Editing a scene means editing the `SCENES` table at the top. Three traps, all of which fail quietly, and all of which the script already handles — they are written down here because they cost an afternoon each: - 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. - Snap-confined Chromium cannot write into hidden directories — not `~/.cache`, not any dot-directory, not the private `/tmp` it is handed. It fails with a bare "Permission denied" and no hint as to why. Both the HTML it reads and the PNG it writes have to sit in a plainly-named directory. ## 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.