| name | release |
| description | Cut a new agentd release. Suggests the next semver version from conventional commits (or accepts an explicit `x.y.z`), bumps the workspace version, regenerates the changelog with git-cliff, then commits, tags, and pushes the `v*` tag that triggers the Release workflow. Use when the user runs /release or asks to publish/cut/tag a new version. |
Release
Cut a new release of agentd. Releases are tag-driven: pushing a v* tag to
GitHub triggers .github/workflows/release.yml, which cross-compiles the
binaries and publishes a GitHub Release with notes generated by git cliff.
This skill prepares the version bump and changelog, then performs the tag push
that kicks off CI.
Invocation
/release — inspect commits since the last tag and suggest the next
version (the agent proposes it and asks the user to confirm before proceeding).
/release x.y.z — use x.y.z as the new version explicitly (no leading v).
The argument, if present, is the target version. Validate it matches
^[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.]+)?$. Reject anything else and ask the
user to restate it.
Preconditions (check first, stop on any failure)
- Clean working tree — run
git status --porcelain. If there are
uncommitted changes, stop and report them; do not bundle unrelated work into
a release commit.
- On a release-able branch — releases are cut from
main. Confirm with
git rev-parse --abbrev-ref HEAD. If not on main, ask the user whether to
switch (git checkout main && git pull) before continuing.
- Up to date with origin —
git fetch --tags origin then verify main is
not behind origin/main.
- Tooling present —
git cliff --version (expect 2.x) and cargo --version.
Step 1 — Determine the current and next version
Read the current version (single source of truth — all crates inherit it):
grep -m1 '^version' Cargo.toml
git tag -l 'v*' | sort -V | tail -1
[!IMPORTANT]
These two can disagree (e.g. Cargo.toml at 0.2.0 but latest tag v0.3.0).
If they differ, surface the mismatch to the user and ask which is the true
baseline before suggesting a bump. Do not silently pick one.
If a version argument was given: use it as NEW_VERSION. Sanity-check it is
strictly greater than both the current Cargo.toml version and the latest tag.
If it is not greater, warn and ask the user to confirm.
If no argument was given (suggest mode): let git-cliff infer the bump from
conventional commits since the last tag:
git cliff --bumped-version
Map the result to NEW_VERSION (strip the leading v). Also show the user a
short summary of what changed so the suggestion is justified:
git cliff --unreleased --bump
Present the suggested version + the changelog preview and ask the user to
confirm or override before making any changes. Do not proceed unprompted.
Step 2 — Bump the workspace version
Only the root Cargo.toml needs editing — every crate uses
version.workspace = true, so the bump propagates automatically.
Edit Cargo.toml:
[workspace.package]
version = "X.Y.Z"
Then refresh the lockfile so the workspace package entries match:
cargo update --workspace
If cargo update --workspace does not update them, run cargo check --workspace
(a build resolves and rewrites Cargo.lock). Confirm Cargo.lock now shows the
new version for the workspace crates.
[!NOTE]
ui/package.json is intentionally 0.0.0 and is not part of the release
version. Leave it untouched unless the user explicitly asks.
Step 3 — Regenerate the changelog
The committed CHANGELOG.md is produced by git-cliff (config in cliff.toml).
Regenerate it for the new tag from full history:
git cliff --tag vX.Y.Z --output CHANGELOG.md
Review the diff. Only feat, fix, refactor/perf, chore(deps), and
docs commits appear (per cliff.toml); style/chore/ci/test/build
are skipped. If the new section is empty or obviously wrong, stop and report —
it usually means there are no release-worthy commits since the last tag.
Step 4 — Commit, tag, push
[!CAUTION]
Pushing a v* tag is outward-facing and hard to reverse — it immediately
triggers the Release workflow and publishes a public GitHub Release. Show the
user exactly what will be committed and pushed, and get explicit confirmation
before running the push. Never --force push or retag an existing release.
git add Cargo.toml Cargo.lock CHANGELOG.md
git commit -m "chore(release): vX.Y.Z"
git push origin main
git tag -a vX.Y.Z -m "Release vX.Y.Z"
git push origin vX.Y.Z
If the project's branch policy (see CLAUDE.md) blocks pushing the release
commit directly to main, instead open a PR for the chore(release) commit,
get it merged, then create and push the tag from the updated main. Ask the
user which path they want when in doubt.
Step 5 — Verify the release ran
After pushing the tag, confirm CI picked it up:
gh run list --workflow=release.yml --limit 3
gh release view vX.Y.Z
The workflow builds binaries for x86_64-unknown-linux-musl,
x86_64-apple-darwin, and aarch64-apple-darwin, then publishes a GitHub
Release with git cliff --current notes and the binaries attached. Report the
release URL (or the in-progress run) back to the user.
Rollback
If something is wrong before the tag is pushed: git reset --soft HEAD~1
and discard the changelog/version edits.
If the tag was already pushed and the release is bad, do not delete or move
the tag yourself — that is a destructive, gated operation. Surface the problem
to the user and let them decide (typically: cut a new patch release rather than
retag).