| name | release-harn |
| short | Merge-queue-safe Harn patch/minor/major release workflow. |
| description | Cut a Harn release through the merge queue. One PR carries CHANGELOG + Cargo.toml bump + regenerated artifacts; downstream tag push + binary build cascades fire automatically once it lands. |
| when_to_use | Use when cutting a Harn `vX.Y.Z` patch / minor / major release from main, or recovering from a partially-failed release run. |
Release Harn
Use this skill when cutting a Harn vX.Y.Z release from main, or
recovering from a partial release.
Pair it with [[harn-providers]] when the release includes provider
catalog or capability matrix changes (the bump regenerates those
artifacts).
Shape of a release
A Harn release is one human PR titled Release vX.Y.Z carrying
the consolidated bump:
CHANGELOG.md — a new ## vX.Y.Z section at the top with
### Added / ### Changed / ### Fixed subsections summarising
everything that lands in this version.
Cargo.toml (workspace version field) bumped to X.Y.Z.
Cargo.lock re-locked.
- Any per-crate manifest bumps the release-prep script touches
(
crates/*/Cargo.toml).
- Regenerated mirror artifacts the release-prep script refreshes
(provider catalog JSON / TS / Swift, capability matrix, highlight
keywords, etc. — whatever the previous release shipped).
After this PR lands through the merge queue, two GitHub Actions
workflows cascade automatically under the harn-release-bot App
identity:
land "Release vX.Y.Z" → publish-release pushes tag + cargo publish + GH release
→ tag push → build-release-binaries assembles binaries + GHCR container
Local entry points
The default flow:
./scripts/release_ship.sh --prepare --bump <patch|minor|major>
Recovery / partial-run reentry:
./scripts/release_ship.sh --finalize
./scripts/release_gate.sh <audit|prepare|publish|notes|full> ...
Manual workflow_dispatch entry points for recovery:
gh workflow run publish-release.yml --ref main
gh workflow run build-release-binaries.yml --ref main -f tag=vX.Y.Z
gh workflow run bump-release.yml --ref main
Before opening the PR
Sanity-check the local developer surface so any release-note bump that
mentions setup still works:
README.md
CONTRIBUTING.md
docs/src/portal.md
scripts/dev_setup.sh
Makefile
.githooks/
Commit pattern
A real release lands as one commit on main after squash:
Release vX.Y.Z — code + docs + CHANGELOG.md + Cargo.toml /
Cargo.lock + per-crate manifest bumps + regenerated mirrors.
Authored by you via release_ship.sh --prepare --bump <type>,
then rebased onto latest origin/main before push (because
--prepare takes 1–15 min and main may have moved during),
landed through PR / merge queue with gh pr merge --auto
enabled so it lands as soon as CI is green.
That's it. The bot takes over once it lands.
Cross-repo consumers don't wait on releases
An IDE host's scripts/fetch-harn.sh --local builds Harn from
~/projects/harn and installs the binaries directly. Use that during
cross-repo iteration instead of waiting for crates.io. Release batching
is a published-version concern, not a developer-loop concern.
Workflows
.github/workflows/publish-release.yml (display name: "Publish
release") — fires on push to main when Cargo.toml is ahead of
the latest vX.Y.Z tag. Pushes the tag using the App token so
downstream cascades fire (a GITHUB_TOKEN tag push would be
suppressed by GHA).
.github/workflows/build-release-binaries.yml (display name:
"Build release binaries") — fires on tag push. Also accepts a
tag input via workflow_dispatch for re-running against an
existing tag.
.github/workflows/bump-release.yml (display name: "Open
version bump PR (recovery)") — workflow_dispatch only; used to
reconstruct a bump PR if a "Prepare vX.Y.Z release"-style commit
accidentally lands on main without the consolidated bump.
Hard rules
- Never push to a PR already in the merge queue. GitHub silently
snapshots the PR at enqueue time and ignores subsequent pushes.
The pre-push hook detects this and aborts.
- Always rebase the release PR onto latest
origin/main before
the final push. release_ship.sh --prepare takes long enough
that main usually moves; not rebasing means the merge queue sees
a stale base and reorders the bump behind unrelated work.
- Never amend the release commit after CI starts. Open a new
bump PR via the recovery workflow instead.
Required repo state
- Secrets:
RELEASE_APP_ID, RELEASE_APP_PRIVATE_KEY,
CARGO_REGISTRY_TOKEN.
- App permissions on the repo:
Contents: write, Pull requests: write, Actions: write, Metadata: read.
Verify
- The release bump compiles:
cargo check --workspace.
- Conformance still passes:
make conformance.
- Catalog artifacts are in sync:
harn provider catalog generate --check.
- The CHANGELOG entry is non-empty and cites the issue / PR numbers
the release contains.
Cargo.toml workspace version matches the PR title's vX.Y.Z.