test-go / test (push) Successful in 1m43s
test-web / test (push) Successful in 1m13s
test-go / integration (push) Successful in 4m12s
release / Build signed APK (releases and dev) (push) Successful in 5m11s
release / Build + push container image (push) Successful in 38s
release / Verify release artifacts (tag releases only) (push) Skipped
The image tag map was the inverse of family rules 145 and 147 on every count: it published :vYYYY.MM.DD.HHMM that nobody pinned, published :main that rule 147 says should not exist, and published no commit-addressable image at all — so the rollback unit the rule names did not exist in this repo. A bad main push had nothing to roll back to but the previous release tag, which may be many commits back. The whole map is now: dev → :dev main → :latest + :<sha> tag → :latest A release refreshes the channel and mints nothing else. The tag build rebuilds the SAME SOURCE as main's build minutes earlier, differing only in which APK is baked in, so rule 145's immutability clause applies directly: move the channel tag, never re-push a commit-addressable one. :latest has to move here rather than waiting for the next main push, or the channel would carry the previous release's APK indefinitely — a channel that cannot refresh itself (rule 146). Two consequences that are not optional: The verify job asserted the :<version> image existed. With version tags gone that would fail every release for a tag nothing mints. Re-pointed at the :<sha> image rather than deleted — deleting it is the tempting way to make a failing guard go green, and it earns its keep twice now: it still catches an image push that silently did not happen, and it additionally proves the ordering, since a tag cut on a commit whose main build never completed has no rollback target. The server's self-reported version was the literal string "main" or "dev". That was survivable while :vYYYY.MM.DD.HHMM existed to identify a build; with version tags gone it is the ONLY thing that says which build is running, and two dev images months apart were indistinguishable. It now carries the derived name from ci/version.sh on every lane, with the channel as a sibling field (rule 149) rather than folded into the string. Surfaced at /healthz and beside the version in Settings. Guards added for each arm of the policy, and every one was falsified against the specific regression it names before committing. That caught two real bugs in the guards themselves: stepBody cut at the next `- name:`, which returns an EMPTY body for the last step in a job and made the assertions pass vacuously, and its replacement cut at any blank line followed by indentation, which truncated a step mid-run-block. The helper now refuses an empty body outright. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SQ31KQpYbStyK5y58UmPLH
32 lines
1.5 KiB
Go
32 lines
1.5 KiB
Go
package server
|
|
|
|
// MinClientVersion is the lowest mobile-client semver that this server
|
|
// accepts. Bump it when a server change requires a paired client update;
|
|
// older clients see version_too_old at /healthz and refuse to operate.
|
|
const MinClientVersion = "0.1.0"
|
|
|
|
// ServerVersion is the build's own version name — YYYY.MM.DD.HHMM, derived
|
|
// from the commit it was built from by ci/version.sh. Defaults to "dev" for
|
|
// local builds; overridden at link time via:
|
|
//
|
|
// -ldflags="-X 'git.fabledsword.com/bvandeusen/minstrel/internal/server.ServerVersion=2026.09.10.1449'"
|
|
//
|
|
// release.yml passes it through the MINSTREL_VERSION build-arg → Dockerfile
|
|
// ldflag. Surfaced at /healthz so operators can verify which image their
|
|
// container is running without exec'ing into it.
|
|
//
|
|
// This carried the literal strings "main" and "dev" until 2026-09-10, which
|
|
// made every image on a channel report the same thing forever. It stopped
|
|
// being cosmetic when :vYYYY.MM.DD.HHMM image tags were retired (family rule
|
|
// 145): this is now the ONLY thing that says which build is running.
|
|
var ServerVersion = "dev"
|
|
|
|
// ServerChannel is which line this build came off — "stable" or "dev", or
|
|
// "local" for a plain `docker build`.
|
|
//
|
|
// A SIBLING FIELD, never a suffix inside ServerVersion (family rule 149). The
|
|
// same commit built on both lanes reports the same version and differs only
|
|
// here; folding the two together is what makes a version string stop being
|
|
// comparable.
|
|
var ServerChannel = "local"
|