-
v2026.09.10.1449
Stabletest-go / test (push) Successful in 59stest-go / integration (push) Successful in 3m1srelease / Build signed APK (releases and dev) (push) Successful in 4m41srelease / Build + push container image (push) Successful in 14srelease / Verify release artifacts (tag releases only) (push) Successful in 2sreleased this
2026-09-10 10:55:19 -04:00 | 0 commits to main since this releaseThe versioning rework, and the first release under the new tag shape.
Versions are three values now, not one
A build reports a name, an ordering key, and a channel, and they answer different questions:
name—YYYY.MM.DD.HHMM, derived from the commit's timestamp. A label for people. Every lane that builds a given commit reports the same name.code— minutes since 2020-01-01 at build time. This is the value Android itself installs by, so it is the value the update check decides on. Monotonic by construction; a commit count was not.channel— a sibling field, never a suffix inside the name.
The Android client now decides whether an update is available on the ordering key rather than the displayed name, so an offer it makes is one the platform will actually accept. When a server predates the field, it falls back to comparing names — the behaviour those builds already had.
The derivation moved out of workflow YAML into
ci/version.sh, which means it is executable and guarded on every push that touches release machinery. It previously could not be tested until a release was already under way, and its failure mode is silence: an update nobody is offered looks exactly like being up to date.A dev channel
:devis rebuilt on every push todevand carries its own freshly-built, identically-signed APK. Testing no longer requires cutting a release. It rolls constantly, has no per-commit tag to pin, and its only recovery path is forward.Tag shape
Release tags are now
vYYYY.MM.DD.HHMM— the build's own version name with avin front, derived from the tagged commit. Two releases can never collide and a re-cut is simply a new tag. Tags are never moved or deleted.Releases before today use the older per-day
vYYYY.MM.DDshape. Those tags still exist and still work; they are simply not extended.Fixes
- Miniplayer content sat at the top of its bar instead of filling it, leaving a gap at the bottom.
- Rebundle step died at a variable assignment when its
grepmatched nothing. The runner invokesshell: bashwith-o pipefail, so a command substitution whose grep finds nothing is fatal at the assignment — before reaching theifwritten to handle the empty case. Every "degrades gracefully" branch in that step was unreachable. Caught by the firstmainbuild after the rework, when the newest release predated sidecar assets. - versionCode ceiling — a build clock set far in the future would emit a key above
int32, which the platform refuses and which would permanently outrank every real build that followed. Refused at the source instead.
Upgrading
Nothing to do.
:latestand:vYYYY.MM.DD.HHMMboth bundle a signed APK, so the in-app update channel stays live. Stable and dev builds share a signing key, so a phone can move between channels without uninstalling.🤖 Generated with Claude Code
Downloads