Skip to content

ci: stage npm releases via changesets and OIDC trusted publishing - #1033

Merged
taylanpince merged 5 commits into
masterfrom
ci/staged-npm-publishing
Oct 14, 2026
Merged

taylanpince merged 5 commits into
masterfrom
ci/staged-npm-publishing

Conversation

@taylanpince

Copy link
Copy Markdown
Contributor

Summary

Moves npm releases to CI-only staged publishing, mirroring oms-wallet-typescript-sdk:

  • Merging changesets into master keeps a changesets: Release / Deploy PR up to date.
  • Merging that PR runs the release gates, packs every publishable package whose version is not on npm (pnpm rewrites workspace: ranges), and sends the tarballs to npm stage publish under latest via OIDC trusted publishing (no NPM_TOKEN). Changesets then creates package tags and GitHub Releases.
  • A maintainer approves each staged package on npm with 2FA, in the dependency order printed in the run summary.
  • workflow_dispatch with snapshot_tag stages a throwaway snapshot of all packages.

Differences from the reference repo:

  • Packages are versioned independently (no fixed group), so the staging script orders packages dependencies-first instead of validating one group version. Snapshots bump every package so they only depend on each other.
  • Release gates include the anvil-backed wallet tests (Foundry installed in the job).
  • Hardened per the 0xPolygon/pipelines fix for GHSA-rxhc-j8g6-h4jp, which the reference workflow predates: no persisted credentials, --ignore-scripts install, gates run before the release bot token is minted, and the token is scoped to contents and pull-requests write for changesets/action only.

Also:

  • repository.directory on every published package (npm provenance rejects publishes without a matching repository.url).
  • .nvmrc (Node 22; staged publishing needs ≥ 22.14), CI install action reads it.
  • @changesets/changelog-github for PR/commit links in changelogs; shared changeset check on PRs.
  • scripts/configure-npm-trust.sh: one-time registration of this workflow as a stage-only trusted publisher for all 31 package names across master and v2.
  • PUBLISHING.md documents the flow, approvals, recovery, and setup.

Companion PR for v2 (stages under v2-legacy so v2 releases stop moving latest): see the linked PR.

Prerequisites before merging

  1. Create the 0xsequence release bot GitHub App, install it on this repo, and add CHANGESET_RELEASE_BOT_APP_ID / CHANGESET_RELEASE_BOT_APP_PRIVATE_KEY repo secrets (Polygon's app is private to 0xPolygon).
  2. Run ./scripts/configure-npm-trust.sh, then set packages to "Require 2FA and disallow tokens".

The first release PR after merge ships wallet-core@3.0.14 (passkey fee options fix, #1031) plus all packages from the unpublished 3.0.13 version commit; approving the 3.x services packages under latest also moves latest back from v2's 2.3.47.

Test plan

  • pnpm test:release: 12 node:test cases for the staging and snapshot scripts
  • Staging rehearsal with a stub npm stage: all 14 packages packed, no workspace: ranges left, repository.directory present, correct dependency order, real npm view detection of unpublished versions
  • Snapshot versioning: all 14 packages get 0.0.0-canary-<ts>
  • changeset version with changelog-github: wallet-core@3.0.14 entry links Fix fee options stub signature for pending config updates #1031
  • typecheck, lint, build; actionlint on the new workflows
  • First live run: snapshot dispatch, then the 3.0.14 release PR

🤖 Generated with Claude Code

https://claude.ai/code/session_014qDHk3SaPaDGpPTU1jjLpz

taylanpince and others added 3 commits October 14, 2026 11:02
Mirror the staged publishing flow from oms-wallet-typescript-sdk:

- Release workflow opens a changesets Release / Deploy PR; merging it runs
  the release gates, packs every unpublished package with pnpm and sends
  the tarballs to `npm stage publish` (OIDC, no NPM_TOKEN). A maintainer
  approves each stage with 2FA.
- Workflow-dispatch snapshot path stages all packages under a non-semver
  dist-tag.
- Staging script orders packages dependencies-first (no fixed group here)
  and is covered by node:test suites run in CI.
- Add repository.directory to every published package (required for
  provenance), .nvmrc (Node 22), changelog-github, shared changeset check.
- scripts/configure-npm-trust.sh registers the workflow as a stage-only
  trusted publisher for all master and v2 packages.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014qDHk3SaPaDGpPTU1jjLpz
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014qDHk3SaPaDGpPTU1jjLpz
Apply the 0xPolygon/pipelines fix for GHSA-rxhc-j8g6-h4jp, which the
oms-wallet-typescript-sdk workflow this was modelled on predates:

- Check out with persist-credentials: false and install with
  --ignore-scripts, so no token sits in .git/config while dependency code runs.
- Run the release gates (build, typecheck, lint, tests) on release-PR merges
  before the app token is minted; ci:stage-release now only packs and stages.
- Mint the token last (create-github-app-token v3.2.0), scoped to contents
  and pull-requests write, for changesets/action only. Default-deny
  workflow permissions; snapshot job gets pull-requests: read.
- Document the 0xsequence-owned release bot app; Polygon's app is private
  to the 0xPolygon org.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014qDHk3SaPaDGpPTU1jjLpz
@taylanpince
taylanpince requested a review from a team October 14, 2026 09:55
@taylanpince
taylanpince requested a review from a team as a code owner October 14, 2026 09:55
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-14T09:59:55.832623Z 59d1249 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 59d12490a7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread .github/workflows/npm-release-trigger.yml Outdated
Comment thread scripts/prepare-npm-snapshot.mjs Outdated
Comment thread scripts/stage-npm-packages.mjs Outdated
Comment thread scripts/configure-npm-trust.sh Outdated
taylanpince and others added 2 commits October 14, 2026 12:09
`--allow-stage-publish` only exists in npm >= 11.15; the npm bundled with
Node 24.14 is 11.11 and rejects it with EUSAGE. Pin the same npm the
release workflow uses.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014qDHk3SaPaDGpPTU1jjLpz
- prepare-npm-snapshot: reject snapshot tags npm parses as semver ranges
  (`x`, `v1.x`, `v3`) via semver.validRange, before the release gates run.
- stage-npm-packages: the approval summary now lists every unpublished
  version in dependency order, including ones staged by an earlier,
  partially failed run, so dependencies are approved first on retries.
- configure-npm-trust: a failed fetch, missing ref or empty package list
  is fatal instead of reporting success.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014qDHk3SaPaDGpPTU1jjLpz
@taylanpince
taylanpince merged commit 4926b6e into master Oct 14, 2026
15 checks passed
@taylanpince
taylanpince deleted the ci/staged-npm-publishing branch October 14, 2026 11:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant