| name | gnit-release |
| description | Cuts a Gnit release: runs pre-release checks (fmt, clippy, tests, clean tree, auth, fetched tags), proposes the next semver from the commits since the last tag, sweeps docs (README, site guide, the bundled CLI skill) for release-tied updates, bumps the version in Cargo.toml and Cargo.lock, commits and pushes the bump to master, then tags vX.Y.Z and pushes the tag so the tag-driven release workflow builds the binaries and publishes the GitHub release. Use this skill whenever the user says "release", "cut a release", "new version", "bump the version", "ship vX.Y.Z", or anything about shipping a new version of gnit.
|
Gnit release
This skill cuts a release of the gnit CLI. The pipeline is tag-driven:
pushing a v* tag triggers .github/workflows/release.yml, which builds the
binaries for every target and publishes the GitHub release. Two other workflows
react to the same push to master: ci.yml (fmt + clippy + tests on Ubuntu and
macOS) and deploy-site.yml (redeploys the VitePress site).
Gnit is a single Rust binary with no submodules, no Docker images, and no runtime
infra pins — so a release is just: get master green and version-bumped, push
it, then push the tag. The release workflow does the building and publishing.
Your job is to prepare everything locally, push the version-bump commit to
master, then push the release tag and verify the workflows go green.
Step 1: Pre-release sanity checks
git status --short
git fetch --tags
gh auth status
cargo fmt --check
cargo clippy --all-targets -- -D warnings
cargo test --locked
If the working tree is dirty, decide with the user whether those changes belong
in this release or should be committed/stashed separately.
CI runs clippy with the current stable toolchain and -D warnings. If your
local toolchain lags, a lint that is clean locally can fail CI on the tag. Run
rustup update stable && cargo clippy --all-targets -- -D warnings before
tagging to catch newer lints in one pass.
Step 2: Determine the version
git tag --sort=-v:refname | head -3
gh release list --limit 5
git log "$(git describe --tags --abbrev=0)..HEAD" --oneline
Propose a semver bump from the commits and confirm with the user (or use the
version the user already named):
- patch (0.x.Y) — bug fixes, doc updates, dependency bumps, internal
refactors, diagnostics.
- minor (0.X.0) — new subcommands or flags, new capabilities, changed
default behavior that is additive.
- major (X.0.0) — breaking changes (not applicable pre-1.0).
If there are no commits since the last tag, there is nothing to release — say so.
Step 3: Docs sweep
Release changes ripple into docs. Sweep each before bumping the version, and
commit doc changes as their own focused commit(s) ahead of the version bump.
README — README.md
- Quickstart commands, flags, and example output still accurate.
- The feature/command list reflects reality (new commands, new behavior).
- The "Repository Layout" and install sections are current.
- Any version strings.
Site guide — site/guide/*.md
cli.md — new/changed subcommands, flags, default behavior, output examples,
new error conditions. This is the command reference; keep it exhaustive.
quickstart.md, concepts.md, design.md (locked-decision list).
- Validate the build before committing:
cd site && npm run build
Bundled CLI skill — skills/gnit/SKILL.md
This is the shipped agent skill: it is embedded into the gnit binary via
include_str!("../skills/gnit/SKILL.md") in src/skills.rs and is what
gnit skills install puts into agent harnesses. Any user-visible CLI change must
be reflected here, or every agent using the installed skill gives stale guidance.
(This gnit-release skill is not shipped — gnit skills install is hardcoded
to skills/gnit/ only, so the maintainer skills under skills/ never reach end
users.)
Decisions and examples
docs/decisions/ — if a decision changed user-visible behavior, make sure the
README and guide reflect it.
- Keep example identifiers and output snippets consistent with current formats
(e.g. Change/Pin ids).
Grep for stale version strings:
grep -rn "0\.[0-9][0-9]*\.[0-9]" README.md site/ skills/ --include='*.md'
Step 4: Bump the version
Edit the version in both files — in Cargo.lock, change only the name = "gnit"
package's version:
Cargo.toml → version = "X.Y.Z" under [package].
Cargo.lock → the version line directly under name = "gnit".
Verify the bump is internally consistent and reported correctly:
cargo build --locked
./target/debug/gnit --version
Step 5: Commit and push master first
Stage explicitly — do not use git add -A:
git add Cargo.toml Cargo.lock
git commit -m "Bump version to X.Y.Z"
git push origin master
Match the existing history: the version bump is its own commit (message exactly
Bump version to X.Y.Z), and the release tag points at it. Push master before
tagging so the release build checks out a commit that exists on the remote
default branch.
Do not add a signature or Co-Authored-By trailer to the commit (repo
convention).
If the push is rejected because the remote moved, rebase and re-push before any
tag work:
git pull --rebase origin master
git push origin master
Step 6: Tag and push the release
Gnit tags are lightweight and sit on the bump commit (match v0.8.0,
v0.8.1):
git tag vX.Y.Z
git push origin vX.Y.Z
Pushing the tag triggers release.yml. The build job compiles three targets —
linux-x86_64, darwin-x86_64, darwin-aarch64 — packages each as
gnit-X.Y.Z-<os>-<arch>.tar.gz, and the release job creates the GitHub release
with those tarballs plus checksums.txt. GitHub marks the newest release Latest
automatically.
Step 7: Verify
gh run list --limit 6
gh run watch <release-run-id> --exit-status
Then confirm the published release:
gh release view vX.Y.Z --json tagName,isDraft,isPrerelease,assets \
--jq '{tag: .tagName, draft: .isDraft, prerelease: .isPrerelease, assets: [.assets[].name]}'
gh release list --limit 3
Expect: not draft, not prerelease, marked Latest, and four assets —
checksums.txt, gnit-X.Y.Z-darwin-aarch64.tar.gz,
gnit-X.Y.Z-darwin-x86_64.tar.gz, gnit-X.Y.Z-linux-x86_64.tar.gz.
Also confirm CI went green on both the master push and the tag, and watch the
Deploy Site run to success if the release touched site/:
gh run list --limit 8
gh run watch <deploy-site-run-id> --exit-status
Report the result to the user with links:
- Release:
https://github.com/mostlydev/gnit/releases/tag/vX.Y.Z
- Site:
https://mostlydev.github.io/gnit/
Optional: enrich the release notes
The workflow publishes bare notes (Gnit vX.Y.Z). For a notable release, replace
them with synthesized highlights grouped by theme — not a raw commit list:
gh release edit vX.Y.Z --notes "$(cat <<'EOF'
## Highlights
- **Feature** — what changed and why it matters.
## Fixes
- Fix: brief description.
EOF
)"
Edge cases