Skip to content

chore(ci): adopt mise, move to Node 24 for npm OIDC trusted publishing - #11

Merged
brentrager merged 2 commits into
mainfrom
chore/mise-node24
Aug 24, 2026
Merged

chore(ci): adopt mise, move to Node 24 for npm OIDC trusted publishing#11
brentrager merged 2 commits into
mainfrom
chore/mise-node24

Conversation

@brentrager

Copy link
Copy Markdown
Contributor

Problem

We publish to npm with long-lived access tokens that bypass MFA. npm's recommended replacement is trusted publishing (OIDC), which requires npm >= 11.5.1.

Every workflow in this repo pinned node-version: 22npm 10.9.x. OIDC could never have worked here, whatever we configured on npmjs.com. Node 24.14.0 ships npm 11.9.0.

Why npm's version is the thing that matters

pnpm publish doesn't implement publishing — it delegates the registry PUT to the npm CLI on PATH. Verified locally: pnpm 10.34.5's publish emits npm's own npm notice Publishing to https://registry.npmjs.org/…. So npm's version gates OIDC, not pnpm's.

That also explains pnpm#11513 (OIDC worked on pnpm 10, broke on pnpm 11): pnpm 11 stopped delegating. pnpm is pinned here at 10.34.5, deliberately not 11.x.

What changed

  • mise.toml — new. Pins: node = "24.14.0" . Read by mise locally and jdx/mise-action@v4 in CI, so a shell and the runner can't drift.
  • packageManagerpnpm@10.34.5.
  • Workflows: actions/setup-node (and setup-go / setup-python / setup-uv where present) → jdx/mise-action@v4.

Deliberately kept on their own actions:

action why
pnpm/action-setup already reads the packageManager pin — pnpm self-substitutes to it regardless of which binary launches, so a mise pnpm pin would be cosmetic and would drift
dtolnay/rust-toolchain rustup is canonical for Rust; mise defers to it
actions/setup-dotnet installs multiple SDKs side by side; mise's dotnet backend pins one

Restored explicitly (setup-node was providing them implicitly): the pnpm store cache, and the .npmrc token write that registry-url: did. npm tries OIDC first and falls back to that token, so it stays until this package has a trusted publisher registered.

Not in this PR

Registering the trusted publisher on npmjs.com — it's per-package and can't be done until this lands, since the config names the workflow file. The token fallback stays in place until then, so publishing keeps working either way.

🤖 Generated with Claude Code

https://claude.ai/code/session_013YaefW6U442PHZf94fMAer

…lishing

npm trusted publishing needs npm >= 11.5.1. Every workflow here pinned
`node-version: 22`, which ships npm 10.9.x — so OIDC could never have
worked regardless of npm-side configuration. Node 24.14.0 ships npm 11.9.0.

`pnpm publish` delegates the registry PUT to the npm CLI on PATH (verified:
it emits npm's own `npm notice` output), so npm's version is what gates
OIDC, not pnpm's. pnpm is pinned at 10.34.5 and deliberately NOT 11.x —
pnpm 11 regressed OIDC by no longer delegating (pnpm#11513).

Toolchain versions move into mise.toml, read by mise locally and by
jdx/mise-action in CI, so a developer's shell and the runner cannot drift.
Pinned here: node = "24.14.0"

Left on their existing actions on purpose: pnpm/action-setup (already reads
the "packageManager" pin), dtolnay/rust-toolchain (rustup is canonical and
mise defers to it), and actions/setup-dotnet (installs several SDKs side by
side, which mise's single-version dotnet backend cannot do).

Restored explicitly because actions/setup-node was providing them
implicitly: the pnpm store cache, and the .npmrc token write that
`registry-url:` performed. npm tries OIDC first and falls back to that
token, so it stays until each package has a trusted publisher registered.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013YaefW6U442PHZf94fMAer
@changeset-bot

changeset-bot Bot commented Aug 24, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 98888ce

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

This repo has no root package.json — the package (and now the
packageManager pin) lives in sst/. Unpinning the action's version made it
look for the pin at the repo root and fail with 'No pnpm version is
specified'.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013YaefW6U442PHZf94fMAer
@brentrager
brentrager merged commit 3af7b97 into main Aug 24, 2026
2 checks passed
@brentrager
brentrager deleted the chore/mise-node24 branch August 24, 2026 21:23
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