Split out of the 4.0.0rc1 release prep (#474) — an RC release PR was the wrong vehicle for a tag-scheme migration across four workflows, so the analysis is parked here.
The problem
All 20 tags to date are unprefixed and use a non-semver RC form: 3.0.0, 3.0.0rc1, 3.0.1rc1. X.Y.ZrcN is not valid semver — that would be X.Y.Z-rcN. This already caused a real bug, documented in release.yml:
rc tags use the form X.Y.ZrcN, which is not valid semver (that would be X.Y.Z-rcN). version-increment cannot parse it, silently falls back to the last parseable tag, and proposes a version that goes backwards — after 3.0.0rc1 it proposed 2.5.2.
The workaround was to skip bump_version for prereleases entirely. That is a patch over the tag scheme, not a fix.
What has to change together
A v-prefixed semver tag (v4.1.0, v4.1.0-rc.1) currently triggers nothing — it matches no tag filter anywhere. Four places have to move in one change:
- .github/workflows/release.yml — tag filters are [0-9]+.[0-9]+.[0-9]+ and [0-9]+.[0-9]+.[0-9]+rc[0-9]+; neither matches a v prefix or a -rc.N suffix. The Generate Metadata step then needs VERSION="${TAG#v}" so --version prints 4.1.0-rc.1 and not v4.1.0-rc.1 — note the Verify the built binary reports the tagged version step compares against this, and archive_name is derived from it, so the strip has to happen once, upstream of both. The notes lookup (BASE="${VERSION%%rc*}") also needs the -rc.N form: BASE="${BASE%%-rc*}".
- .github/workflows/pages-release.yml — stable-only filter [0-9]+.[0-9]+.[0-9]+, same prefix problem. Also decide whether the store path becomes /v/v4.1.0/ or stays /v/4.1.0/; the latter means stripping the prefix before the store write.
- scripts/assemble_site.py — VERSION = re.compile(r"[0-9]+\.[0-9]+\.[0-9]+") is fullmatched against every entry in versions.json and hard-fails the Pages deploy on a mismatch. A v4.1.0 entry fails this gate.
- .github/workflows/homebrew-bump.yml — validates ^[0-9]+\.[0-9]+\.[0-9]+(rc[0-9]+)?$ and errors out otherwise. Manual-dispatch only, so it breaks quietly rather than at release time.
Why now is a good moment
pages-site's versions.json is currently [] — no /v/<tag>/ URLs are published yet, so the store path decision in (2) has no back-compat cost today. That stops being true after the first stable 4.x release.
Suggested approach
Keep the existing patterns alongside the new ones so historic tags still resolve, normalise to a bare X.Y.Z[-rcN] version immediately after reading the ref, and let everything downstream consume the normalised value. Then re-enable bump_version for prereleases, since version-increment can parse proper semver.
Split out of the 4.0.0rc1 release prep (#474) — an RC release PR was the wrong vehicle for a tag-scheme migration across four workflows, so the analysis is parked here.
The problem
All 20 tags to date are unprefixed and use a non-semver RC form: 3.0.0, 3.0.0rc1, 3.0.1rc1. X.Y.ZrcN is not valid semver — that would be X.Y.Z-rcN. This already caused a real bug, documented in release.yml:
The workaround was to skip bump_version for prereleases entirely. That is a patch over the tag scheme, not a fix.
What has to change together
A v-prefixed semver tag (v4.1.0, v4.1.0-rc.1) currently triggers nothing — it matches no tag filter anywhere. Four places have to move in one change:
Why now is a good moment
pages-site's versions.json is currently [] — no /v/<tag>/ URLs are published yet, so the store path decision in (2) has no back-compat cost today. That stops being true after the first stable 4.x release.
Suggested approach
Keep the existing patterns alongside the new ones so historic tags still resolve, normalise to a bare X.Y.Z[-rcN] version immediately after reading the ref, and let everything downstream consume the normalised value. Then re-enable bump_version for prereleases, since version-increment can parse proper semver.