fix: the release suite accepts the ceremony's own tree (#108)
release.test.ts demanded the real changelog's literal Unreleased section extract non-empty containing '#96' — false by construction on the very tree the release PR produces, so the first real 'release: 0.1.0' PR turned CI red and the ceremony blocked itself. Fork rehearsals missed it: a tag push runs release.yml, never ci.yml. The guard now asserts the TOP section, whatever its name, extracts non-empty via the exact tool release.yml runs — verified on both legitimate tree states. Fixes #108 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
ffaa850723
commit
f9187272ec
2 changed files with 29 additions and 5 deletions
12
CHANGELOG.md
12
CHANGELOG.md
|
|
@ -9,6 +9,18 @@ actually cutting it, and this file starts there.
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
|
- **The release suite accepts the ceremony's own tree** (#108) —
|
||||||
|
`test/release.test.ts` demanded the real `CHANGELOG.md`'s literal
|
||||||
|
`Unreleased` section extract non-empty and contain `#96`: false by
|
||||||
|
construction on the `release: X.Y.Z` tree the ceremony's own PR produces
|
||||||
|
(it stamps that heading into `## X.Y.Z — date`), so the first real
|
||||||
|
release PR turned CI red and the flow blocked itself — invisible to the
|
||||||
|
fork rehearsals, which tag a branch (`release.yml` runs; `ci.yml` never
|
||||||
|
does). The guard now asserts its actual purpose: whatever the TOP `## `
|
||||||
|
section is — `Unreleased` between releases, the stamped version on and
|
||||||
|
right after one — the exact `release-notes.sh` the workflow runs
|
||||||
|
extracts it non-empty. rig's twin is heavy-duty/rig#44.
|
||||||
|
|
||||||
- **`apply` no longer demands a GitHub App for a manifest that declares no
|
- **`apply` no longer demands a GitHub App for a manifest that declares no
|
||||||
applications** (#103) — found live in the 2026-07-19 release drill, where a
|
applications** (#103) — found live in the 2026-07-19 release drill, where a
|
||||||
databases-only manifest (`applications: {}`) rendered its plan of two
|
databases-only manifest (`applications: {}`) rendered its plan of two
|
||||||
|
|
|
||||||
|
|
@ -143,12 +143,24 @@ describe("release-notes.sh", () => {
|
||||||
expect(r.output).toContain("no such file");
|
expect(r.output).toContain("no such file");
|
||||||
});
|
});
|
||||||
|
|
||||||
// The REAL changelog: its Unreleased section must extract non-empty with
|
// The REAL changelog: the guard against header-format drift. The file has
|
||||||
// the exact tool release.yml runs — the guard against header-format drift.
|
// two legitimate states, and this test used to know only one (#108, found
|
||||||
it("the real CHANGELOG.md's Unreleased section extracts", async () => {
|
// the day the first release PR turned CI red): BETWEEN releases the top
|
||||||
const r = await notes("Unreleased", join(ROOT, "CHANGELOG.md"));
|
// section is `## Unreleased`; on a `release: X.Y.Z` tree — the ceremony's
|
||||||
|
// own PR stamps that heading into `## X.Y.Z — date` — and on main right
|
||||||
|
// after it, the top section IS the stamped release. Demanding the literal
|
||||||
|
// Unreleased (with an issue number inside it, rotting per release) made
|
||||||
|
// the release PR unshippable by construction, invisible to fork
|
||||||
|
// rehearsals (a tag push runs release.yml, never ci.yml). Whatever the
|
||||||
|
// top section is called, the exact tool release.yml runs must extract it
|
||||||
|
// non-empty.
|
||||||
|
it("the real CHANGELOG.md's top section extracts", async () => {
|
||||||
|
const changelog = readFileSync(join(ROOT, "CHANGELOG.md"), "utf8");
|
||||||
|
const top = changelog.match(/^## (\S+)/m);
|
||||||
|
expect(top).not.toBeNull();
|
||||||
|
const r = await notes(top![1], join(ROOT, "CHANGELOG.md"));
|
||||||
expect(r.code).toBe(0);
|
expect(r.code).toBe(0);
|
||||||
expect(r.output).toContain("#96");
|
expect(r.output.trim()).not.toBe("");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue