Skip to content

version: retain prerelease suffix in Semver comparisons - #35

Merged
TeoSlayer merged 1 commit into
mainfrom
sec/findings-updater
Jul 26, 2026
Merged

TeoSlayer merged 1 commit into
mainfrom
sec/findings-updater

Conversation

@TeoSlayer

Copy link
Copy Markdown
Contributor

M25 — Updater version pinning ignores prerelease suffix

ParseSemver (version.go:23) discarded everything after the first hyphen, so v1.2.3-rc1 and v1.2.3 parsed to the identical Semver{1,2,3}. Two call sites depended on that value:

  • updater.go:231latest.NewerThan(current): with v1.2.3-rc1 installed, the real v1.2.3 release compared equal and was never installed.
  • updater.go:265current == pinned in checkPinnedVersion: an exact pin to v1.2.3 was satisfied by an installed v1.2.3-rc1, and vice versa.

.pilot-version already stores the raw tag (release.TagName), so the suffix was present on disk and only lost at parse time.

Change

  • Semver gains a Pre field holding the prerelease identifiers after the first hyphen.
  • +build metadata is stripped before parsing (it takes no part in precedence), so v1.2.3+build.7 still equals v1.2.3.
  • New Compare implements semver precedence: numeric triple first, then the prerelease suffix, with a suffixed version sorting below the plain release. Identifiers are split on .; all-digit identifiers compare numerically and sort before alphanumeric ones.
  • NewerThan delegates to Compare; String round-trips the suffix.

No wire or on-disk format change — the version file contents and the GitHub API shapes are untouched. Semver grows a field, so the in-repo positional composite literals in the tests were updated.

Tests

Table tests extended in zz_test.go / zz_more_test.go:

  • TestParseSemver-dirty, -rc1, -beta.2, +build.7, -rc.1+build.7.
  • TestSemverNewerThan — 13 new pairs covering 1.2.3-rc1 < 1.2.3, rc1 < rc2, beta.9 < rc.1, rc.1 < rc.1.1, numeric-before-alphanumeric, and build-metadata equality.
  • TestSemverPinEquality (new) — asserts an exact pin only matches the same suffix, mirroring the checkPinnedVersion equality check.

go build ./..., go vet ./... and go test ./... all green.

Base branch note

The task named fix/gh-free-attestation as the base. That branch exists only locally — its commit is already squash-merged into main as 5588eb0 — so this PR is rebased onto and targets main to avoid re-proposing merged work.

🤖 Generated with Claude Code

ParseSemver discarded everything after the first hyphen, so v1.2.3-rc1
and v1.2.3 parsed to the same value. Both the latest-release comparison
and the exact-pin equality check in checkPinnedVersion therefore treated
a prerelease and its matching release as interchangeable.

Semver now carries the prerelease identifiers in a Pre field, build
metadata is stripped before parsing, and Compare implements semantic
version precedence: the numeric triple first, then the prerelease
suffix, with a suffixed version sorting below the plain release.
NewerThan delegates to Compare and String round-trips the suffix.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@codecov

codecov Bot commented Jul 26, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@TeoSlayer
TeoSlayer merged commit 5236479 into main Jul 26, 2026
10 checks passed
@TeoSlayer
TeoSlayer deleted the sec/findings-updater branch July 26, 2026 14:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants