From 646d514a65a7ecc9a3b161da5dd119dfa0c9f57a Mon Sep 17 00:00:00 2001 From: Minseong Choi Date: Mon, 20 Jul 2026 19:05:19 +0900 Subject: [PATCH] test(updates): pin the ordering of a dev build's own version stamp 659c8e5 chose "+g" over "-g" for the dev channel's stamp on the grounds that "+" is SemVer build metadata, ignored for precedence, so a build some commits past v1.2.3 still reads as v1.2.3 rather than as something older. That claim is load-bearing and was asserted only in prose: if metadata ever counted for ordering, every dev install would report an upgrade available onto a release it already contains. Parse does handle it -- build metadata is stripped before the prerelease tail, so the "-earlyAccess+g" order a real build stamps splits correctly too -- but nothing tested it. The existing coverage compares "+k3s1" against "+k3s2", which is metadata on BOTH sides; the case that matters here is metadata on one side only, against the bare tag. Four pairs in the compare table, plus "v0.0.0+g" in the parse table for a build pinned to a ref with no tag behind it. Verified by mutation: disabling the "+" split in Parse fails these cases specifically. They sit at the end of the table rather than beside the other build-metadata pairs. The entries are wide and carry no trailing comment, and inserting them mid-table splits the contiguous comment block, which makes gofmt rewrite the alignment of seven untouched lines. --- internal/updates/version_test.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/internal/updates/version_test.go b/internal/updates/version_test.go index 69b83e6..47b1584 100644 --- a/internal/updates/version_test.go +++ b/internal/updates/version_test.go @@ -17,6 +17,7 @@ func TestParseTolerant(t *testing.T) { {"1.2.3-rc.1", 1, 2, 3, "rc.1"}, // prerelease {"v3.3.0-SNAPSHOT", 3, 3, 0, "SNAPSHOT"}, // velocity-style {"1.2.3-rc.1+build.9", 1, 2, 3, "rc.1"}, // prerelease AND build + {"v0.0.0+g1a2b3c4", 0, 0, 0, ""}, // stamp of a build pinned to a ref with no tag behind it {"v2", 2, 0, 0, ""}, // missing minor/patch fill 0 {"2.0", 2, 0, 0, ""}, // missing patch fills 0 {" v1.2.3 ", 1, 2, 3, ""}, // surrounding whitespace @@ -64,6 +65,18 @@ func TestCompareAndAfter(t *testing.T) { {"1.2.3-alpha", "1.2.3-beta", -1}, // alphanumeric lexical {"1.2.3-rc.1", "1.2.3-rc.1.1", -1}, // longer identifier set is higher {"1.2.3-1", "1.2.3-alpha", -1}, // numeric identifier sorts below alphanumeric + + // A dev build's own stamp, "+g", against the tag it is built past. + // It must read EQUAL, never newer: deploy/bootstrap.sh's dev channel stamps the + // binary this way, so if metadata counted for ordering every dev install would + // report an upgrade onto a release it already contains. The "+" spelling exists + // precisely to buy this, and the mixed case -- metadata on one side only -- is + // the one the k3s pair above does not exercise. The last pair carries the + // metadata after a prerelease tail, the order a real earlyAccess build stamps. + {"v1.2.3+g1a2b3c4", "v1.2.3", 0}, + {"v1.2.3", "v1.2.3+g1a2b3c4", 0}, + {"v1.2.3+g1a2b3c4", "v1.2.4", -1}, + {"v1.0.0-earlyAccess+g1a2b3c4", "v1.0.0-earlyAccess", 0}, } for _, c := range cases { va, err := Parse(c.a)