{"protocol":"clank-doc/1","frameworkVersion":"0.9.3","slug":"releases","title":"Release process","description":"Clank releases are built from reviewed source, submitted through npm trusted publishing without a long lived registry token, and approved by a maintainer with two factor authentication.","group":{"id":"deploy","title":"Deploy and operate"},"url":"https://docs.clank.run/docs/releases","source":"docs/releases.md","headings":["One time repository configuration","Release ceremony","Failure handling"],"tableOfContents":[{"id":"one-time-repository-configuration","title":"One-time repository configuration","level":2},{"id":"release-ceremony","title":"Release ceremony","level":2},{"id":"failure-handling","title":"Failure handling","level":2}],"markdown":"# Release process\n\nClank releases are built from reviewed source, submitted through npm trusted publishing without a long-lived registry token, and approved by a maintainer with two-factor authentication.\n\n## One-time repository configuration\n\n1. Make the GitHub repository public before the first public package release so npm can attach public provenance.\n2. Protect `main`: require pull requests, the Node runtime checks, packaged-release conformance, conversation resolution, and a non-stale approval.\n3. Protect tags matching `v*`.\n4. Create the GitHub Actions environment `npm` and require a maintainer approval.\n5. Sign in to npm as an owner of the `clank.run` organization, enable account-level 2FA, and confirm `@clank.run/framework` is still available.\n6. Bootstrap the package because npm requires it to exist before a trusted publisher can be attached:\n\n   ```bash\n   npm login\n   npm run check\n   npm pack --dry-run\n   npm publish --access public --provenance=false\n   ```\n\n   This is the only direct, interactive publish. Inspect the tarball and package page before entering the 2FA code. The first version will not have CI provenance; every subsequent version will.\n7. Configure the `@clank.run/framework` trusted publisher:\n   - provider: GitHub Actions;\n   - repository: `nearbycoder/clank.run`;\n   - workflow: `release.yml`;\n   - environment: `npm`; and\n   - allowed action: stage publish only.\n8. With npm 11.18 or newer, the equivalent authenticated CLI command is:\n\n   ```bash\n   npm trust github @clank.run/framework \\\n     --repository nearbycoder/clank.run \\\n     --file release.yml \\\n     --environment npm \\\n     --allow-stage-publish\n   ```\n\n9. Require two-factor authentication, disallow traditional publish tokens, and revoke any bootstrap token or saved npm session that is no longer needed.\n10. Enable GitHub private vulnerability reporting.\n11. Create a GitHub Actions environment named `docs`, restrict it to protected branches, and set:\n    - `CLANK_DOCS_PROJECT_ID` as an environment variable containing the linked `docs.clank.run` project ID; and\n    - `CLANK_DOCS_TOKEN` as an environment secret containing a project token limited to `read,deploy`.\n\nCreate the documentation token from the linked `docs-site` directory with\n`clank token create --name github-actions-docs --permissions read,deploy --expires-in=31536000`.\nThe secret is shown once. Store it directly in the `docs` environment, record its expiry in the\noperator calendar, and replace then revoke it before it expires. Never use an account-wide device\ntoken for the workflow.\n\nThe release workflow uses Node 24 with npm 11.18.0 and requests `id-token: write` only in the publish job. npm exchanges that GitHub OIDC identity for a short-lived credential and automatically produces package provenance for the public package.\n\nThe `clank` npm name belongs to an unrelated project. Do not publish or document it as the framework dependency; the brand command remains `clank`, while package imports use `@clank.run/framework`.\n\n## Release ceremony\n\n1. Confirm `CHANGELOG.md` contains the complete version entry.\n2. Update `package.json` to the intended semantic version.\n3. Run `npm run check` from a clean checkout.\n4. Open and merge the version pull request.\n5. Create an annotated, protected `v<version>` tag from that merge.\n6. Draft a GitHub release from the tag using the matching changelog entry.\n7. Publish the GitHub release.\n8. Approve the `npm` GitHub environment deployment after verifying the tag and workflow summary.\n9. Download and inspect the staged npm tarball, then approve it with 2FA from npmjs.com or `npm stage approve <stage-id>`.\n10. Verify:\n   - the npm package shows provenance;\n   - the attached `.tgz` verifies with `gh attestation verify`;\n   - a fresh consumer can install, scaffold, build, and run; and\n   - `https://docs.clank.run/healthz` reports the released framework version; and\n   - the package contains no database, credential, environment, platform-state, or unrelated generated files.\n\nThe GitHub release event runs the complete gate again, packs one tarball, creates a GitHub artifact attestation for it, attaches it to the release, and submits the same source to npm's staged-publishing queue through trusted publishing.\n\nEvery successful same-repository `main` CI run also starts the documentation deployment workflow.\nIt checks out the exact commit that passed CI, rebuilds the complete documentation corpus, runs\n`doctor` and a deterministic dry-run, then deploys to the fixed `docs.clank.run` project. The\nproject-scoped token is available only through the protected `docs` environment. Pull requests,\nforks, failed CI runs, other branches, and unverified revisions cannot reach the deployment job.\n\n## Failure handling\n\n- Do not reuse or move a published version or tag.\n- Deprecate a bad npm version and publish a new patch.\n- If publication identity or source provenance is questionable, revoke obsolete tokens, disable publishing, preserve evidence, and follow `SECURITY.md`.\n- A GitHub attestation proves which workflow and source produced an artifact; it does not prove the source itself is vulnerability-free.\n"}