Skip to content

fix(release): refuse a release without notes - #343

Merged
eddietejeda merged 2 commits into
mainfrom
fix/require-release-notes
Oct 15, 2026
Merged

eddietejeda merged 2 commits into
mainfrom
fix/require-release-notes

Conversation

@eddietejeda

Copy link
Copy Markdown
Contributor

0.42.0 shipped with an empty GitHub Release. Its CHANGELOG section was empty because nothing had landed since the v0.41.0 tag: #340 and #341 merged while the 0.41.0 release PR waited for review, so they were inside that tag but outside its notes, and git-cliff's next run (which starts at the tag) never saw them either.

  • scripts/check-release-notes.py <version> [--since <ref>]: the section must exist and have bullets; with --since, every PR merged since that ref must appear in it by (#N).
  • release.sh prepare runs it after cargo-release (bullets required).
  • release.sh finish runs it with --since <previous v* tag> before tagging, and tells you to cut again from current main when PRs are missing.

Checked against history: 0.40.0 passes, 0.41.0 fails (misses #340, #341), 0.42.0 fails (no bullets).

0.42.0 shipped with an empty GitHub Release. Its CHANGELOG section was empty
because nothing had landed since the v0.41.0 tag: #340 and #341 merged while
the 0.41.0 release PR waited for review, so they were inside that tag but
outside its notes, and git-cliff's next run (starting at the tag) never saw
them either.

scripts/check-release-notes.py checks a version's section. `prepare` runs
it after cargo-release and fails on a section with no bullets. `finish`
runs it with --since <previous tag> before tagging and fails when a pull
request merged since then is missing from the section, with a message to
cut the release again from current main.
@eddietejeda
eddietejeda requested a review from a team as a code owner October 15, 2026 21:46
@eddietejeda
eddietejeda requested review from anoop-narang and removed request for a team October 15, 2026 21:46
Comment on lines +68 to +72
missing = [
s for s in subjects
if not RELEASE_COMMIT.match(s)
and (m := PR_NUMBER.search(s)) and m.group(1) not in noted
]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exempt every subject that git-cliff drops from the --since check, not only release commits. The current check demands subjects that git-cliff never writes, so finish can fail permanently.

cliff.toml drops these commits:

  • non-conventional subjects (filter_unconventional = true, line 42)
  • docs(changelog) (line 68)
  • chore: bump version (line 75)
  • Merge pull request (line 76)

Failure scenario: this PR squash-merges as Release scripts refuse a release without notes (#343). That subject is not conventional, so git-cliff leaves #343 out of the 0.43.0 section. finish then reports #343 as missing and refuses to tag. The error message says to cut the release again from main. A new cut runs the same git-cliff filters, so it omits #343 again, and the release never tags.

Fix options:

  • Generate the expected set with git-cliff itself, for example git cliff <since>..HEAD --context, and compare the PR numbers it emits.
  • Or mirror the filters: require only subjects that match ^\w+(\([^)]*\))?!?: and do not match the skip = true parsers.

Also retitle this PR to a conventional subject, for example ci: release scripts refuse a release without notes. Without that change, #343 is dropped from the next changelog even after the fix.

print(__doc__, file=sys.stderr)
sys.exit(2)
version = args[0]
since = args[args.index("--since") + 1] if "--since" in args else None

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Use argparse here, or check that a value follows --since (not blocking). A trailing --since with no value raises IndexError and prints a traceback instead of the usage text. release.sh always passes a value, so only manual runs hit this case.

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review

Blocking Issues

  • scripts/check-release-notes.py:68-72: The --since check requires every (#N) subject since the previous tag. cliff.toml drops non-conventional subjects (filter_unconventional = true), docs(changelog), chore: bump version, and Merge pull request. Those PRs never reach the changelog, so release.sh finish refuses to tag. Cutting the release again produces the same changelog, so the release never tags. This PR's own subject, Release scripts refuse a release without notes (#343), is non-conventional and triggers the failure on 0.43.0.

Action Required

  • Exempt from the --since check every subject that git-cliff drops. Either derive the expected PR numbers from git-cliff output or mirror the cliff.toml filters.
  • Retitle this PR to a conventional subject, for example ci: release scripts refuse a release without notes.

@eddietejeda eddietejeda changed the title Release scripts refuse a release without notes fix(release): refuse a release without notes Oct 15, 2026
Mirror cliff.toml: a non-conventional subject, docs(changelog), the release
and bump-version commits, and merge commits never reach the changelog, so
the --since check must not demand them.
@eddietejeda
eddietejeda merged commit 9c7b62b into main Oct 15, 2026
14 checks passed
@eddietejeda
eddietejeda deleted the fix/require-release-notes branch October 15, 2026 21:50
@codecov

codecov Bot commented Oct 15, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

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.

1 participant