release-gate
Skill14 starsChanged 4 days agoMITView on GitHub
Validates a repository is ready to tag and ship. Use when tagging or cutting a release/version, running a pre-release check, or asking "are we ready to release?" Checks repo hygiene, the local gate, docs, version sync, and build verification.
- Commits and pushes
10 other projects use a version of this.
Adopted by
Most recently taken up by
- kaandgnsh/Claude-Bluetheir own version, first seen Nov 1, 2026
- my-chiefmind/ai-maestrotheir own version, first seen Oct 13, 2026
- jfkconstruct/claude-skillstheir own version, first seen Oct 11, 2026
- imchangchang/dsh-onetheir own version, first seen Oct 11, 2026
- mepotts/agent-operating-kittheir own version, first seen Sep 30, 2026
- nickdesi/FFBB-MCP-Servertheir own version, first seen Sep 23, 2026
Other versions10 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 10
- my-chiefmind/ai-maestro★ 6same name
- nickdesi/FFBB-MCP-Server★ 4same name
- wakqasahmed/ai-engineering-workflow-skills★ 2same name
- wakqasahmed/skills★ 2same name
- CaduS0uza/qa-supreme★ 1same name
- imchangchang/dsh-one★ 1same name
- jfkconstruct/claude-skills★ 0same name
- kaandgnsh/Claude-Blue★ 0same name
- mepotts/agent-operating-kit★ 0same name
- youraioffice/your-ai-office-tools★ 0same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository12 other files it gives its agents.
- .claude/CLAUDE.mdCLAUDE.md
- CLAUDE.mdCLAUDE.md
- cc-release-reviewSkill
- verifySkill
- assisted-logSkill
- code-theorySkill
- code-walkthroughSkill
- downloads-triageSkill
- editorSkill
- release-shipSkill
- release-sweepSkill
- rexSkill
The file
We split this skill into the rules it gives an agent
1 rule. 0 are common, 0 are distinctive, and 1 is very specific to this project.
0
Common
Most of the 7 edited versions we read keep these.
0
Distinctive
This author's own choices. Worth a look.
1
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 210
All checks have already passed and it is time to publish — the user invokes /release-ship
“Common” is measured: kept by at least 6 in 10 of the 7 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Pre-Release Gate
Systematic verification that a repository is ready to tag. Delegates all mechanical checks to a shell script and interprets its output.
Script location
~/.claude/skills/release-gate/scripts/release-check.sh. It resolves the repo root via git rev-parse --show-toplevel and operates from there, so invoke it from anywhere inside the working tree.
Prerequisites
git, jq and gh are always needed. The rest depend on the profile — bun for a Node or
Obsidian repo, go and govulncheck for a Go one, task where a Taskfile supplies the
commands. A missing binary makes its check row fail —
diagnose that as a setup gap, not a real gate failure.
Run
~/.claude/skills/release-gate/scripts/release-check.sh [VERSION]- Omit
VERSIONto check against whatever the repo's own version source reports. This is the normal way to run it — the no-argument form is what drives the two-run pipeline below. - Pass
VERSION(e.g.1.5.0) to verify readiness for a specific target version.
Profiles
Most checks are the same in any repo. Five are not — dependencies, build, tests, audit, and where the version lives — so those come from a profile the script detects from the repo's shape:
| Detected on | Profile | Supplies |
manifest.json with minAppVersion + package.json | Obsidian plugin | bun build/test/audit/outdated; a local gate of frozen install, build and test; version across package.json, manifest.json, versions.json |
package.json alone | Node | the same without the local gate, version from package.json only; build and test only where those scripts exist |
go.mod | Go | go build/go test/govulncheck, outdated via go list -m -u over the modules the build and tests link |
Taskfile.yml with a test: or build: target | Taskfile | task test, and task build when that target exists |
Any repo with package.json and bun.lock gets bun install --frozen-lockfile before the
build row, so the gate runs in a fresh linked worktree with no node_modules. A failed
install fails the build row.
Where no profile names a version source, the newest ## X.Y.Z heading (also ## vX.Y.Z or ## [X.Y.Z]) in
CHANGELOG.md is the version. It is written at release prep, so before prep it names the
shipped version and the gate reports NOT STARTED. A repo with neither still needs a version
argument or a .release-gate.
Profiles compose — a Go repo with a Taskfile takes its build and test commands from the
Taskfile, which is what the fleet actually standardises on. Build and test are looked up
independently: a static site with a build target and no tests gets the first and skips the
second.
A .release-gate file in the repo root overrides any of it. It is sourced as shell:
VERSION_CMD="./cx --version" # prints the version; first semver in stdout wins
VERSION_FILES="cx.js:grep" # path[:spec] cross-checks — jq:<filter> | jqhas | grep
TEST_CMD="task test" # any of DEPS_CMD BUILD_CMD TEST_CMD AUDIT_CMD GATE_CMD
TAG_PREFIX=v # normally detected from the most recent tag
RELEASE_MODE=tag # workflow | gh | tag — see below
DEPLOY_CMD="task deploy" # detected from a deploy target; release-ship runs itRelease mode is how the ship makes the release. workflow means a release.yml
creates it on tag push. gh means gh release create. tag means the annotated tag
and the CHANGELOG are the release, and nothing is created on a forge. Off GitHub (origin
not on github.com) the default is tag, except for a repo with release assets, which
stays gh.
VERSION_CMD has no fallback. A repo whose version the script cannot find is refused
with exit 1 rather than guessed at. Defaulting to the last tag would make check 13
self-satisfying — the version would always equal a tag that exists — and every repo would
report NOT STARTED forever.
Anything a profile leaves empty makes its row SKIP, and skips are counted and named on the result line. A gate that ran no tests must not be readable as "everything passed".
Example output
Pre-Release Gate: 2.1.0 (Taskfile (.release-gate))
==================================================
| # | Check | Status | Details
|----|------------------------|--------|--------
| 1 | Deps current | SKIP | no dependency manifest
| 2 | Clean working tree | PASS |
| 3 | On default branch | PASS | main
| 4 | Up to date with remote | PASS |
| 5 | No open PRs | PASS |
| 6 | Build | SKIP | no build step
| 7 | Tests pass | PASS |
| 8 | Walkthrough snippets | PASS | 27 snippets match
| 9 | Dependency audit | SKIP | no audit command
| 10 | Version consistency | PASS | 2.1.0 across all files
| 11 | CHANGELOG entry | SKIP | no CHANGELOG.md
| 12 | Local gate | PASS | task check on a1b2c3d4
| 13 | Tag available | PASS | v2.1.0 not yet tagged
| 14 | Changes since last tag | INFO | 8 commits since v2.0.0
| 15 | Clean after build | SKIP | no build step
Result: READY (0 failures, 0 warnings, 5 skipped)
Skipped: Deps current, Build, Dependency audit, CHANGELOG entry, Clean after buildExit codes:
0— all pass, ready to tag (Result: READY)1— one or more FAIL rows (Result: BLOCKED), or no version source could be found2— WARN rows only (Result: WARNINGS); not a green light, see below3— the release has not been prepared yet (Result: NOT STARTED); see below
On any FAIL or WARN, the script keeps the per-check log files and prints their location to stderr: Release check logs preserved at: /var/folders/.../tmp.XXXX. Open those logs when the details column points to a path inside.
Where this sits in the pipeline
The gate runs twice per release, answering a different question each time:
- Before prep — the current version is still the released one, so the gate exits
3(NOT STARTED). That is the expected first result, not a failure. - After the prep PR merges — the new version is bumped, changelogged and
walkthrough-current, so the gate should exit
0and the tag can be cut.
This ordering is what keeps the gate and the release from deadlocking: the release
prerequisites want a clean gate, but the gate cannot be clean until the version has been
bumped. Exit 3 is what breaks the cycle.
Interpret the output
Show the script's table to the user as-is. Then:
- If exit 3 (NOT STARTED): The target version is already tagged and nothing new has
been prepared. Do not treat this as a failure and do not try to "fix" checks 10
and 11 — when the version has not been bumped they describe the shipped release and
pass vacuously. Agree the next version with the user (semver: a user-visible behavior
change is a minor, not a patch) and stop. Preparing the release is the user's call to
make: they run
/release-ship, which is user-invoked by design. Do not work through its phases yourself, even though they are readable shell in a file you can open. Any FAIL rows shown alongside are still real — prep covers version, CHANGELOG, walkthrough snippets and a stale build artifact; anything else needs fixing on the prep branch. - If exit 0: Confirm readiness and say what the next step is. Do not tag unprompted.
- If exit 1 (FAIL rows): For each FAIL, suggest a specific fix. Do not offer to tag. Fixes by check:
Clean working tree— commit or stash the modified filesOn default branch—git checkout <default>(details column shows current vs expected). In a linked worktree,git checkout --detach origin/<default>instead: a detached HEAD at origin's default branch passes. Never move the default branch from a worktree (checkout -B,branch -f), because it rewrites the main checkout's HEAD under its indexBuild/Tests pass/Dependency audit— open the log path printed in the details column and work the first error.Walkthrough snippets— the log lists each quoted snippet no longer found in the file its label names. The code moved under the document: regenerate the walkthrough in the prep PR.Version consistency— the details column names each file and what it holds. Bring them into line by whatever the project's bump step is; for an Obsidian plugin that ispackage.jsonplusnpm_package_version=X.Y.Z bun run versionto sync the other two.CHANGELOG entry— add a## <version>section toCHANGELOG.mdLocal gate— "failed": open the log path in the details column and work the first error. "changed files": the gate formatted or regenerated something; commit it on the prep branch and re-run. No CI status is consulted — the repo's own gate is the check. A SKIP means the profile found no gate:task checkwhere it exists, else adefaulttarget whose desc calls it the gate. SetGATE_CMDin.release-gatefor anything else.Tag available— only FAILs now when the version matches an older tag, which is a real conflict: either bump to a new version, orgit tag -d <tag>andgit push --delete origin <tag>if the tag was created in error. If the version is the latest tag the script reports INFO and exits 3 instead — see NOT STARTED above.Clean after build— the details column distinguishes two causes, because the fix differs. "tracked files changed by build": the build rewrote a file check 2 had just certified clean, usually a committed bundle. Almost always that bundle is simply stale, from a dep bump that merged without a rebuild, and a rebuild on the prep branch clears it. Build twice and compare before concluding the build is nondeterministic — that is the rarer cause. "build added untracked files": the build emitted an output nothing tracks — a source map, a metafile, a second stylesheet, typically after a bundler bump. Either add the path to.gitignore, or track it if the project means to ship it.
- If exit 1 with no table (
cannot determine the version): the repo has no detectable version source. Add a.release-gatewithVERSION_CMD, or pass the version as an argument for a one-off. Do not work around it by guessing a version. - If exit 2 (WARN rows): List the warnings and their resolutions. A warning is a check that did not reach a conclusion, not one that passed. Tagging requires exit
0, so each warning has to be cleared and the gate re-run. Typical fixes:Deps current(N outdated) — read-only finding (no files were touched); review the log, update and commit (chore(deps): update) on the prep branch before merging, and re-runUp to date with remote(behind) —git pull --ff-onlyto catch upNo open PRs(N open) — review withgh pr list --base main --state open; merge or close them. Off GitHub this row SKIPs ("not a GitHub remote"), since there are no PRs it can read
Status meanings (from the script)
- PASS — Check succeeded
- WARN — Blocks tagging until resolved; never judge one optional yourself—resolve it or ask
- FAIL — Must be resolved before tagging
- INFO — Informational (commit count, version-not-bumped)
- SKIP — Nothing to check here, or nothing in the profile to check it with. Read the details column: "no CHANGELOG.md" is a fact about the repo, "no test command" is a gap in the profile.
Narrative documents are release-time work
THEORY.md, WALKTHROUGH.md, README.md and CHANGELOG.md are brought current in one pass at
release time, after the code has settled. That is a step in release-ship, not a gate condition:
when the documents were committed, and in which PR, is not something the gate checks.
What the gate does check is the one claim it can verify. Row 8 reads every snippet in
WALKTHROUGH.md labelled `path` — `symbol` and requires it to appear verbatim in that
file, allowing an elided middle marked .... It reads content, never history, so a dependency
bump after the walkthrough cannot fail it, and an edit to quoted code fails it however recently
the document was touched. It does not read the prose. A PASS means the quotes are real, not that
the commentary around them is right.
Do not use when
- All checks have already passed and it is time to publish — the user invokes
/release-ship
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

