Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Cut a skill-guard release — run preflight checks, determine the next version from conventional commits, push, then merge the release-please PR and verify the published binaries. Use when asked to release, cut/publish a version, or ship a release.
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-04 | ✗→✓ | ▲ Improved | 58% | 0% |
| case-05 | ✗→✓ | ▲ Improved | 78% | 0% |
| case-06 | ✗→✓ | ▲ Improved | -3% | 0% |
| case-09 | ✗→✓ | ▲ Improved | 216% | 0% |
| case-13 | ✗→✓ | ▲ Improved | 114% | 0% |
Releases are driven by release-please + GoReleaser (.github/workflows/release.yml). You never create tags or GitHub Releases by hand. The flow is:
conventional commits on main
→ release-please opens/updates a "release PR" (version bump + CHANGELOG)
→ merging that PR creates the vX.Y.Z tag + GitHub Release
→ the goreleaser job attaches cross-platform binaries + checksums.txtAll GitHub interaction uses gh. If gh is unauthenticated, export the keychain token per-command: GH_TOKEN=$(printf "protocol=https\nhost=github.com\n" | git credential fill | sed -n 's/^password=//p') gh ... Never print the token.
Branch protection: main is covered by the protect-main ruleset (direct pushes, force pushes, and deletion are blocked; PRs need 1 approval). Only the repo owner (admin role) bypasses it — that's who this skill assumes is running it, since step 3 pushes to main directly and step 4 merges the release PR without a review. If git push origin main is rejected with a ruleset/protected-branch error, the invoking user is not an admin bypass actor: push a feature branch and open a PR instead, and get an approval before merging — don't try to work around the ruleset.
Run from the repo root:
git status --short — working tree must be clean, or contain only the changes beingreleased. Never release with unrelated uncommitted edits mixed in.
main and synced: git fetch && git status -sb shows no divergence from origin/main.gofmt -l . — empty output.go vet ./... — clean.go test ./... — all pass.go run ./cmd/skill-guard scan testdata/malicious exits 1; go run ./cmd/skill-guard scan testdata/benign exits 0.
go run ./cmd/skill-guard scan .claude/skills/sg-release must pass —skill-guard's own skills must survive skill-guard.
If any step fails, stop and fix before proceeding — the release workflow re-runs tests and will refuse to publish otherwise.
release-please computes the version; your job is to predict it, sanity-check it, and override it only when justified.
List unreleased commits:
shlast=$(git describe --tags --abbrev=0 2>/dev/null || echo "") git log ${last:+$last..}HEAD --pretty='%s'
Bump rules (from release-please-config.json — keep this table in sync if that changes):
| Commits since last tag | Pre-1.0 bump | Post-1.0 bump | |---|---|---| | fix: only | patch | patch | | any feat: | patch | minor | | any ! / BREAKING CHANGE: | minor | major |
Overrides — only with explicit intent (e.g. first release, or graduating to 1.0.0): add an empty commit with a Release-As footer:
shgit commit --allow-empty -m "chore: release X.Y.Z" -m "Release-As: X.Y.Z"
Commits that are not conventional-commit formatted are ignored by release-please. If the work that must be released only has non-conventional messages, it won't trigger a release PR — fix by adding a properly-typed empty commit describing the change.
git push origin main.release workflow run on main to finish:gh run list --workflow=release --branch=main --limit=1 then gh run watch <id>.
gh pr list --search "chore(main): release" --state open.It is labeled autorelease: pending.
doesn't, understand why before continuing (mis-typed commit? missing footer?).
gh pr checks <number>.If no release PR appears: check the workflow run logs. The most common cause is the repo setting "Allow GitHub Actions to create and approve pull requests" being disabled (Settings → Actions → General → Workflow permissions).
Merge the release PR (squash keeps history clean):
shgh pr merge <number> --squash
Then watch the resulting release workflow run on main — this time the release-please job creates the tag + GitHub Release and the goreleaser job must also run: gh run watch <id>.
gh release view vX.Y.Z — must exist, with changelog notes and 7 assets:5 archives (linux/darwin × amd64/arm64 .tar.gz, windows-amd64 .zip) + checksums.txt + source archive behavior varies; the 6 named assets are what matters.
sh VERSION=vX.Y.Z INSTALL_DIR=$(mktemp -d) sh install.sh It must print Installed: skill-guard X.Y.Z — this proves asset naming, checksums, and the ldflags version injection all line up.
gh run view <id> --log-failed.Fix, then re-run the job (gh run rerun <id> --failed); GoReleaser release.mode: keep-existing makes re-runs safe.
Release-As footer.
force a refresh by re-running the release workflow.
Other measured skills in the registry, with their headline benchmark lift.