Releases are fully automated by changesets — no manual git tag, no manual
npm publish. You describe changes; merging a bot-generated PR ships them.
Two artifacts, versioned as a linked changeset group:
@karnstack/reins— the npm package (CLI + daemon)- reins extension — the Chrome Web Store item (version drives the manifest
and the
pnpm zipfilename)
Linked (not fixed) means each package bumps only when a changeset names it,
but whenever they bump together they land on the same version. The extension
carries the debugger permission, so every store upload goes through manual
review — CLI-only releases deliberately leave the extension version alone,
and the release workflow skips the store upload when the store already has the
current extension version.
@reins/protocol is private and bundled into the npm package; changesets
ignores it and it is never published on its own.
-
Describe each change with a changeset and commit it alongside the code:
pnpm changeset
Pick the bump (
patch/minor/major) and a one-line summary, and select the package(s) the change actually ships in:- CLI-only change (daemon, commands, docs in the npm package) →
@karnstack/reinsonly. The extension stays at its current version and nothing is re-submitted to the store. - Extension or protocol change → select both
@karnstack/reinsand@reins/extension. A protocol change without an extension bump would leave the store build speaking an old protocol — CI'sprotocol-guardjob fails the PR ifpackages/protocolchanges with no@reins/extensionchangeset.
- CLI-only change (daemon, commands, docs in the npm package) →
-
Push to
main. Thereleaseworkflow opens (or updates) a "Version Packages" PR that applies the pending changesets: bumpspackage.jsonversions and writesCHANGELOG.md. -
Merge the Version Packages PR. That merge triggers the workflow's publish path:
- publishes
@karnstack/reinsto npm (with provenance), - creates the git tag + GitHub release automatically,
- if the Chrome Web Store secrets are set and the extension version is newer than what the store has (checked against the store API), builds the zip and uploads + submits it. CLI-only releases skip this step, so the store isn't re-reviewed for identical builds.
- publishes
That's it — no tagging by hand.
| Secret | For | Needed by |
|---|---|---|
NPM_TOKEN |
npm automation token, publish rights for @karnstack |
first release |
CWS_EXTENSION_ID |
the store-assigned extension ID | store auto-upload |
CWS_CLIENT_ID / CWS_CLIENT_SECRET / CWS_REFRESH_TOKEN |
Chrome Web Store API OAuth | store auto-upload |
Until the four CWS_* secrets exist, the store step is skipped and everything
else still runs. See CHROME_WEB_STORE.md for how to get
the OAuth credentials — and note the first store upload is manual (that is
what assigns CWS_EXTENSION_ID).
The packages are seeded at 0.1.0 with no changesets. On the first push to
main with this workflow in place, there is nothing to version, so the publish
path runs immediately and changeset publish pushes 0.1.0 to npm (it only
publishes versions not already on the registry). Steps for the first ship:
- Make the repo public and add
NPM_TOKEN. - Land this workflow on
main→@karnstack/reins@0.1.0publishes; the tag + GitHub release appear automatically. - Manually upload
packages/extension/release/reins-extension-v0.1.0.zipto the Chrome Web Store (see CHROME_WEB_STORE.md); the store assigns the extension ID. - Put that ID in
PUBLISHED_EXTENSION_IDS(packages/cli/src/allowlist.ts), add the fourCWS_*secrets, andpnpm changeseta patch — from then on, every release ships to npm and the store automatically.
-
@reins/protocolis bundled (noExternalinpackages/cli/tsdown.config.ts), so the published package has no workspace dependencies. -
npm auth in CI is handled by the changesets action: given the
NPM_TOKENenv var, it writes a user~/.npmrcbefore publishing. (A token line in the committed.npmrcwould be ignored — pnpm won't expand env vars in project-file credentials.) -
Smoke-test the tarball once before the first publish:
cd packages/cli && npm pack npx -y ./karnstack-reins-*.tgz status