Skip to content

ci(release): npm Trusted Publishing (OIDC), drop NPM_TOKEN - #86

Merged
aagarwal1012 merged 1 commit into
mainfrom
ci/npm-trusted-publishing-oidc
Aug 24, 2026
Merged

aagarwal1012 merged 1 commit into
mainfrom
ci/npm-trusted-publishing-oidc

Conversation

@aagarwal1012

Copy link
Copy Markdown
Member

What

Switch chimely's changesets-driven npm publish from a long-lived NPM_TOKEN to npm Trusted Publishing over GitHub Actions OIDC.

Changes

  • Drop NPM_TOKEN: ${{ secrets.NPM_TOKEN }} from the Publish to npm (changesets) step. The publish job already grants id-token: write, so pnpm changeset publish authenticates via OIDC.
  • Update the stale prerequisites comment (was "NPM_TOKEN secret required").

Why this works with pnpm + changesets

pnpm@11.5.2 (this repo's pinned packageManager) includes pnpm#11495, which makes the OIDC-derived token override a static _authToken — matching npm CLI precedence. Leaving NPM_TOKEN set would silently downgrade the publish back to legacy token auth (no trustedPublisher metadata, no provenance), so dropping it is what forces the OIDC path. setup-node here does not set registry-url, so there's no .npmrc _authToken placeholder to poison the exchange.

Prerequisite (done)

Both packages have a trusted publisher registered on npmjs.com — repo dodopayments/chimely, workflow release.yml:

  • @chimely/client
  • @chimely/react

Provenance is already visibility-gated in the workflow (repo is public → provenance on).

Note

This repo wasn't in the original org-wide sweep because it wires the token via changesets' NPM_TOKEN env, not NODE_AUTH_TOKEN. Completes the org rollout (metabase excepted — its dist-tag workflow can't use OIDC).

…M_TOKEN

The publish job already grants id-token: write (used for provenance). Remove
the NPM_TOKEN env from the changesets publish step so pnpm authenticates via
OIDC trusted publishing instead of a long-lived token.

pnpm 11.5.2 (this repo's pinned packageManager) includes the OIDC precedence
fix (pnpm#11495): the OIDC-derived token overrides any static _authToken, so
leaving NPM_TOKEN set would silently downgrade the publish back to legacy
token auth (no trusted-publisher metadata / provenance). Dropping it forces
the OIDC path.

Each @chimely/* package (client, react) has a trusted publisher registered on
npmjs.com for repo dodopayments/chimely + workflow release.yml. Provenance
stays visibility-gated (repo is public, so on). Mirrors dodopayments/dualmark#91.
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Aug 24, 2026 •

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
chimely-docs 95e4f92 Commit Preview URL

Branch Preview URL
Aug 24 2026, 08:01 AM

@aagarwal1012
aagarwal1012 merged commit 9b7b92b into main Aug 24, 2026
10 of 11 checks passed
@aagarwal1012
aagarwal1012 deleted the ci/npm-trusted-publishing-oidc branch August 24, 2026 08:00
@greptile-apps

greptile-apps Bot commented Aug 24, 2026

Copy link
Copy Markdown

Greptile Summary

The PR switches npm releases from a long-lived token to GitHub Actions OIDC trusted publishing.

  • Removes NPM_TOKEN from the Changesets publish environment.
  • Updates workflow prerequisites and publishing comments to describe trusted-publisher setup.
  • Retains visibility-gated npm provenance.

Confidence Score: 4/5

The PR appears safe to merge, with only a non-blocking request to make the new workflow comment concise and invariant-focused.

The publish job has the required OIDC permission, uses a compatible pinned pnpm version, and does not configure a competing npm token; the only accepted concern is the repository’s comment-style requirement.

Files Needing Attention: .github/workflows/release.yml

Important Files Changed

Filename Overview
.github/workflows/release.yml Correctly removes legacy npm-token authentication in favor of the existing OIDC permission, with one non-blocking repository comment-style violation.

Reviews (1): Last reviewed commit: "ci(release): switch chimely to npm Trust..." | Re-trigger Greptile

Comment on lines +97 to +103
# No NPM_TOKEN: npm Trusted Publishing (OIDC) authenticates the
# publish via the job's id-token: write. pnpm >= the #11495 fix
# (this repo pins pnpm 11.5.2) lets the OIDC-derived token override
# any static _authToken, so a token here would only downgrade the
# publish back to legacy token auth (no trusted-publisher metadata).
# Each @chimely/* package has a trusted publisher registered on
# npmjs.com for repo dodopayments/chimely + workflow release.yml.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Keep authentication comment invariant-focused

This block narrates and argues for the implementation rather than documenting the enduring requirement, obscuring the key constraint that NPM_TOKEN must remain unset for OIDC publishing.

Suggested change
# No NPM_TOKEN: npm Trusted Publishing (OIDC) authenticates the
# publish via the job's id-token: write. pnpm >= the #11495 fix
# (this repo pins pnpm 11.5.2) lets the OIDC-derived token override
# any static _authToken, so a token here would only downgrade the
# publish back to legacy token auth (no trusted-publisher metadata).
# Each @chimely/* package has a trusted publisher registered on
# npmjs.com for repo dodopayments/chimely + workflow release.yml.
# NPM_TOKEN must remain unset so npm Trusted Publishing uses the
# job's OIDC credentials.

Context Used: CLAUDE.md (source)

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

@dodo-squirrels dodo-squirrels Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Verified the change end to end against the actual toolchain versions rather than taking the description at face value. The reasoning holds up. Approving.

What I checked

  • Which client actually publishes. @changesets/cli@2.31.0 resolves the publish tool via preferred-pm, and with pnpm-lock.yaml present it spawns pnpm publish, not npm publish. So pnpm's OIDC implementation is the one that runs and Node 24's bundled npm version is irrelevant here. The premise is right.
  • pnpm floor. The OIDC-overrides-static-_authToken fix (pnpm#11495, 90e215f) is first tagged in v11.0.7. The repo pins pnpm@11.5.2 in packageManager, and pnpm/action-setup@v4 is used with no version input so it reads that field. Comfortably above the floor.
  • No _authToken=undefined poisoning. This was my main concern, since changesets/action writes ~/.npmrc itself, independently of setup-node. Since v1.7.0 (changesets/action#545) that write is guarded by if (process.env.NPM_TOKEN), with an explicit OIDC branch that writes nothing. @v1 currently resolves to 1.9.0, so this is fine, and pnpm's override would cover it anyway. Belt and braces.
  • No .npmrc placeholder. Confirmed setup-node has no registry-url here, as stated.
  • No stale references. NPM_TOKEN / NODE_AUTH_TOKEN / registry-url appear nowhere else in workflows, docs, or scripts, so the secret can be deleted from repo settings without collateral damage.
  • Provenance gate still works. pnpm does publishOptions.provenance ??= oidc?.provenance, so an explicit NPM_CONFIG_PROVENANCE still wins over the OIDC-derived default. The existing visibility gate is unaffected.
  • No auth pre-check in the way. In CI process.stdin.isTTY is false, so changesets skips its 2FA probe. Nothing needs a token before the publish itself.
  • Preconditions. Both packages already exist on the registry (0.2.2), which is required to register a trusted publisher at all. id-token: write is on the publish job only, and version correctly has neither OIDC nor a publish script.

Non-blocking

  1. Name the concrete pnpm floor. The comment says pnpm >= the #11495 fix, which sends a future reader to a PR number to work out what "the fix" is. pnpm >= 11.0.7 is directly checkable against packageManager. Worth saying both.
  2. Duplicated fact. The trusted-publisher registration (repo + release.yml) is now stated twice, in the header prerequisites and again in the step env. Given the repo's "a comment must earn its place" rule, the step comment could drop its last two lines and keep only the non-obvious part, the silent-downgrade failure mode. That is the bit genuinely worth writing down.
  3. The workflow filename is now load-bearing. The trusted publisher is bound to release.yml, so renaming this file or moving the publish step into a reusable workflow breaks the exchange at release time with no earlier signal. Worth stating as a failure mode in the header, not only as a configuration fact.
  4. Confirm there is no GitHub environment on the npm side. If the trusted publisher entries were registered with an environment name, this job would need a matching environment: key. Not visible from the diff, but worth double-checking before the next release since the first symptom is a failed publish.
  5. Stale neighbour (pre-existing, in the block this PR is already tidying): the provenance gate comment still says "chimely is private now and public-bound", but the repo is public, so that step now always evaluates to true. Either fold the cleanup in here or leave it, but the comment is currently wrong.
  6. Follow-up hardening. Trusted publishing scopes the credential to this workflow, not to the actions running inside it, so anything in the publish job can still mint a publish token. That is strictly better than a long-lived NPM_TOKEN (no secret at rest to exfiltrate, short-lived credential), but SHA-pinning the publish job's third-party actions is the natural next step. Out of scope here.

Unrelated pre-existing footgun

Noticed while reading changesets/action: the OIDC and publish path only runs in the !hasChangesets && hasPublishScript case. If any .changeset/*.md file happens to be present at the release commit, the publish job takes the version branch instead, opens a PR, and exits 0 without publishing. Not caused by this PR, but a silent no-op release is an unpleasant way to discover it.

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