Status: partly live, partly target.
@changesets/cli is configured (.changeset/config.json) and
pnpm changeset, pnpm changeset:status and pnpm changeset:version exist.
.github/workflows/release.yml opens the version pull request and, on its merge, runs changeset publish to npm.figentra.com. Not built: the Infisical release identity, a packed-artifact smoke
test and signed artifacts. Today every package is still "private": true, so nothing publishes
yet. Policy: 0025 (supersedes 0013 decision 3),
0024 (MIT),
0119 (the owner merges the version pull request).The rules
- Every change to a member ships with a changeset.
pnpm changesetrecords it;pnpm changeset:statusfails when a changed member has none (target: chained intopnpm verify). CHANGELOG.mdfiles are generated by changesets and never hand-edited.- Versions are bumped by the release job on
main, not on a feature branch.guard-bashdenieschangeset versionlocally for that reason. - Merging the version pull request is the release decision. Claude prepares it; the owner merges it (0119 D7).
- Published or tagged versions are permanent. A version is never republished or silently replaced; roll forward with a new patch.
- Only packages are versioned. Apps and services deploy by commit SHA and get no version or tag (
privatePackages: { version: false, tag: false }, 0025 decision 4). - A package publishes when it flips to
"private": false. It then builds todist/*.mjs+.d.mtsand publishes tonpm.figentra.com(@stackrascope).
A normal release
1
Land changesets with the work
In each pull request that changes a member:
pnpm changeset, pick the members, pick the bump
(patch, minor, major) and write one user-facing line. Commit the generated file under
.changeset/.2
Let CI open the version pull request
After a push to
main the release job runs pnpm changeset:version (which also refreshes the
lockfile) and opens or updates one pull request titled chore(release): version packages.3
Review it
Read the
CHANGELOG.md diffs and the version bumps. Check the bump matches the change. The
release job pushes and opens it as stackra-bot (a GitHub App token from
actions/create-github-app-token, repo secrets STACKRA_BOT_APP_ID and
STACKRA_BOT_PRIVATE_KEY), so the Quality Gate runs on it without a close and reopen.4
Merge it
The merge to
main is the release. The job builds, publishes every non-private package to
npm.figentra.com, tags it and creates the release notes.5
Verify
git ls-remote --tags origin shows the new tags on the merge commit, and each member’s
CHANGELOG.md contains the entry.Before the first release (once, by a human)
- Branch protection on
mainrequires theQuality Gatecheck (CI). - A tag ruleset on the version tag pattern blocks deletion and non-fast-forward updates for everyone. Version tags are immutable.
- The host setting that lets the workflow token create pull requests is on.
- The release job runs in a protected environment restricted to
main, so a branch that edits the workflow cannot obtain a credential.
Publishing to npm.figentra.com
0025 records the decision. Before the first package flips to"private": false, a human:
- creates an Infisical machine identity for the release job (OIDC, trusting only this repository’s
releaseenvironment onmain) with read access to/ciinprod; - stores the registry publish token in
/ciasNPM_FIGENTRA_TOKEN; - sets the repository variables
INFISICAL_RELEASE_IDENTITY_IDandINFISICAL_PROJECT_ID(names and ids, never a token). Until they are set the release job skips the token step.
- The publish token comes only from Infisical
/ciover OIDC (0009); no token sits in.npmrc, a repository secret or a file. - Build the tarball and an SBOM with no privileges, then sign both keylessly in the one job that holds
id-token: write. - Publish is idempotent: the same bytes already on the registry are not published again, so re-running failed jobs is safe; different bytes fail the job.
- Read access for consumers is a read-only token held in Infisical
/ciand fetched through OIDC (Secrets). - A prerelease publishes under a
nextdist-tag and moves no floating tag.
When something fails
Re-run only the failed jobs of the same run unless a row says otherwise.Revert
- Before merging: close the version pull request. The next push recreates it from the remaining changesets.
- After merging: roll forward. For a bad release that was published, deprecate it (
npm deprecate <pkg>@<bad> "<reason; use <good>>"), move thelatestdist-tag back to the last good version withnpm dist-tag addif needed, and ship a fixed patch. Prefer deprecate over unpublish. - A bad release record on the host: mark it a prerelease or delete the release page; leave the tag.
- The workflow itself: revert the workflow file on
main; nothing else depends on it.
Checks that back this page
See also Mobile release, Deploys and Commits and releases.