Skip to content

feat(release): attach built distributions to the GitHub Release on tag - #2

Merged
haoranc merged 1 commit into
mainfrom
promote/github-release-job
Sep 7, 2026
Merged

feat(release): attach built distributions to the GitHub Release on tag#2
haoranc merged 1 commit into
mainfrom
promote/github-release-job

Conversation

@spbkgw-beep

Copy link
Copy Markdown
Contributor

The v0.1.0 tag published to PyPI and left this repository with a bare tag — no Release, and none of the artifacts the run had already built and uploaded. This adds the job that closes that.

The v0.1.0 Release was created by hand from that run's artifacts so it is not left empty. This is so nobody has to do that again.

The job

A third job, needs: build, permissions: contents: write, downloading the same python-package-distributions artifact the build job already uploads. Create-or-update, so a re-run refreshes the assets rather than failing.

It depends on build rather than on publish-pypi, so a Release still appears if the PyPI upload is skipped or fails. Noting that as a deliberate choice rather than an oversight.

Why the notes come from the changelog

Generated release notes summarise the commits in a release. This repository receives each version as a single commit, so generated notes for v0.1.0 would have been one line describing thirteen changes. The changelog section is already one line per user-visible change, each linking into the command reference.

scripts/release_notes.py extracts it and does two things a raw paste would get wrong:

  1. Rewrites relative links absolute, pinned at the tag. A release body is not rendered relative to the repository root, so docs/commands.md#init would 404. Pinning at the tag rather than a branch also keeps old release notes pointing at the documentation as it stood for that version.
  2. Drops the section heading — the release already carries the version.

Verified

  • The script reproduces the notes on the live v0.1.0 Release byte for byte, which is the evidence it would produce the same result unattended.
  • Positive path: --tag v0.1.0 exits 0 — 13 links, all absolute, all pinned at /blob/v0.1.0/.
  • Negative path: --tag v9.9.9 exits 1 with a diagnostic, and the workflow branches on that to fall back to generated notes. A guard that cannot fail is not a guard, so this direction was tested rather than assumed.
  • Both changelog heading shapes parse: ## 0.1.0 - DATE and the bracketed ## [0.1.0] - DATE.
  • make preflight green — ruff clean including the new script, 654 passed / 46 skipped, both artifacts built, twine check PASSED.

No changelog entry: a release-pipeline step is not a user-visible delta, and an entry would consume the next version number for plumbing.

🤖 Generated with Claude Code

https://claude.ai/code/session_01GeBdcy43H9CZkcjk4Jvt8n

…n tag

A `v*` tag published to PyPI and left the tag bare here: no Release, and none of
the artifacts the run had already built. A third job now downloads the same
artifact the build job uploads and creates or updates the Release with the wheel
and sdist attached.

Release notes come from the changelog section for the tag rather than from
generated notes, which summarise commits and so cannot describe a release that
arrives as a single commit. `scripts/release_notes.py` extracts the section,
rewrites its relative links absolute and pinned at the tag — a release body is
not rendered relative to the repository root, so relative targets 404 — and
exits non-zero when no section matches, so the workflow falls back to generated
notes instead of publishing an empty body.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GeBdcy43H9CZkcjk4Jvt8n
@haoranc
haoranc merged commit d51fa4c into main Sep 7, 2026
4 checks passed
@haoranc
haoranc deleted the promote/github-release-job branch September 7, 2026 05:20
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.

2 participants