Skip to content

🐛 fix(release): generate consistent CHANGELOG heading levels#1032

Merged
gaborbernat merged 3 commits into
pypa:mainfrom
gaborbernat:fix/release-changelog-headings
Apr 13, 2026
Merged

🐛 fix(release): generate consistent CHANGELOG heading levels#1032
gaborbernat merged 3 commits into
pypa:mainfrom
gaborbernat:fix/release-changelog-headings

Conversation

@gaborbernat

Copy link
Copy Markdown
Collaborator

Read the Docs' stable version has been pinned at 1.4.0 since January because every tagged release after it (1.4.1, 1.4.2, 1.4.3) shipped a CHANGELOG.rst entry whose heading characters did not match prior entries, and sphinx -W rejected the file with Inconsistent title style: skip from level 1 to 3. The previous two releases were patched up by hand after the fact; 1.4.3 has not been, which is what issue #1031 reports. 🐛

The root cause traces back to #1002, which added top_underline = "#" to [tool.towncrier] intending to drive the version overline character. top_underline has never been a towncrier config key, though. Its settings loader only reads underlines, and internally towncrier passes underlines[0] into the template as the top_underline variable. The addition was silently ignored from the day it landed, and every subsequent release kept emitting * for the version heading and = for the section headings, neither of which match the #/* hierarchy the rest of the changelog uses. When the release script then ran pre-commit, docstrfmt rejected the hybrid file and left the new entry half-rewritten.

The fix prepends # to underlines so towncrier feeds # as the top underline and * as the section underline, which matches both the historical changelog and docstrfmt's expectations. The 1.4.3 entry is rewritten to the correct hierarchy so the current docs build succeeds without another follow-up patch commit. As a backstop, the pre-release workflow now runs tox r -e docs against the generated release commit before pushing, so any future regression fails the workflow instead of shipping a tag whose docs cannot build.

Verified end-to-end by running tox r -e release -- --version 1.4.3 --no-push against the pre-1.4.3 commit in a worktree: with the config fix, the release script completes, docstrfmt stays idempotent, and sphinx -W -n builds cleanly. Once 1.4.4 tags with this fix, RTD's stable will catch up.

Closes #1031.

Every release since 1.4.1 produced a CHANGELOG entry whose heading
characters did not match prior entries, breaking sphinx -W with
"Inconsistent title style: skip from level 1 to 3" and pinning
Read the Docs' stable version at 1.4.0 since no tagged build after
that could complete.

The root cause is that `top_underline` has never been a towncrier
config key. The settings loader only reads `underlines`, and towncrier
passes `underlines[0]` into the template as the `top_underline`
variable. PR pypa#1002 added `top_underline = "#"` intending to drive the
version heading, but towncrier silently ignored it and kept emitting
`*` for the top line and `=` for sections, neither of which matched
the `#`/`*` hierarchy established by every historical entry. docstrfmt
then rejected the hybrid file, and the release script's first
pre-commit pass left the new entry half-rewritten.

Prepend `#` to `underlines` so towncrier feeds `#` as the top
underline and `*` as the section underline, matching the existing
changelog and docstrfmt's expectations. Rewrite the 1.4.3 entry to
the correct hierarchy so the current docs build succeeds without a
follow-up patch commit. Add a docs build step to the pre-release
workflow as a backstop so any future regression fails the run before
a tag is pushed.
@gaborbernat gaborbernat added the bug Something isn't working label Apr 13, 2026
@gaborbernat gaborbernat enabled auto-merge (squash) April 13, 2026 16:05
@gaborbernat gaborbernat merged commit 3f43463 into pypa:main Apr 13, 2026
65 checks passed
@gaborbernat gaborbernat deleted the fix/release-changelog-headings branch April 13, 2026 16:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Docs show error (inconsistent skip) and stable docs stuck at 1.4.0

2 participants