Commit 35c90d9
feat: registry-aware release workflow with provenance + OIDC (#1664)
* feat: add registry-aware release workflow with provenance + OIDC
Add a release pipeline that publishes only the workspace packages whose
manually-set version is ahead of the npm registry — versions are never
bumped by the tooling.
- scripts/release.mjs: enumerates publishable packages (pnpm), compares
each local version against the registry (404/new/already-published),
computes the full plan before publishing, and publishes in dependency
(topological) order using pnpm only with provenance. Supports --dry-run
(plan + `pnpm publish --dry-run` packaging validation), --json, and
writes a GitHub step summary + outputs.
- .github/workflows/release.yml: runs on push to main (package.json
changes) and manual dispatch with a dry-run input; grants id-token:
write for OIDC trusted publishing + provenance, with NPM_TOKEN as an
optional fallback.
- RELEASE.md: documents the flow and the one-time npmjs.com trusted
publisher setup.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01F7cjEDzGAPQUmvQehU1sGF
* fix: address review feedback on release tooling
- release.mjs: encode all "/" in scoped package names for the registry URL
(replaceAll) — fixes the CodeQL "incomplete string escaping" alert.
- release.mjs: abort a real publish on the first failure so a failed
dependency never leaves dependents publishing against a missing version;
a dry run still validates every package. Report packages skipped by the
abort.
- release.mjs: add a 10s AbortSignal.timeout to registry fetches so a
stalled registry fails fast into the existing retry/backoff.
- release.yml: set persist-credentials: false on checkout (the job only
reads the repo and never pushes).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01F7cjEDzGAPQUmvQehU1sGF
* refactor: make release fully tokenless (OIDC trusted publishing only)
Remove the NODE_AUTH_TOKEN/NPM_TOKEN fallback so publishing relies solely
on OIDC trusted publishing, eliminating the long-lived npm token. Each
package must have a trusted publisher configured on npmjs.com; document
that a brand-new package's first publish needs a one-time manual publish.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01F7cjEDzGAPQUmvQehU1sGF
* fix: guard against version rollbacks and off-main manual publishes
Addresses two Codex review findings:
- release.mjs: refuse to publish a package whose local version is behind
the registry's `latest` dist-tag. Publishing under the default tag would
move `latest` (and every `^`/`~` consumer) backward, so an accidental
rollback now fails the run before anything is published. Adds a small
spec-correct semver comparator (no new dependency).
- release.yml: force a dry run for any manual dispatch from a ref other
than `main`, so branch versions can't be published to npm (the publish
step uses --no-git-checks). Real publishing only happens on main.
The "abort on first publish failure" finding was already handled in the
prior review-fixes commit.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01F7cjEDzGAPQUmvQehU1sGF
* fix: trigger release on published GitHub release, not push to main
Per review: the release workflow should run when a GitHub release is
published (in lockstep with deploy-website.yml, which also runs on
`released`) or on manual dispatch — not on every push to main.
- Replace the push-to-main trigger with `release: types: [released]`.
- A published release publishes for real; a manual run still honors its
dry-run input and is forced to a dry run from any ref other than main.
- Update RELEASE.md to describe the release-driven flow.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01F7cjEDzGAPQUmvQehU1sGF
* docs: move release docs into CONTRIBUTING.md
Per review: fold the release process into the existing CONTRIBUTING.md as
a "Releasing" section instead of a standalone RELEASE.md file.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01F7cjEDzGAPQUmvQehU1sGF
* docs: add Releasing section to CONTRIBUTING.md
Completes the move from RELEASE.md (the prior commit deleted the file but
the staging of CONTRIBUTING.md was dropped due to a git add error).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01F7cjEDzGAPQUmvQehU1sGF
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 917bd83 commit 35c90d9
3 files changed
Lines changed: 596 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
28 | 28 | | |
29 | 29 | | |
30 | 30 | | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
31 | 94 | | |
32 | 95 | | |
0 commit comments