Maintainers only. A release is a tag; the workflow in .github/workflows/release.yml does the rest.
- The version is
[workspace.package] versioninCargo.toml;Cargo.lock(thecomparegraphentry),server.json,.claude-plugin/plugin.json,.claude-plugin/marketplace.jsonandnpm/package.json(its own version and its fiveoptionalDependencies) repeat it, anddocs/catalog.jsoncarries it (comparegraph catalog > docs/catalog.jsonregenerates it). CI checksserver.json;cargo testchecks the rest. Bump them in the commit that will be tagged; every release job exits 4 when the tag disagrees. - Date the section in
CHANGELOG.md(## [x.y.z] - YYYY-MM-DD), leave an empty## [Unreleased]above it, and update the two link lines at the bottom. cargo test -p comparegraphandcargo clippy -p comparegraph --tests -- -D warningsgreen; theciworkflow green onmainfor that commit.- Move the README's read-first install block to the new tag: the script URL (
.../comparegraph/vX.Y.Z/scripts/install.sh) andCOMPAREGRAPH_VERSION=vX.Y.Z.
git tag -a vX.Y.Z -m "vX.Y.Z"
git push origin vX.Y.Zbuild: five jobs, one per platform (linux-x64, linux-arm64, darwin-arm64, darwin-x64, win32-x64), each on a runner of that platform. Each checks the version, builds with--locked, strips the Linux binaries, and uploads the binary with its.sha256. Windows builds withclang-cl: one grammar's C build passes a GCC-style warning flag thatclrejects.release: downloads the five binaries, writesSHA256SUMS, checks it, and publishes a GitHub release with the binaries, the sums and generated notes.publish-npm: runs only when the repository variableNPM_PUBLISHistrue. Checksnpm/package.jsonagainst the tag (exit 4), takes the released binaries from the same artifacts (checksums verified), builds six packages withnpm/build.mjs, publishes the five platform packages and then the wrapper. Authentication: the repository secretNPM_TOKEN(a granular npm token with publish rights on the@massrelayaiscope; npm caps its lifetime at 90 days, so it is renewed by setting the secret again) while it is set; with the secret empty, npm trusted publishing through OIDC, once the maintainer has registered this workflow on each of the six packages.publish-registry: downloads a pinnedmcp-publisher(checksum verified), checks thatserver.jsoncarries the tag's version, validates it, authenticates through GitHub OIDC (the registry grants this repository's owner theio.github.MassRelayAI/*namespace) and publishes. It first waits (up to 15 minutes) until npm serves the versionserver.jsonnames, becausepublish-npmruns in parallel and the registry checks npm. The entry carries the repository, not a package: the install script is the distribution.
.github/workflows/dependabot-automerge.yml runs after ci completes on a Dependabot branch.
- A patch or minor bump merges itself (
--rebase --delete-branch) onceciis green on the PR's current head. The update type is read from theupdated-dependenciesblock in Dependabot's verified commit message. - A major bump (or a group containing one) gets one comment and waits. Merge it by hand after reading it:
gh pr merge <n> --rebase --delete-branch. - A red or cancelled
cirun merges nothing, and neither does a green run for a head that has since moved. - The merge is made with
GITHUB_TOKEN, and GitHub starts no workflow for events that token makes, socidoes not run on the merge commit. That commit was green on the PR's own run; the next push tomainrunscion it.
@massrelayai/comparegraph is a launcher; the binary comes from one of five platform packages
(@massrelayai/comparegraph-<platform>) that npm installs as optional dependencies. npm/build.mjs <version> --bins <dir> --out <dir> builds them from the release binaries; scripts/test/npm-package.test.mjs builds, packs, installs and runs them.
One-time steps for the maintainer:
- Create the
massrelayaiorganisation on npmjs.com. - Make the six package names exist and trust this repository. A package must exist before npm lets you configure a trusted
publisher on it, so either publish the six packages by hand once (
node npm/build.mjs <version> --bins <dir> --out dist-npm, thennpm publish --access publicin each directory, platform packages first), or use whatever npmjs.com offers for configuring a publisher on a name not yet published. Then, for each of the six packages, add a trusted publisher: GitHub Actions, repositoryMassRelayAI/comparegraph, workflow filenamerelease.yml. - In the repository settings (Actions, Variables) set
NPM_PUBLISHtotrue. Until then thepublish-npmjob is skipped and a release is unaffected.
The job needs npm 11.5.1 or later and Node 22.14 or later (it installs the latest npm); provenance is attached automatically for a public repository.
After the first successful npm publish, add this entry to server.json (not before: mcp-publisher publish checks
mcpName on the live npm package and fails the registry step while the package is absent):
"packages": [
{
"registryType": "npm",
"registryBaseUrl": "https://registry.npmjs.org",
"identifier": "@massrelayai/comparegraph",
"version": "<version>",
"runtimeHint": "npx",
"transport": { "type": "stdio" },
"packageArguments": [{ "type": "positional", "value": "mcp" }]
}
]The version there is the released one, so it moves with every release like the other version files.
The install scripts (scripts/install.sh, scripts/install.ps1) read releases/latest/download/, so they serve the new
version as soon as the release exists; nothing in them is versioned. The shared Homebrew tap (MassRelayAI/homebrew-tap)
updates its formula from the latest release on a schedule and on demand (its own workflow, no secret).
The release job signs a build-provenance attestation (actions/attest-build-provenance, Sigstore, this workflow's OIDC
identity) over every file it uploads that matches dist/comparegraph-*: the five binaries and their per-file .sha256
files, plus SHA256SUMS. The attestation lives in GitHub's attestation store, not as a release asset. To verify a download
(needs the GitHub CLI, version 2.49 or later):
gh attestation verify comparegraph-linux-x64 -R MassRelayAI/comparegraphThe first attested release is v0.1.2; earlier releases carry checksums only.
deny.toml drives the deny job in ci.yml (cargo deny --locked check): licence allowlist, advisories, bans and
sources. An ignore entry in [advisories] carries its reason and is removed when the lock moves past the flaw.
On a clean machine:
curl -fsSL https://raw.githubusercontent.com/MassRelayAI/comparegraph/main/scripts/install.sh | sh
comparegraph --versionIn Claude Code: /plugin install comparegraph --marketplace MassRelayAI/comparegraph, then comparegraph doctor in a
workspace from the agent. Run the tap's update workflow and brew install massrelayai/tap/comparegraph. Look for
io.github.MassRelayAI/comparegraph at https://registry.modelcontextprotocol.io/v0/servers?search=comparegraph. Then move
the changelog on: a new empty ## [Unreleased] is already there.