Releasing - visubramaniam/vsp360-mcp GitHub Wiki

A release is a version bump merged to main, then a v* tag on the merged commit. The Release workflow does the rest.

What a release produces

Output Where
Claude Desktop extension (.mcpb) GitHub release
Standalone archives for macOS, Linux and Windows on x64 and arm64, with Node.js 24 GitHub release
npm package (.tgz) GitHub release and the npm registry
SHA256SUMS GitHub release
Container image for linux/amd64 and linux/arm64 ghcr.io/visubramaniam/vsp360-mcp and Docker Hub, tagged <version> and latest

Steps

  1. Prepare a release branch from main:
    • npm version <x.y.z> --no-git-tag-version
    • Rename the changelog's Unreleased section to <x.y.z> โ€” <date>.
    • Update the version examples in INSTALL.md, README.md and README.docker.md.
    • Leave the Claude plugin on the previous version. Its lockfile can only name a version that's already on npm, so a follow-up pull request moves it (step 7). tests/unit/plugin.test.mjs allows the plugin to trail package.json.
    • Run npm test.
  2. Open a pull request into main in the release's milestone, and merge it once CI passes. Use Rebase and merge, unless main was merged into the branch: rebasing replays each commit and drops the merge commit, so GitHub reports conflicts that the merge already resolved. Use Squash and merge then.
  3. Tag the merged commit and push the tag:
git fetch origin && git tag v<x.y.z> origin/main && git push origin v<x.y.z>
  1. Watch the Release workflow. Its jobs:

    • packages checks that the tag matches package.json, runs the tests, builds every package and attaches them to the GitHub release. It creates the release from the changelog section if it doesn't exist.
    • npm publishes the release's .tgz to npm, after checking it against SHA256SUMS. It skips versions already on npm.
    • docker builds the multi-arch image and pushes it to ghcr.io, and to Docker Hub when its secrets are set.
    • windows downloads the release's Windows zips on GitHub's Windows x64 and arm64 machines, checks them against SHA256SUMS and runs tests/smoke/package-smoke.mjs with their own Node.js. Run the Windows packages workflow by hand to test any earlier release.
  2. Check the result:

    • npm may hold a new version in Validating for a few minutes before it appears. npm view vsp360-mcp@<x.y.z> returns 404 until then, even though the npm job's log says + vsp360-mcp@<x.y.z>.
    • Check that npm view vsp360-mcp shows the new latest with provenance.
    • Check that both image tags resolve to the same digest.
  3. Update the wiki, milestones and project board. The wiki is a separate repository, so release pull requests don't change it.

    • Wiki: the version examples (Installation, Connecting Claude), the Roadmap, and any page describing behaviour the release changed.
    • Close the release's milestone, with a description of what shipped and the release link.
    • On the project board, mark the release's items Done, and add its pull requests with their Target release.
  4. Move the plugin to the new version in a follow-up pull request, once npm serves it: version in plugin/.claude-plugin/plugin.json and plugin/package.json, the exact vsp360-mcp dependency, and a regenerated plugin/package-lock.json. The plugin listing in Anthropic's directory follows main, so it picks up the change by itself.

One-time setup

What Where
npm trusted publisher npmjs.com โ†’ vsp360-mcp โ†’ Settings โ†’ Trusted Publisher โ†’ GitHub Actions: user visubramaniam, repository vsp360-mcp, workflow release.yml, no environment
Docker Hub (optional) Repository secrets DOCKERHUB_USERNAME and DOCKERHUB_TOKEN, a Docker Hub personal access token with Read & Write access
ghcr.io Nothing: the workflow uses its own token. The package must be public, under Packages โ†’ vsp360-mcp โ†’ Package settings.

No npm token is stored anywhere. npm trusts the workflow through OIDC and adds a provenance attestation to each version.

When something fails

  • Tag doesn't match package.json: the packages job stops. Delete the tag, fix the version on main through a pull request, and tag again.
  • npm job fails with 404: the trusted publisher is missing or doesn't match, e.g. it names an environment the job doesn't use. Fix it on npmjs.com, then rerun the failed job: gh run rerun <run-id> --failed. The rerun publishes the same .tgz.
  • docker job fails at login: check the Docker Hub secrets. The ghcr.io push needs no secrets.
  • windows job fails in the smoke test itself: a re-run of the failed jobs checks out the tag, so it fails the same way. Fix tests/smoke/package-smoke.mjs on main, then run the Windows packages workflow by hand with the tag. It uses main's smoke test against the release's zips. This happened in 0.1.22: the smoke test's http:// mock needed VSP360_ALLOW_HTTP=true.
  • packages fails the Node.js signature check: a new Node.js releaser may have signed NODE_VERSION. Move NODE_KEYRING in scripts/package.mjs to a newer commit of nodejs/release-keys.
  • Rebuilding an existing tag: run the workflow by hand with that tag. This replaces the GitHub release's files and the images; npm is skipped because the version already exists. npm versions can't be replaced.

Building packages locally

npm run package

Use --only npm,mcpb,standalone and --targets darwin-arm64,... to build fewer, e.g. npm run package -- --only standalone --targets darwin-arm64. The Node.js runtimes are downloaded once into release/.cache and checked against nodejs.org's published SHA-256 sums. The signature of those sums is checked with gpgv (GnuPG) and the Node.js release keys. Without gpgv, a local build prints a warning and goes on; in CI it fails.

โš ๏ธ **GitHub.com Fallback** โš ๏ธ