release-and-publish
Skill0 starsChanged 6 months agoApache-2.0View on GitHub
Ship a release end-to-end across every registry the project targets (npm, MCP Registry, GitHub Releases for `.mcpb` bundles, GHCR). Runs the final verification gate, pushes commits and tags, then publishes to each applicable destination. Assumes git wrapup (version bumps, changelog, commit, annotated tag) is already complete — this skill is the post-wrapup publish workflow. Retries transient network failures on publish steps; halts with a partial-state report when retries are exhausted or the failure is terminal.
- Reads credentials
- Installs packages
- Commits and pushes
In this repository31 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- add-app-toolSkill
- add-promptSkill
- add-resourceSkill
- add-serviceSkill
- add-testSkill
- add-toolSkill
- api-authSkill
- api-canvasSkill
- api-configSkill
- api-contextSkill
- api-errorsSkill
- api-linterSkill
- api-mirrorSkill
- api-servicesSkill
- api-telemetrySkill
- api-testingSkill
- api-utilsSkill
- api-workersSkill
- code-simplifierSkill
- design-mcp-serverSkill
- field-testSkill
- git-wrapupSkill
- maintenanceSkill
- polish-docs-metaSkill
- report-issue-frameworkSkill
- report-issue-localSkill
- security-passSkill
- setupSkill
- tool-defs-analysisSkill
The file
Show its rules and text
We split this skill into the rules it gives an agent
13 rules. About 0 are common, 3 are distinctive, and 10 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈3
Distinctive · estimate
This author's own choices. Worth a look.
10
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 25
If any are missing, halt and tell the user to finish wrapup first.
- Distinctive: line 53
If retries are exhausted, or the failure matches none of the transient patterns, halt and report:
- Very specific: line 66
Read package.json → capture version.
- Very specific: line 72
If working tree is dirty or HEAD isn't on v<version>, halt.
- Very specific: line 76
All three must succeed. Check package.json scripts for test:all.
- Distinctive: line 88
Use your git tools to push the branch commits first, then push tags to origin.
- Very specific: line 109
Only if server.json exists at the repo root (otherwise skip).
- Very specific: line 115
If publish-mcp isn't defined in package.json, add it permanently (one-time setup, macOS):
- Very specific: line 158
Always latest (powers the install badge): https://github.com/<OWNER>/<REPO>/releases/latest/download/<name>.mcpb
- Very specific: line 160
If server.json includes an MCPB packages[] entry, its identifier should match this URL and fileSha256 should match shasum -a 256 <bundle> — …
- Very specific: line 168
Only if Dockerfile exists at the repo root (otherwise skip).
- Very specific: line 182
If the project uses a non-GHCR registry or a custom image name, respect the project's convention.
- Very specific: line 204
If any check fails, halt and report which destination is unreachable.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Preconditions
This skill runs after git wrapup. By the time it's invoked:
- Pre-wrapup verification is done (
field-test,security-pass,polish-docs-metaas applicable) package.jsonversion is bumpedchangelog/<major.minor>.x/<version>.mdis authoredCHANGELOG.mdis regenerated- README and every version-bearing file is in sync
- Release commit (
chore: release v<version>) exists - Annotated tag (
v<version>) exists locally - Working tree is clean
If any are missing, halt and tell the user to finish wrapup first. Do not attempt to redo wrapup work from inside this skill.
Failure Protocol
Steps 3–7 are network-bound. For those, retry transient failures up to 2 times with short backoff (~5 s before the first retry, ~15 s before the second) before halting. All other steps halt on the first non-zero exit — they're deterministic and a second attempt won't change the outcome.
Retry on transient patterns
Match stderr (case-insensitive) against any of these — if matched, the failure is almost always a network blip; retry:
integrity check failed/IntegrityCheckFailed— corrupt tarball during downloadECONNRESET/EAI_AGAIN/ETIMEDOUT/ENOTFOUND— network layerconnection reset/connection refused— transport bliptimed out/request timeout— server or network timeout- HTTP
502/503/504— transient registry error
Before retrying docker buildx --push (step 7), run docker builder prune -f to drop any cached corrupt layer. Skip this extra step for other retries.
Never retry on idempotent-success signals
These mean the step already succeeded on a prior run — treat as success and proceed to the next step:
- npm (
bun publish):version already exists,You cannot publish over the previously published versions - MCP Registry (
mcp-publisher publish):cannot publish duplicate version - GitHub Release (
gh release create):release already exists— fall back togh release upload --clobber(see step 6)
Halt fallback
If retries are exhausted, or the failure matches none of the transient patterns, halt and report:
- Which step failed
- The exact error output
- Retry count attempted (0 for terminal errors, 2 for exhausted retries)
- Which destinations already received the release (npm published? tag pushed? MCP Registry? GitHub Release with
.mcpb? GHCR?) — the partial state across destinations
The user fixes locally and re-invokes. On re-invocation, already-published destinations hit the idempotent-success signal and skip naturally — no manual step-skipping required.
Steps
1. Sanity-check wrapup outputs
Read package.json → capture version. Then use your git tools to verify:
- Working tree is clean — no uncommitted changes
- HEAD is tagged
v<version>— matches thepackage.jsonversion - Current branch name — note it for step 3
If working tree is dirty or HEAD isn't on v<version>, halt.
2. Run the verification gate
All three must succeed. Check package.json scripts for test:all; if absent, fall back to test:
bun run devcheck
bun run rebuild
bun run test:all # or `bun run test` if no test:allAny non-zero exit → halt with the failing command's output.
3. Push to origin
Use your git tools to push the branch commits first, then push tags to origin. If the remote rejects either push, halt.
4. Publish to npm
bun publish --access publicbun publish uses whatever npm auth the user has configured in ~/.npmrc. If 2FA is enabled on the npm account, the command will prompt for an OTP or open a browser — that's expected; the user completes it interactively.
Friction reducers (optional, configure once):
| Option | How |
| npm granular access token with "Bypass 2FA for publish" | Generate at npmjs.com → replace _authToken in ~/.npmrc → no OTP prompt at all |
1Password CLI TOTP injection (requires brew install --cask 1password-cli + signed-in op) | bun publish --access public --otp="$(op item get 'npm' --otp)" |
Halt on publish error other than "version already exists" (which means this step already ran).
5. Publish to MCP Registry
Only if server.json exists at the repo root (otherwise skip). Note: server.json (MCP Registry metadata) and manifest.json (MCPB bundle manifest, step 6) are independent — a project may have either, both, or neither.
bun run publish-mcpIf publish-mcp isn't defined in package.json, add it permanently (one-time setup, macOS):
"publish-mcp": "mcp-publisher login github -token \"$(security find-generic-password -a \"$USER\" -s mcp-publisher-github-pat -w)\" && mcp-publisher publish"Prereq: a GitHub PAT with read:org + read:user scopes stored in Keychain under the service name mcp-publisher-github-pat:
security add-generic-password -a "$USER" -s mcp-publisher-github-pat -w
# paste PAT at the silent promptHalt on any publisher error other than "cannot publish duplicate version".
6. Create GitHub Release
For all projects (including those without manifest.json):
bun run release:githubThe script (scripts/release-github.ts) handles everything in one command:
- Reads
versionfrompackage.json - Derives the tag subject via
git for-each-ref refs/tags/v<version> - Runs
gh release create v<version> --verify-tag --notes-from-tag --title "v<version>: <subject>" - Attaches
dist/*.mcpbwhenmanifest.jsonexists (skip thebun run bundlestep first if not already built — see below) - On "release already exists" (re-invocation after a prior partial run): uploads/clobbers the
.mcpbasset (if applicable) and patches the title viagh release edit
If manifest.json exists, build the bundle first so the asset is ready:
bun run bundle # produces dist/<name>.mcpb (stable filename, no version)
bun run release:github # attach + release in one stepThe stable filename matters: it lets the README "Install in Claude Desktop" badge point at releases/latest/download/<name>.mcpb and always resolve to the most recent release. The bundle script in the templates outputs dist/{{PACKAGE_NAME}}.mcpb for this reason.
Deterministic download URLs (for MCPB projects):
- Pinned to this version:
https://github.com/<OWNER>/<REPO>/releases/download/v<VERSION>/<name>.mcpb - Always latest (powers the install badge):
https://github.com/<OWNER>/<REPO>/releases/latest/download/<name>.mcpb
If server.json includes an MCPB packages[] entry, its identifier should match this URL and fileSha256 should match shasum -a 256 <bundle> — keep these in sync during wrapup, not here.
Framework note: mcp-ts-core has no manifest.json — the bundle attach path is skipped automatically. Skip the Docker build/push step too (this framework package is consumed via npm, not as a container image).
Halt on any non-zero exit not handled by the script's built-in fallback.
7. Publish Docker image
Only if Dockerfile exists at the repo root (otherwise skip).
Derive:
OWNER/REPOfrom the origin remote URL — use your git tools to read it; strip.git, handle bothhttps://github.com/<owner>/<repo>andgit@github.com:<owner>/<repo>formsVERSIONfrompackage.json(step 1)
docker buildx build --platform linux/amd64,linux/arm64 \
-t ghcr.io/<OWNER>/<REPO>:<VERSION> \
-t ghcr.io/<OWNER>/<REPO>:latest \
--push .If the project uses a non-GHCR registry or a custom image name, respect the project's convention. If push fails with a 401/403, prompt the user to authenticate (echo $GITHUB_TOKEN | docker login ghcr.io -u <OWNER> --password-stdin) and retry. Halt on build failure or non-auth push failure.
8. Report the deployed artifacts
Print clickable URLs for every destination that succeeded:
- npm:
https://www.npmjs.com/package/<package.json#name>/v/<version> - MCP Registry:
https://registry.modelcontextprotocol.io/v0.1/servers/<mcpName>/versions/<version>—mcpNameis thenamefield fromserver.json(URL-encode the/as%2F) - GitHub Release:
https://github.com/<OWNER>/<REPO>/releases/tag/v<VERSION>(with.mcpbasset attached) - GHCR:
ghcr.io/<OWNER>/<REPO>:<VERSION>
Skip any destination that was skipped in its step.
9. Verify artifacts are reachable
Confirm each published artifact is actually live — don't rely on a successful push exit code alone. For each destination that succeeded:
- npm:
npm view <package.json#name>@<version> version— must return the version string - MCP Registry:
curl -s "https://registry.modelcontextprotocol.io/v0.1/servers/<mcpName>/versions/<version>"— must return HTTP 200 withserver.versionmatching<version>(mcpNameis thenamefield fromserver.json; URL-encode/as%2F). The search endpoint (/v0.1/servers?search=) paginates and may not include the latest version for packages with many releases — always use the direct version lookup. - GitHub Release:
gh release view v<VERSION> -R <OWNER>/<REPO> --json assets --jq '.assets[].name'— must list the.mcpbfile - GHCR: fetch an anonymous bearer token, then
curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Bearer $TOKEN" "https://ghcr.io/v2/<OWNER>/<REPO>/manifests/<VERSION>"— must return HTTP 200
If any check fails, halt and report which destination is unreachable. A successful docker push or bun publish exit code does not guarantee the artifact is queryable — registry propagation delays, auth scoping, and partial failures all exist.
Checklist
- Working tree clean; HEAD tagged
v<version>; current branch name noted for push bun run devcheckpassesbun run rebuildsucceedsbun run test:all(ortest) passes- Commits pushed to origin
- Tags pushed to origin
bun publish --access publicsucceedsbun run publish-mcpsucceeds (ifserver.jsonpresent)bun run bundle(ifmanifest.jsonpresent) +bun run release:githubsucceeds- Docker buildx multi-arch push succeeds (if
Dockerfilepresent) - All published artifacts verified reachable (npm, MCP Registry, GH Release asset, GHCR manifest)
- On re-invocation: idempotent-success signals recognized for already-published destinations
- Deployed artifact URLs reported to the user
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.

