From faa99d696bb11453f877873f9c142319639ee512 Mon Sep 17 00:00:00 2001 From: Brent Date: Mon, 24 Aug 2026 16:59:45 -0400 Subject: [PATCH] chore(ci): adopt mise, move to Node 24 so npm can do OIDC trusted publishing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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" python = "3.13" go = "1.23" uv = "latest" 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) Claude-Session: https://claude.ai/code/session_013YaefW6U442PHZf94fMAer --- .github/workflows/pr-checks.yml | 43 ++++++++++++++++++++++----------- .github/workflows/release.yml | 29 +++++++++------------- mise.toml | 16 ++++++++++++ package.json | 2 +- 4 files changed, 58 insertions(+), 32 deletions(-) create mode 100644 mise.toml diff --git a/.github/workflows/pr-checks.yml b/.github/workflows/pr-checks.yml index aa3634d..256c336 100644 --- a/.github/workflows/pr-checks.yml +++ b/.github/workflows/pr-checks.yml @@ -32,9 +32,11 @@ jobs: timeout-minutes: 5 steps: - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 - with: - node-version: 22 + # Toolchains come from mise.toml, read here by mise-action so the runner + # and a developer's shell resolve identical versions. + - name: Setup toolchains (mise) + uses: jdx/mise-action@v4 + - name: Version consistency run: node scripts/sync-versions.mjs --check @@ -45,10 +47,21 @@ jobs: steps: - uses: actions/checkout@v4 - uses: pnpm/action-setup@v4 - - uses: actions/setup-node@v4 + # Toolchains come from mise.toml, read here by mise-action so the runner + # and a developer's shell resolve identical versions. + - name: Setup toolchains (mise) + uses: jdx/mise-action@v4 + + - name: Locate pnpm store + run: echo "STORE_PATH=$(pnpm store path --silent)" >> "$GITHUB_ENV" + + - name: Cache pnpm store + uses: actions/cache@v4 with: - node-version: 22 - cache: 'pnpm' + path: ${{ env.STORE_PATH }} + key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} + restore-keys: ${{ runner.os }}-pnpm-store- + - run: pnpm install - name: Typecheck run: pnpm ts:typecheck @@ -72,10 +85,11 @@ jobs: working-directory: python steps: - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 - with: - python-version: '3.13' - - uses: astral-sh/setup-uv@v6 + # Toolchains come from mise.toml, read here by mise-action so the runner + # and a developer's shell resolve identical versions. + - name: Setup toolchains (mise) + uses: jdx/mise-action@v4 + - run: uv sync --group dev - name: Typecheck run: uv run poe typecheck @@ -128,10 +142,11 @@ jobs: working-directory: go/fetch steps: - uses: actions/checkout@v4 - - uses: actions/setup-go@v5 - with: - go-version: '1.23' - cache-dependency-path: go/fetch/go.sum + # Toolchains come from mise.toml, read here by mise-action so the runner + # and a developer's shell resolve identical versions. + - name: Setup toolchains (mise) + uses: jdx/mise-action@v4 + - name: Format check run: test -z "$(gofmt -l .)" - name: Vet diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 64d8bd9..3aa604f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -37,19 +37,20 @@ jobs: - name: Setup pnpm uses: pnpm/action-setup@v4 - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: 22 - cache: 'pnpm' + # Toolchains come from mise.toml, read here by mise-action so the runner + # and a developer's shell resolve identical versions. + - name: Setup toolchains (mise) + uses: jdx/mise-action@v4 - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: '3.13' + - name: Locate pnpm store + run: echo "STORE_PATH=$(pnpm store path --silent)" >> "$GITHUB_ENV" - - name: Setup uv - uses: astral-sh/setup-uv@v6 + - name: Cache pnpm store + uses: actions/cache@v4 + with: + path: ${{ env.STORE_PATH }} + key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} + restore-keys: ${{ runner.os }}-pnpm-store- - name: Setup Rust toolchain uses: dtolnay/rust-toolchain@stable @@ -61,12 +62,6 @@ jobs: rust/fetch -> rust/fetch/target cache-on-failure: true - - name: Setup Go - uses: actions/setup-go@v5 - with: - go-version: '1.23' - cache-dependency-path: go/fetch/go.sum - - name: Setup .NET uses: actions/setup-dotnet@v4 with: diff --git a/mise.toml b/mise.toml new file mode 100644 index 0000000..c937323 --- /dev/null +++ b/mise.toml @@ -0,0 +1,16 @@ +# Toolchain versions for this repo — read by mise locally and by +# jdx/mise-action in CI, so a developer's shell and the runner agree. +# +# Not listed here on purpose: +# pnpm -> package.json "packageManager". pnpm self-substitutes to that +# version regardless of which pnpm binary launches it, so a mise +# pin would be cosmetic and would drift. +# dotnet-> actions/setup-dotnet. It installs several SDKs side by side +# (8/9/10 in some repos); mise's dotnet backend pins one. +# rust -> rust-toolchain.toml + dtolnay/rust-toolchain. rustup is canonical +# and mise defers to it anyway. +[tools] +node = "24.14.0" # ships npm 11.9.0 — required (>=11.5.1) for npm OIDC trusted publishing +python = "3.13" +go = "1.23" +uv = "latest" diff --git a/package.json b/package.json index 3da2e9c..fc9ae2d 100644 --- a/package.json +++ b/package.json @@ -168,5 +168,5 @@ "optional": true } }, - "packageManager": "pnpm@10.6.1+sha512.40ee09af407fa9fbb5fbfb8e1cb40fbb74c0af0c3e10e9224d7b53c7658528615b2c92450e74cfad91e3a2dcafe3ce4050d80bda71d757756d2ce2b66213e9a3" + "packageManager": "pnpm@10.34.5" }