Releasing
Releases are automated with Changesets (opens in a new tab). Nobody publishes from a laptop.
The pipeline
PR merged to main
│
▼
release.yml runs
│
├─ pending changesets exist?
│ │
│ ├─ yes → open/update "Version Packages" PR
│ │ (bumps versions, writes CHANGELOGs)
│ │
│ └─ that PR merged → pnpm changeset publish → npm
│
└─ no changesets → nothing happensWorkflows
ci.yml
Runs on every push and PR to main:
- pnpm install --frozen-lockfile
- pnpm -r buildNode 20, pnpm 9. This is the gate — a type error anywhere fails it.
release.yml
Runs on push to main and on manual dispatch. Node 24, pnpm 9. Uses
changesets/action@v1 with publish: pnpm changeset publish.
Permissions: contents: write, id-token: write, pull-requests: write.
Concurrency is keyed on workflow + ref, so overlapping runs cancel.
Changeset configuration
{
"changelog": "@changesets/cli/changelog",
"commit": false,
"access": "public",
"baseBranch": "main",
"updateInternalDependencies": "patch"
}updateInternalDependencies: "patch" matters: bumping @mirage-engine/painter
automatically patches @mirage-engine/core and mirage-engine, which depend on
it. One fix deep in the tree ripples outward on its own.
access: "public" is required — scoped packages default to restricted on npm.
Writing a changeset
pnpm changesetThe summary is published verbatim in the changelog, so write it for users:
---
"@mirage-engine/core": minor
"mirage-engine": minor
---
Add `canvasSize` option to control whether the overlay canvas is allocated at
viewport size or full document height.Good summaries name the option or behaviour and say what it does. Avoid "fix bug" and "update logic".
One changeset can bump several packages. If a change spans core and painter, select both — a partial bump ships a version of core that depends on an unreleased painter.
Version policy
| Bump | Meaning |
|---|---|
patch | Bug fix, no API change |
minor | Additive: new option, attribute or export |
major | Breaking: removal, rename, changed default |
All packages are pre-1.0 except @mirage-engine/painter, which is at 1.x. They
version independently — fixed and linked are both empty in the changeset
config.
Manual release
Only if the automation is broken:
Apply pending changesets
pnpm changeset versionBumps package.json versions and updates CHANGELOG.md files.
Build
pnpm -r buildPublish
pnpm changeset publishPublishes only packages whose version is not yet on npm, then creates git tags.
Push tags
git push --follow-tagspackages/mirage-engine has a prepublishOnly hook that rebuilds. Publishing
a stale dist is still possible for the other packages — always run
pnpm -r build first.
Documentation deploys
apps/docs is a Next.js app on Vercel and deploys on push to main,
independently of npm releases. Doc fixes ship without a version bump.
Release checklist
-
pnpm -r buildpasses locally - Changeset added, covering every affected package
- Breaking changes marked
majorand explained in the summary - Docs updated in both locales for any API change
-
apps/devsandbox still runs - Root
README.mdupdated if the public API changed