Make RELEASE.md describe the release we actually run - #129
Conversation
Two places where the documented process contradicted the tooling, both of which have already cost us something. The version bump section told you to hand-write the `Version X.Y.Z (YYYY-MM-DD)` heading into CHANGELOG.rst and commit it, then run `make version-bump`. But bump_version.py inserts that heading itself and commits it. Following the document produces a duplicate heading and a redundant commit - which happened on 9.3.1 - and a duplicate heading also breaks extract_changelog.py, so the GitHub release notes would come out wrong. The section now says to write entries under `Unreleased` only, and lists what the script does, including the clean-tree and up-to-date checks that decide whether it runs at all. Sections 6-8 documented `make publish` / `twine upload` with TWINE_USERNAME and TWINE_PASSWORD. That path is obsolete: release.yml publishes through PyPI trusted publishing when a v* tag is pushed. A maintainer following the document after pushing a tag would attempt to upload a version PyPI had already accepted. Those sections are replaced by a description of what the workflow does, an explicit "do not publish by hand", and a note that no credentials need setting up. The Makefile targets stay as an emergency fallback and are labelled as such - in the docs and in `make release`'s own output, which was telling you to run `make publish` when it finished. Also adds the recovery for a release that fails after the tag is pushed, since the tag is the trigger and a red pre-release check leaves one behind. That is what 9.3.1 needed, and it was not written down. The CI section no longer suggests setting up CI that has existed for a while; it lists the jobs, including why `Test without CLI extras` is there. Claude-Session: https://claude.ai/code/session_01XVj9BYvuLj7Th3iFUVoeCn
There was a problem hiding this comment.
🟡 Changes recommended
RELEASE.md currently documents a CI job (“Test without CLI extras”) that is not present in ci.yml (PR #128 is still open), and a couple of script-behavior details are slightly overstated.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
Updates the project’s release documentation (and make release messaging) to match the actual automated tag-triggered GitHub Actions publishing flow, reducing the risk of maintainers following obsolete/manual steps.
Changes:
- Clarifies that
make releaseis a local readiness check/build step and does not publish. - Updates version bump guidance to reflect that the bump script owns the changelog heading/commit/tag.
- Replaces obsolete manual PyPI upload instructions with the CI-driven trusted publishing workflow and recovery guidance.
File summaries
| File | Description |
|---|---|
RELEASE.md |
Aligns the documented release process with the current bump script + tag-triggered release.yml workflow, and updates CI/publishing guidance. |
Makefile |
Adjusts release target description/output to avoid implying manual publishing and to point at the tag-based release flow. |
Review details
Suppressed comments (1)
RELEASE.md:391
- This paragraph describes the rationale for a "Test without CLI extras" job, but that job is not present in
.github/workflows/ci.ymlin the current codebase (PR #128 is still open). Either add the job to CI in this PR, or reword this section to describe it as a proposed/pending improvement instead of an existing workflow.
`Test without CLI extras` exists because `tox` installs the `cli` extra while
`release.yml` does not. Without it, a test module that imports `click` outside
its `ImportError` guard passes every pull request and fails only once the
release tag has been pushed.
- Files reviewed: 2/2 changed files
- Comments generated: 4
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| - Refuse to run unless the working directory is clean and in sync with | ||
| the remote |
There was a problem hiding this comment.
Fixed in f7aacf5 — the list now says it refuses to run when the working directory is dirty or the branch is behind its upstream, and that being ahead or having no upstream only warns.
| - Insert `Version X.Y.Z (YYYY-MM-DD)` under `Unreleased` in `CHANGELOG.rst` | ||
| - Commit that as `Update changelog for vX.Y.Z` | ||
| - Create the annotated tag `vX.Y.Z` | ||
|
|
There was a problem hiding this comment.
Fixed in f7aacf5, at the source: bump_version.py no longer prints the make publish-test / make publish next steps. It now says to push the commit and the tag, and that the tag triggers release.yml — so there is nothing left for the document to warn about.
| progression checks, and does not touch the changelog - so the GitHub release | ||
| notes will be empty unless you added the heading yourself. Use the version |
There was a problem hiding this comment.
Fixed in f7aacf5 — the warning now says extract_changelog.py finds no matching section and the notes fall back to the bare line Release X.Y.Z, rather than being empty.
| | Test without CLI extras | pytest against a `.[testing]`-only install, matching what `release.yml` does | | ||
| | Build Distribution | `python -m build` plus `twine check` | |
The script refuses to run when the branch is behind upstream; being ahead or having no upstream is only a warning, so "in sync with the remote" overstated it. A manual tag does not produce empty release notes either - extract_changelog.py falls back to "Release X.Y.Z". The script's own closing output still pointed at make publish-test / make publish, contradicting the document it is meant to match; it now points at the tag flow. Claude-Session: https://claude.ai/code/session_01YDSWT2RqH9T5r7Q4ZUsaEK
Two places where the documented process contradicts the tooling. Both have already cost us something on 9.3.1.
1. Two things wanted to write the changelog heading
RELEASE.md:114said to editCHANGELOG.rstand addVersion X.Y.Z (YYYY-MM-DD)by hand, then commit it, then runmake version-bump. Butbump_version.py:update_changelog()inserts that heading itself andcommit_changelog()commits it.Follow the document and you get a duplicate heading and a redundant commit — which is what happened cutting 9.3.1. It is worse than cosmetic:
scripts/extract_changelog.pyparses that heading to build the GitHub release notes, so a duplicate produces wrong release notes.The section now says to write entries under
Unreleasedonly, and lists what the script actually does — including the clean-working-directory and up-to-date-with-remote checks that decide whether it runs at all, neither of which was documented.2. The manual publish path is obsolete
Sections 6–8, the pre-release checklist, and the command table all documented
make publish/twine uploadwithTWINE_USERNAMEandTWINE_PASSWORD. That is not how this project publishes:release.ymlusespypa/gh-action-pypi-publishwith PyPI trusted publishing, triggered by av*tag.A maintainer following the document after pushing a tag would attempt to upload a version PyPI had already accepted. Replaced with:
make release's own output was also telling you to runmake publishwhen it finished — that now points at the tag flow. Its name is misleading too, so the Quick Release section opens by saying it releases nothing.Also
Test without CLI extras(Run the tests once without the CLI extras #128) exists.Verified: no broken intra-document anchors, no surviving references to the manual upload flow,
make release's new output reads correctly.Docs and one Makefile echo only — no library code changes.