mirror of
https://tangled.org/evan.jarrett.net/at-container-registry
synced 2026-09-03 08:46:57 +00:00
isNewerVersion split versions on "." and ran each component through
strconv.Atoi, discarding the error and substituting 0. For a git-describe
build the last component is "4-18-g8f70cce", which does not parse, so it
became 0 and every published release compared as newer. Running
v0.1.4-18-g8f70cce printed "Update available: v0.1.4" on every single
invocation, naming a version the binary was already 18 commits past.
Versions are now parsed properly: the "-<commits>-g<sha>" tail is recognised
and kept as a count of commits past the tag, and a version that cannot be
read in full returns false rather than being silently treated as 0. That
second part is the actual root cause — the comparison could not distinguish
"this component is zero" from "I could not read this component".
Ordering for a git-describe build is deliberately not semver, where a
prerelease sorts below its release. Such a build is commits AHEAD of its tag,
so v0.1.4-18-g8f70cce is newer than v0.1.4 and older than v0.1.4-20-gabc1234.
The function had no tests. Both failing cases are pinned along with the
ordinary release comparisons, so the git-describe handling cannot regress the
normal upgrade path.
Pre-existing at efabb677 rather than introduced by this range.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
51 lines
1.9 KiB
Go
51 lines
1.9 KiB
Go
package credhelper
|
|
|
|
import "testing"
|
|
|
|
// isNewerVersion had no tests, and a git-describe build ("v0.1.4-18-g8f70cce")
|
|
// nagged about an update on every single invocation. The cause was a silent
|
|
// default: strconv.Atoi("4-18-g8f70cce") fails, the failure was swallowed, the
|
|
// component became 0, and so every published release compared as newer than any
|
|
// dev build of the same tag.
|
|
func TestIsNewerVersion(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
latest string
|
|
current string
|
|
want bool
|
|
}{
|
|
// The reported case: a dev build 18 commits past v0.1.4 is AHEAD of
|
|
// v0.1.4, so there is nothing to update to.
|
|
{"git describe build is ahead of its own tag", "v0.1.4", "v0.1.4-18-g8f70cce", false},
|
|
{"git describe build vs a real later release", "v0.2.0", "v0.1.4-18-g8f70cce", true},
|
|
{"git describe build vs a later patch", "v0.1.5", "v0.1.4-18-g8f70cce", true},
|
|
{"further ahead of the same tag", "v0.1.4-2-gabc1234", "v0.1.4-18-g8f70cce", false},
|
|
{"behind another describe build", "v0.1.4-20-gabc1234", "v0.1.4-18-g8f70cce", true},
|
|
|
|
// Plain releases.
|
|
{"newer patch", "v0.1.5", "v0.1.4", true},
|
|
{"newer minor", "v0.2.0", "v0.1.9", true},
|
|
{"newer major", "v1.0.0", "v0.9.9", true},
|
|
{"same version", "v0.1.4", "v0.1.4", false},
|
|
{"older patch", "v0.1.3", "v0.1.4", false},
|
|
{"older major", "v0.9.9", "v1.0.0", false},
|
|
{"missing v prefix still compares", "0.1.5", "0.1.4", true},
|
|
|
|
// An untagged build always updates.
|
|
{"dev always updates", "v0.1.4", "dev", true},
|
|
|
|
// Nothing parseable means no nagging.
|
|
{"garbage latest does not nag", "not-a-version", "v0.1.4", false},
|
|
{"empty latest does not nag", "", "v0.1.4", false},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if got := isNewerVersion(tt.latest, tt.current); got != tt.want {
|
|
t.Errorf("isNewerVersion(%q, %q) = %v, want %v",
|
|
tt.latest, tt.current, got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|