Skip to content

chore: add prepare-release and publish-release agent skills - #6147

Open
henryiii wants to merge 5 commits into
pybind:masterfrom
henryiii:chore/release-skills
Open

chore: add prepare-release and publish-release agent skills#6147
henryiii wants to merge 5 commits into
pybind:masterfrom
henryiii:chore/release-skills

Conversation

@henryiii

@henryiii henryiii commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator

Haven't tried these yet, but can try it on the next release.

To use this with Claude, symlink it to .claude/skills. Everyone else follows the agentskills standard.

🤖 AI text below 🤖

Description

Split the release process from docs/release.rst into two agent skills in .agents/skills/: prepare-release opens the changelog/version-bump PR, and publish-release does the manual steps after that PR merges (release branch, tag, stable, GitHub release, post-release bump).

Also un-ignores .agents in .gitignore (the MSVC Release pattern matched the release skill directory case-insensitively on macOS/Windows), and removes the outdated manual pybind11/_version.py update step from docs/release.rst — that file reads the macros from common.h and needs no edit.

Suggested changelog entry:

  • Make our release process a little more automated.

📚 Documentation preview 📚: https://pybind11--6147.org.readthedocs.build/

Split the release process from docs/release.rst into two agent skills:
a changelog/version-bump PR, and the manual publication steps after
that PR merges. Un-ignore .agents (the MSVC 'Release' pattern matched
the release skill directory case-insensitively) and drop the outdated
manual _version.py step from docs/release.rst.

Assisted-by: ClaudeCode:claude-fable-5
Comment thread .agents/skills/prepare-release/SKILL.md Outdated
[needs changelog](https://github.com/pybind/pybind11/pulls?q=is%3Apr+is%3Aclosed+label%3A%22needs+changelog%22).
- Integrate the output into `docs/changelog.md` under the section for this
version, and add the release date (today) to the section header.
- Review, and inform the user if any edits are needed.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I believe I can extract more detailed instructions from an agent context that I used for the 3.0 patch releases. I'll try to do that soon.

This is to instruct the agent to normalize the style of the changelog entries.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Go ahead, you should be able to push here.

Teach the prepare-release skill to proofread generated changelog entries for tense, concision, categorization, and PR-link consistency before opening release-prep PRs.
@rwgk

rwgk commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator

Small update:

I added commit 77292b9, using an old agent thread from the 3.0.2, 3.0.3, 3.0.4 releases.

I'm now working with a fresh agent and newer model on a full review.

@rwgk

rwgk commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator

Hi @henryiii gpt-5.6-sol ultra added two more commits. It worked on them much longer than I anticipated (1/2 hour or so!). Feel free to rework any way you see fit.


Summary

I added two [no ci] commits after a second full audit of the release skills and the existing release process:

  • 4f864b4 is a small portability/metadata cleanup.
  • c590ce9 makes the release workflow fail closed: it selects the actual release line, pins the reviewed and tested release tree, makes interrupted publication safely resumable, and brings docs/release.rst into agreement with the skills.

There are no library or runtime-code changes. The [no ci] markers are intentional; the relevant local validation is summarized below.

Why the larger safety pass seemed necessary

The earlier Cursor review correctly identified the most serious issue: a maintenance release could be prepared from master, after which publish-release would merge master into vX.Y. Once master has moved to a newer minor line, that can import the newer line into the maintenance branch before the old workflow notices a version mismatch.

Looking at the recent release history also showed that the correct base cannot be inferred from the patch number alone: some patch releases were still cut from master, while later maintenance releases used vX.Y. The revised workflow therefore inspects and confirms the actual release line, and never merges a newer master into an older release branch.

The audit found a few related cases with the same underlying problem: the workflow relied too much on moving branch tips and local checkout state. In particular, it did not pin the release to the preparation PR, validate the requested version before the first remote mutation, or define safe retry behavior after a partially completed release.

Portability cleanup

4f864b4:

  • Removes argument-hint, which is not accepted by the portable skill validator used here.
  • Spells out the full PY_RELEASE_LEVEL_ALPHA / BETA / GAMMA names.
  • Removes the broad !.agents/** exception from .gitignore. I reproduced the ignore-case behavior: the existing Release pattern does not hide prepare-release or publish-release, while the blanket exception could unintentionally re-include future ignored files anywhere below .agents.

Release-workflow hardening

c590ce9 updates both skills and the canonical release documentation. The main changes are:

Release source and identity

  • The preparation PR explicitly targets either master or the maintained vX.Y line, based on branch state and release history rather than version spelling.
  • Publication requires the exact requested version and preparation PR. Its merge commit is the default release commit.
  • A later commit can be selected, but only deliberately: its additional changes, changelog implications, review, and equivalent CI must be checked and recorded.
  • Version macros, changelog version/date, branch containment, CI-tested tree, and both PyPI distributions are checked before any official ref changes.

Remote operations and retries

  • Official repository URLs, remote refs, push refspecs, and PR bases/heads are made explicit; stale local tracking branches are not trusted.
  • Release branches are created or fast-forwarded only after ancestry checks. They are never rewound or force-pushed.
  • Tags are annotated and point to the exact release SHA. The instructions distinguish absent, local-only, remote-only, and matching local/remote states, so an interruption between tag creation and push can be resumed safely.
  • A durable checkpoint records the chosen SHA, CI evidence, tag object, remote refs, release, and workflow state after each step.
  • stable is never updated for a prerelease or moved backward to an older maintenance line. GitHub's “Latest” designation follows the same explicit decision.

GitHub release and post-release handling

  • Release notes come from the verified tag and are previewed from a file. Publication uses --notes-file, --verify-tag, and --repo pybind/pybind11; prerelease and --latest=false handling are explicit.
  • The release-triggered workflow and the inventories of both pybind11 and pybind11-global must be verified before consumed changelog labels are removed.
  • A manual upload is treated as a separate recovery operation using inspected artifacts, rather than an automatic fallback over dist/*.
  • The next development version is no longer inferred arithmetically. A maintenance release leaves an already-ahead master alone; prereleases normally remain on the same line; any next patch/minor alpha is an explicit project decision.
  • Version invariants are documented completely, including final serial 0 and prerelease serials 1..15 (the serial occupies four bits in PYBIND11_VERSION_HEX).

The docs/release.rst change is intentionally substantial because both skills declare it the source of truth. Fixing only the agent instructions would have left the human release documentation prescribing the unsafe branch, stable, and post-release behavior.

Validation

I ran:

  • the full pre-commit suite;
  • the validator for both skills;
  • the Sphinx documentation build; and
  • independent forward audits covering a current-line final release, an RC, an older-line maintenance release after master moved on, and retries after partial branch/tag/release progress.

After the final fixes, those scenario audits found the flows fail-safe and internally consistent. The two policy choices most worth a human look are the explicit stable/GitHub Latest decision and the decision not to invent a post-release development version automatically.

Comment thread docs/release.rst

nox -s build
nox -s build_global
twine upload dist/*

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Removing this was an "over correction". I'm working on it.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Pushed commit 9b88152

IIUC, my codex wants to make everything watertight, which is probably good for steering agents, but is a bit at odds with what a human would do.

My thinking: maybe make another pass with another model, to simplify, then try it out in the wild and tweak as needed, based on practical experience?

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