Maintainer release procedure
This is the release runbook for the publicinvariantcad npm package, its
GitHub release, and the live documentation. Every release flows through
GitHub: a reviewed release pull request, then an automated, approval-gated
publication from the merged commit. Nothing is published from a workstation.
Everyday changes
Every change reachesmain through a pull request. Protected main requires:
- CI on Node 22.13, 24, and 26 plus the Chromium production-bundle smoke test;
- CodeQL code scanning;
- Socket pull-request alerts for dependency and supply-chain risk;
- a Greptile review, configured by the repository’s
.greptile/rules; and - every review conversation resolved.
## [Unreleased] in CHANGELOG.md.
Ordinary pull requests never change the package version.
Greptile reviews maintainer pull requests automatically, on open and on every
push. It has not reviewed Dependabot pull requests automatically; comment
@greptileai on a bot-authored pull request to request the required review.
Preparing a release
- In GitHub Actions, run Prepare release on
mainwith the new stable version, such as0.2.0. Locally,pnpm release:prepare 0.2.0performs the same file preparation. - The workflow moves the
Unreleasedchangelog entries under a dated## [0.2.0]heading, updates the comparison links, bumpspackage.json, addsdocs/releases/0.2.0.mdand its navigation entry, verifies the result withpnpm release:metadata:check 0.2.0, and pushesrelease/v0.2.0. - Open the release pull request from the link in the workflow summary. Opening it yourself, rather than with the workflow token, starts every required check and review.
- In that pull request, curate
docs/releases/0.2.0.mdinto release notes; its body becomes the GitHub release. Link other documentation pages with the same site-relative or file-relative targets as any other page; the GitHub release receives them as absolute links to the hosted site.pnpm release:metadata:check 0.2.0rejects a relative link that leaves the documentation site, such as../../CHANGELOG.md; link to repository files with an absolute GitHub URL instead. Update release status text such as the README status line, roadmap, support matrix, and supported versions inSECURITY.md. Review theetc/api/diff since the previous release. - Merge when every required check passes and every thread is resolved.
Automated publication
Every push tomain runs .github/workflows/release.yml. A push is a release
only when its package.json version differs from the version main had
before the push, which happens only when a release pull request merges by
merge commit, squash, or rebase. For a release the workflow:
- checks release metadata and runs
pnpm release:check: strict TypeScript, source correctness and format hygiene, public-entrypoint and API-report consistency, package metadata/types, clean-consumer installation of the packed tarball, checked coverage, the six-case reference benchmark, dependency audit, Mintlify validation and links, and the production browser bundle; - waits for approval in the
npmenvironment, then publishes that exact smoke-tested tarball through npm trusted publishing with provenance. It refuses a version older than one already on npm, so npm’slatestdist-tag never moves backwards; - confirms through npm’s SLSA provenance that the registry package was built from this repository, workflow, and commit, and, when this attempt published it, that the registry serves the same tarball integrity;
- creates the annotated
v<version>tag on the release commit and the GitHub release from the body ofdocs/releases/<version>.md, without its YAML frontmatter and with documentation links made absolute (pnpm exec tsx scripts/release.ts notes <version>prints it), marking it latest only when it is the highest stable tag; and - fast-forwards the
docs-livebranch, from which the hosted Mintlify site deploys, to the release commit, never moving it backwards.
docs-live. Both skip
work already done, refuse a tag that points elsewhere, and refuse an npm
version whose provenance names another commit. The workflow deliberately has
no manual trigger: a fresh run on a later main commit could otherwise release
unrelated changes under the stuck version. GitHub allows re-runs for 30 days;
after that, release a new patch version instead.
Published npm versions are immutable. If verification uncovers a defect, do not
attempt to replace the version; fix it and release a new patch version.
Live documentation
The hosted documentation deploys fromdocs-live, which only the release
workflow advances, so readers see documentation for the latest npm release.
Documentation on main is still validated by CI on every pull request. A
documentation-only correction for the current release ships with the next
release; for an urgent fix, release a patch version.
One-time npm bootstrap
The one-time bootstrap completed withinvariantcad@0.1.0 on 2026-07-22.
The public registry artifact, provenance, owner, files, CLI, entry points,
geometry kernels, and latest tag were independently verified. The release
workflow does not read or require a registry token.
Never commit an npm token or copy it into a workflow file, shell history, issue,
release note, or CI log. The npm-side bootstrap token must also be revoked.
The package’s npm trusted publisher is configured with these case-sensitive
values:
- provider: GitHub Actions;
- organization or user:
shlokjain42; - repository:
invariantCAD; - workflow filename:
release.yml; - environment:
npm; and - allowed action:
npm publish.
ENEEDAUTH, verify every trusted-publisher field
exactly; do not restore a long-lived publish secret. The workflow filename
release.yml and environment name npm are part of that binding.