Release Checklist
Runner note: From the repo root run
export MCP_RUNNER="$PWD/runner"and use$MCP_RUNNER <command>for every shell command listed below unless the step explicitly says otherwise. This keeps the guardrails active even when the checklist jumps between directories.
Helper script: You can run
./scripts/release.sh <phase>(gates | artifacts | publish | smoke | tag | all) to execute the steps below with the runner by default. It stops on first error; rerun the next phase after fixing issues.
No-warning policy: Every command below must finish without warnings (Oxfmt, Oxlint, tsgo, Vitest, npm pack, etc.). Fix issues before continuing; releases cannot ship with outstanding warnings.
#Definition of “released”
Shipping a release means all of:
- Tag pushed (
v<version>). - npm published (
mcporter@<version>visible vianpm view mcporter version). - GitHub release published for the tag with assets + checksums.
- Homebrew tap updated (and verified) after assets propagate.
- Update version in package.json and src/runtime.ts.
- Run pnpm install to refresh the lockfile if dependencies changed.
- pnpm check (zero warnings allowed; abort immediately on any error)
- pnpm test (must finish with 0 failed; if Vitest prints any red FAIL lines or a non-zero exit code, stop and fix it before proceeding)
- pnpm build
- pnpm build:bun
- tar -C dist-bun -czf dist-bun/mcporter-macos-arm64-v<version>.tar.gz mcporter
- shasum -a 256 dist-bun/mcporter-macos-arm64-v<version>.tar.gz | tee dist-bun/mcporter-macos-arm64-v<version>.tar.gz.sha256
- npm pack --pack-destination /tmp && mv /tmp/mcporter-<version>.tgz . # keep the real tarball
- shasum mcporter-<version>.tgz > mcporter-<version>.tgz.sha1 && shasum -a 256 mcporter-<version>.tgz > mcporter-<version>.tgz.sha256
- Verify git status is clean.
- git commit && git push.
- pnpm publish --tag latest (the runner already has npm credentials configured, so you can run this directly in the release shell; bump
timeout_msif needed because prepublish re-runs check/test/build and can take several minutes.) npm view mcporter version(andnpm view mcporter time) to ensure the registry reflects the new release before proceeding. If the new version isn’t visible yet, wait a minute and retry—npm’s replication can lag briefly.- Sanity-check the “one weird trick” workflow from a completely empty directory (no package.json/node_modules) via:
- Draft the GitHub release notes using this template (copy/paste and edit). Title the release
mcporter v<version>(project name + version) to keep GitHub’s releases list consistent.
``bash rm -rf /tmp/mcporter-empty && mkdir -p /tmp/mcporter-empty cd /tmp/mcporter-empty # run this without the runner because we are outside the repo and npx handles its own logging npx mcporter@<version> generate-cli "npx -y chrome-devtools-mcp" --compile ./chrome-devtools-mcp --help | head -n 5 `` Only continue once the CLI compiles and the help banner prints.
```markdown ## Highlights
- <top feature>
- <second feature>
- <bugfix or UX callout>
SHA256 (mcporter-macos-arm64-v<version>.tar.gz): <sha from step 8> SHA256 (mcporter-<version>.tgz): <sha from npm pack> ```
Then create the GitHub release for tag v<version> and upload all assets:
mcporter-macos-arm64-v<version>.tar.gzmcporter-macos-arm64-v<version>.tar.gz.sha256(from step 8; add a.sha256file)mcporter-<version>.tgz(fromnpm pack)mcporter-<version>.tgz.sha1andmcporter-<version>.tgz.sha256
Double-check the uploaded checksums match your local files.
- Tag the release (git tag v<version> && git push --tags).
- Post-tag housekeeping: add a fresh "Unreleased" stub to CHANGELOG.md (set to "- Nothing yet.") and start a new version section for the just-released patch if it isn’t already recorded.
After the release is live, always update the Homebrew tap and re-verify both installers. The tap formula should install the npm .tgz, not the Bun-compiled macOS tarball, because generate-cli --compile needs the installed package tree so Bun can resolve mcporter, commander, and related dependencies when compiling from an empty directory. Keep the macOS tarball on the GitHub release as a direct binary asset, but point Homebrew at mcporter-<version>.tgz.
- Update
steipete/homebrew-tap->Formula/mcporter.rbwith:
- URL
https://github.com/steipete/mcporter/releases/download/v<version>/mcporter-<version>.tgz - SHA256 from
mcporter-<version>.tgz.sha256 require "language/node",depends_on "node", andsystem "npm", "install", *std_npm_args, "--min-release-age=0"so same-day releases with fresh npm dependencies can install immediately.
Refresh the tap README highlight so Homebrew users see the new version callout.
- Commit and push the tap update.
- Refresh and reinstall from the real tap:
- Run a Homebrew-installed empty-directory compile smoke:
- Install the npm package globally (or leave it to npx) and verify that path too:
- If installing on another Mac, repeat the real tap reinstall and compile smoke there:
``bash brew update brew reinstall steipete/tap/mcporter brew test steipete/tap/mcporter /opt/homebrew/bin/mcporter --version ``
``bash rm -rf /tmp/mcporter-brew-smoke && mkdir -p /tmp/mcporter-brew-smoke cd /tmp/mcporter-brew-smoke /opt/homebrew/bin/mcporter generate-cli "npx -y chrome-devtools-mcp" --compile ./chrome-devtools-mcp --help | head -n 5 ``
``bash npm install -g mcporter@<version> mcporter --version npx --yes mcporter@<version> --version ``
``bash brew update brew reinstall steipete/tap/mcporter /opt/homebrew/bin/mcporter --version ``