release: rc notes resolve to the base version; publish without jq
CI / shell (shellcheck + syntax) (push) Successful in 14s
CI / python 3.11 (push) Successful in 17s
CI / python 3.12 (push) Successful in 20s
CI / python 3.13 (push) Successful in 21s
TrueNAS compatibility / compat (push) Successful in 10s
Release / release (push) Successful in 14s

release_notes.py 'notes v0.6.0-rc1' looked for a CHANGELOG section literally named
v0.6.0-rc1. check() already used base_version(); extract_notes() did not. So the
release workflow cut the tag, passed every gate, and then died extracting the body --
the candidate existed but was never published.

Caught in an rc, which is the entire point of having them.

Also: the Gitea publish and issue steps used jq, which is not guaranteed on a
self-hosted runner. A publish step that dies on a missing tool leaves a tag with no
release behind it, and a bug report that dies on one is a warning system that does
not warn. Both now use python3, which setup-python guarantees.
This commit is contained in:
2026-07-13 18:38:02 +00:00
parent c250bc8f5d
commit 8c1b4c45f5
4 changed files with 105 additions and 42 deletions
+28
View File
@@ -205,3 +205,31 @@ class TestSignificance:
assert version_tuple("0.4.2") > version_tuple("0.4.1")
# Pre-release suffixes are dropped, not ranked above the release.
assert version_tuple("v0.5.0-rc1") == version_tuple("v0.5.0")
class TestCandidateNotesResolveToTheBaseVersion:
"""`notes v0.6.0-rc1` must return v0.6.0's section.
A candidate ships the same code as the release it is a candidate for, and the
CHANGELOG only ever has the one section. Without this, the release workflow cut
v0.6.0-rc1, passed every gate, and then died extracting the body -- so the tag
existed but nothing was ever published. Caught in an rc, which is the entire
point of having them.
"""
CHANGELOG = "# C\n\n## v0.6.0 — 2026-07-13\n\n### Added\n- the thing\n\n## v0.5.1 — 2026-07-13\n\n- older\n"
def test_an_rc_resolves_to_its_base_version(self):
body = extract_notes(self.CHANGELOG, "v0.6.0-rc1")
assert "the thing" in body
assert "older" not in body
def test_rc10_too(self):
assert "the thing" in extract_notes(self.CHANGELOG, "v0.6.0-rc10")
def test_the_plain_version_still_works(self):
assert "the thing" in extract_notes(self.CHANGELOG, "v0.6.0")
def test_a_genuinely_missing_section_still_raises(self):
with pytest.raises(KeyError):
extract_notes(self.CHANGELOG, "v9.9.9-rc1")