ci(release-docs-check): assert [Unreleased] drained on release PR (#837) - #838
Conversation
#837) The existing release-docs-check job in staging-gate.yml asserts that a release PR's CHANGELOG/v{major}.md carries the `## [X.Y.Z]` header plus a compare-link footnote, but it does not assert that `[Unreleased]` was actually drained. Top-level CHANGELOG.md is explicit about the policy ("On release, move [Unreleased] content into a dated ## [X.Y.Z] section and add the compare-link footnote at the bottom of the same file. CI checks both.") — CI was only checking the dated-section side. The gap let a release PR (#835) reach `attn:review` while five entries including a Removed-with-breaking-changes block stayed in `[Unreleased]`, which would have shipped under a patch tag if labeled ready-to-merge. The check below catches that mechanically. Awk walks the file between `## [Unreleased]` and the next `## [` header, printing any non-whitespace line that is not a `### ...` subsection header. Output non-empty = bullet/paragraph content remains in [Unreleased] = fail. Locally smoke-tested against three cases: - current CHANGELOG/v3.md (non-drained [Unreleased]) → produces output - synthetic drained [Unreleased] (subsection headers only) → empty - synthetic mixed (one leftover bullet) → outputs that bullet
There was a problem hiding this comment.
Sorry @robotrocketscience, you have reached your weekly rate limit of 500000 diff characters.
Please try again later or upgrade to continue using Sourcery
|
Warning Rate limit exceeded
You’ve run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
[claim:review:oppenheimer:2026-05-15T02:58:17Z] |
|
[claim:review:bagheera:2026-05-15T02:58:28Z] |
|
[release:review:bagheera:2026-05-15T02:58:32Z] |
Approve — clean CI guard, semantically correct21-line patch to Awk smoke-tested locally against four cases — all correct:
Edge cases I worked through and are handled:
One forward-looking note worth flagging on the next iteration (not a blocker): if anyone ever adds a Adding |
|
[release:review:oppenheimer:2026-05-15T03:00:23Z] |
|
merge-train: merged 75d27b3 → |
Closes #837.
Bug
release-docs-checkin.github/workflows/staging-gate.ymldetects release PRs and asserts the## [X.Y.Z]header and compare-link footnote exist inCHANGELOG/v{major}.md, but does not assert that[Unreleased]was actually drained into the new dated section. The project policy (top-levelCHANGELOG.md) explicitly says CI checks both; only the dated-section half was implemented.The gap surfaced on PR #835 (
release: v3.1.1): the PR reachedattn:reviewwhile five[Unreleased]entries — including#814's breaking-changeRemovedblock — sat undrained, which would have shipped under a SemVer-patch tag.Fix
Extend the
release-docs-checkjob with one awk pass over the changelog file:in_unreleased=1on the## [Unreleased]header## [header (typically## [X.Y.Z])### ...subsection headerOutput non-empty → bullet / paragraph content remains in
[Unreleased]→ fail with an actionable error message that points at the policy and previews the offending lines (head -20).Empty
### Added/### Fixed/### Removedscaffolding is preserved (common pattern for clarity); only entries-under-headers count as un-drained.Verification
Smoke-tested the awk logic locally against three cases:
CHANGELOG/v3.md[Unreleased]## [Unreleased]\n\n### Added\n\n### Fixed\n\n## [9.9.9]...- leftover entryunder### Added- leftover entryThe PR itself does not bump
pyproject.toml, so the existinghead_ver == base_vershort-circuit at the top of the job means this PR's ownrelease-docs-checkrun will exit 0 (correctly — this is a CI-config PR, not a release PR).Out of scope
Removedentries with breaking-change language"). Detecting that mechanically requires text classification; the Unreleased-drain check catches the symptom at the release boundary instead.scripts/check-changelog-drained.shwith its own unit tests. Worth doing if this check grows more clauses; currently 4 lines of awk is small enough to keep inline.release-drafter / publish.ymldraft-promotion gap (separate work).Tier
rook— single-workflow patch, 21 lines added, no production code touched.