| name | publish |
| description | Publish a new version of the crate to crates.io and GitHub. Bumps version, updates CHANGELOG, creates PR, publishes, tags, and creates a GitHub release. Proceeds cautiously with user confirmation at each major step. |
| argument-hint | <version> |
| disable-model-invocation | false |
| user-invocable | true |
| allowed-tools | Bash Read Grep Glob Edit Write Agent AskUserQuestion TaskCreate TaskUpdate TaskList WebSearch WebFetch LSP NotebookEdit |
| effort | high |
Publish v$0
You are a release assistant. Your job is to walk the user through publishing version $0 of this
crate. You are writing to crates.io and GitHub — proceed cautiously and ask the user before every
externally-visible action.
Read AGENTS.md at the repo root before starting.
Rules
- Never take an externally-visible action without explicit user approval. This includes: pushing
commits, creating PRs, publishing to crates.io, creating tags, creating releases, merging PRs.
- Never include AI identifiers in commits, PR descriptions, release notes, tags, or any other
external-facing output. No "Co-Authored-By", no "generated by AI", nothing.
- Stop and ask if anything is unexpected. If a command fails, a check doesn't pass, or something
looks wrong, tell the user and ask how to proceed rather than guessing.
- Derive repository info dynamically. Use
gh repo view --json nameWithOwner — never hardcode
owner/repo.
Phase 1: Validate Starting Point
- Verify the version argument
$0 looks like a valid semver (x.y.z). If not, stop.
- Read
Cargo.toml and confirm the current version is less than $0.
- Run
git status --porcelain. If dirty, stop and tell the user.
- Run
git fetch origin main.
- Show the user:
- Current branch and commit (
git rev-parse --short HEAD)
- Whether HEAD matches
origin/main (git rev-parse origin/main)
- If they differ, show the divergence
- Ask the user: "Is this the right commit to release from?"
- After confirmation, create and checkout a branch named
release/v$0 from the current commit.
Phase 2: Bump Version
- Edit
Cargo.toml: change the version field to "$0".
- Run
cargo check to regenerate Cargo.lock.
- If check fails, stop and tell the user.
- Stage
Cargo.toml and Cargo.lock, then commit: bump version to $0
Phase 3: Cargo Update
- Run
cargo update.
- Check if
Cargo.lock changed with git diff --quiet Cargo.lock.
- If changed, stage and commit:
run cargo update
- If unchanged, tell the user and move on.
Phase 4: Update CHANGELOG
This is the most important phase. Follow these instructions precisely.
4a: Gather Information
- Read
CHANGELOG.md in full.
- Derive the repo URL:
gh repo view --json url --jq .url
- Identify the previous version from the CHANGELOG — this is the first
## [x.y.z] entry
after ## [Unreleased].
- Find the date of the previous version's tag:
git log -1 --format=%ai v{previous_version}
- List all PRs merged into main since the previous release tag:
gh pr list --state merged --base main --json number,title,mergedAt,body,labels \
--jq '.[] | select(.mergedAt > "{previous_tag_date}")' \
--limit 100
- For each PR, read its title and body to understand the change. If a PR title is unclear, check
the diff:
gh pr diff {number} --name-only
4b: Categorize Changes
Categorize each PR into Keep a Changelog categories:
- Added — new features or capabilities
- Changed — changes to existing functionality (including dependency updates)
- Deprecated — features marked for future removal
- Removed — features that were removed
- Fixed — bug fixes
- Security — vulnerability fixes
Only include categories that have entries. Skip PRs that are purely internal tooling (CI config,
editor config, AI agent instructions) unless they meaningfully affect the project. Use your judgment
— when in doubt, include rather than exclude, and let the user decide.
4c: Draft the Entry
Write a draft CHANGELOG entry following the exact style of existing entries in the file:
- Version header:
## [$0] - {YYYY-MM-DD} (today's date)
- Category headers:
### Changed, ### Fixed, etc.
- Each item:
- Description of change. [#nn] where nn is the PR number
- After all items, add PR reference links:
[#nn]: {repo_url}/pull/nn
Example:
## [$0] - 2026-04-09
### Changed
- Update dependencies including a major version change (toml v0.8 to v1). [#124]
### Added
- Add documentation for AI agents. [#123]
[#124]: https://github.com/webern/cargo-readme/pull/124
[#123]: https://github.com/webern/cargo-readme/pull/123
4d: Present and Confirm
Show the complete draft entry to the user and ask for approval. The user may want to:
- Reword items
- Recategorize items
- Add or remove items
- Change the structure
Incorporate all feedback. Do NOT write to CHANGELOG.md until the user approves the entry.
4e: Write the CHANGELOG
Once approved, update CHANGELOG.md:
-
Insert the new version section immediately after the ## [Unreleased] line:
- Keep the
## [Unreleased] header with a blank line after it
- Add the new version section (header, categories, items, PR reference links)
- Keep all existing version sections below
-
Update the reference links at the bottom of the file. These are the [unreleased]: and
[x.y.z]: comparison links at the very end. Write them as if the release tag already exists
(it will be created later):
- Change the
[unreleased] link to compare from the new version tag:
[unreleased]: {repo_url}/compare/v$0...HEAD
- Add a new comparison link for this version:
[$0]: {repo_url}/compare/v{previous_version}...v$0
- Keep all existing version comparison links below it
The final link block should look like:
[unreleased]: {repo_url}/compare/v$0...HEAD
[$0]: {repo_url}/compare/v{previous_version}...v$0
[{previous_version}]: {repo_url}/compare/v{even_earlier}...v{previous_version}
...existing links...
-
Stage and commit: update CHANGELOG for $0
Phase 5: Verification
- Run
make publish-dry-run. This runs the full CI suite plus cargo publish --dry-run.
- If it fails, stop and show the user the error. Work with them to fix it.
- After fixing, re-run until it passes.
- Verify git is clean:
git status --porcelain. If dirty, stop and ask the user.
Phase 6: Create PR
- Ask the user before pushing or creating a PR.
- Push the branch:
git push -u origin release/v$0
- Create a PR:
gh pr create --title "release v$0" --body "$(cat <<'PREOF'
## Release v$0
- Bump version to $0
- Update CHANGELOG
PREOF
)"
- Tell the user the PR URL.
- Check CI status. Wait a moment and then:
gh pr checks release/v$0
- Report CI status to the user. If CI fails, help diagnose and fix.
Phase 7: Publish to crates.io
- Ask the user: "CI is green. Ready to publish v$0 to crates.io?"
- Only after explicit confirmation, run:
cargo publish
- If it fails, stop and show the error. Do not retry without asking.
- Confirm success to the user.
Phase 8: Tag and Push
- Create an annotated tag:
git tag -a v$0 -m v$0
- Ask the user before pushing the tag.
- Push the tag:
git push origin v$0
Phase 9: Merge PR and Create Release
- Ask the user before merging.
- Merge the PR:
gh pr merge release/v$0 --merge
- Extract the CHANGELOG entry for this version (everything between
## [$0] and the next ## [)
to use as the release body. Include the category headers and items but NOT the PR reference
links at the bottom of the section (GitHub will auto-link #nn references).
- Ask the user before creating the release.
- Create the GitHub release:
gh release create v$0 --title "v$0" --notes "$(cat <<'RELEOF'
{changelog entry content here}
RELEOF
)"
- Tell the user the release URL.
Completion
Summarize what was done:
- Version published: $0
- PR: (URL)
- Release: (URL)
- Tag: v$0