From a687ef439c5252919f967fda80db9d3dd513ac42 Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Wed, 9 Sep 2026 22:17:07 -0400 Subject: [PATCH] fix(release): refuse an ordering key that overflows versionCode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The script asserted the key was positive but never that it fits. Android's versionCode is a signed 32-bit int and the platform rejects an APK above it, so a build machine with a badly wrong clock would emit a code the script happily hands on and the install then refuses. Worse than a rejected build: an over-ceiling code is also unreachably high, so every correct build afterwards would fail to outrank it and the update channel would be permanently stuck. Cheaper to refuse at the source than to diagnose it from a phone that will not update. The Go guard already asserted this, but only against a pinned value. The script is what actually runs at build time, so the check belongs here too. Falsified at the boundary rather than by eye — exactly at the ceiling exits 0, one minute past exits 1. My first probe used a year-6000 clock and did NOT fire, which turned out to be the probe being wrong rather than the check: that epoch still lands under the ceiling. The ceiling is reached in 6103, roughly 4079 years out, so this only ever catches a misconfigured clock. This commit deliberately touches ci/version.sh alone, to verify the path filters added in eaf4654c actually fire the Go lane for release-machinery changes. That run proved nothing about them, because it also touched internal/** and would have run regardless. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01SQ31KQpYbStyK5y58UmPLH --- ci/version.sh | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/ci/version.sh b/ci/version.sh index 36583f45..72d115df 100755 --- a/ci/version.sh +++ b/ci/version.sh @@ -65,6 +65,19 @@ if [ "${code}" -le 0 ]; then exit 1 fi +# Android's versionCode is a signed 32-bit int and the platform refuses an APK +# whose code exceeds it. At ~525k minutes a year this is four thousand years +# away in normal operation, so the realistic cause is a build machine with a +# badly wrong clock — which produces a code that is not merely too large but +# also unreachably high, permanently blocking every real build that follows +# from ever outranking it. Cheaper to refuse the build than to discover that +# from a phone that will not update. +readonly VERSION_CODE_CEILING=2147483647 +if [ "${code}" -gt "${VERSION_CODE_CEILING}" ]; then + echo "version.sh: ordering key '${code}' exceeds versionCode's int32 ceiling — build clock wrong?" >&2 + exit 1 +fi + # KEY=VALUE, which is also exactly $GITHUB_OUTPUT's format. echo "name=${name}" echo "code=${code}"