Skip to content

ci: standardize on npm 11 with min-release-age gate - #2351

Merged
nickytonline merged 5 commits into
mainfrom
ntaylor/eng-4332-npm-11
Aug 25, 2026
Merged

nickytonline merged 5 commits into
mainfrom
ntaylor/eng-4332-npm-11

Conversation

@nickytonline

@nickytonline nickytonline commented Aug 20, 2026

Copy link
Copy Markdown
Member

Summary

The pre-commit CI failure on #2350 surfaced that this repo had never actually been migrated to npm 11 as part of ENG-3817's package-age-quarantine rollout — it was still on Yarn when that work was scoped, so it got missed. npm ci errored with:

npm error Missing: unist-util-visit@4.1.2 from lock file
npm error Missing: unist-util-visit-parents@5.1.3 from lock file

Root cause: Node's bundled npm (10.9.4, from .tool-versions' pinned Node 22.22.0) resolves an optional nested dependency subtree differently than npm 11 (hast-util-to-estree's optional dependency on unist-util-visit/unist-util-visit-parents) — npm 11 tolerates the gap, npm 10.9.4 hard-fails npm ci on it. Confirmed by reproducing the failure locally with npx npm@10.9.4 ci against a freshly-regenerated lockfile, and confirming success with npm 11.

This PR brings the repo onto npm 11 by bumping Node itself, rather than pinning npm separately: .tool-versions now pins Node 24.19.0, which bundles npm 11.17.0 by default (matching the convention already used in pomerium/pomerium). That also means min-release-age (which npm 10 silently ignores) actually takes effect now, bringing this repo in line with the supply-chain hardening already rolled out to other Pomerium repos.

Changes

  • .tool-versions: nodejs 22.22.024.19.0 — Node's bundled npm 11 is what actually fixes the npm ci failure; no separate npm install step needed
  • .npmrc: min-release-age=3
  • package.json:
    • engines.node bumped to >=24.0.0 (the version where npm 11 becomes the bundled default), engines.npm pinned to >=11 <12 — the <12 ceiling is deliberate: npm 12.0.2 already exists on the registry, but no Node release line bundles it yet, so this avoids picking up an unvetted major version by accident
    • no packageManager field — Corepack only manages npm from this field if you explicitly run corepack enable npm (this repo doesn't), npm itself doesn't validate its own version against it, and Netlify's docs confirm it's consulted via Corepack for Yarn/pnpm but not for npm, so pinning it here wouldn't have done anything except go stale
  • npm-audit-signatures.yml (new): verifies registry signatures and provenance attestations on package.json/package-lock.json changes
  • package-lock.json regenerated with npm 11

Locally verified under Node 24.19.0 (bundled npm 11.17.0), with no manual npm install and no corepack enable: npm ci, npm ci --ignore-scripts, npm audit signatures --min-release-age=0, and npm run check all pass — including postman-code-generators's yarn-based postinstall script (a transitive dep of docusaurus-theme-openapi-docs), which runs fine since nothing in the ancestor package.json chain declares a packageManager field to trigger Node's disabled yarn shim.

Related

AI disclosure

Claude Code (Sonnet 5) was used throughout, iteratively rather than as a single draft-and-review pass: it investigated the original CI failure, and initial attempts at a fix (regenerating the lockfile, then just bumping npm) didn't hold up under scrutiny, which led to jointly digging further and finding the actual npm 10 vs 11 dependency-resolution root cause. That led to cross-checking the convention used in other Pomerium repos (ENG-3817) and, after review feedback questioned why Node wasn't just bumped, confirming against Node's own release metadata and pomerium/pomerium's existing .tool-versions/CI convention that bumping to Node 24 gets npm 11 natively. Along the way, several intermediate fixes (a packageManager pin, a curl-installed npm binary, a corepack enable step) turned out to be unnecessary once Node was bumped and were removed after verifying locally (clean installs, with Corepack explicitly disabled, confirming npm ci including the yarn-based postinstall still succeeds). Nick Taylor directed the investigation and design decisions at each step and reviewed all resulting changes.

Also needed to manually intervene here. We're not using a netlify.toml so had to modify the build command in the Netlify UI. We already moved to npm a while back, but the build command was not updated.

Snapzy_2026-08-20_16-14-18_915

Also set the Node version to 24.x in the Netlify UI

Snapzy_2026-08-21_08-31-42_590

Checklist

  • reference any related issues
  • disclosed AI usage (or wrote "none") per AI_POLICY.md

Fixes a pre-commit CI failure on PR #2350 where npm ci errored with
"Missing: unist-util-visit@4.1.2 from lock file" — Node's bundled npm
10.9.4 resolves an optional nested dependency subtree differently than
npm 11 (hast-util-to-estree's optional dependency on unist-util-visit/
unist-util-visit-parents), and hard-fails on the gap where npm 11
tolerates it.

Also brings this repo in line with the npm 11 + min-release-age
supply-chain hardening rolled out to other Pomerium repos (npm 10
silently ignores min-release-age, so npm 11 is required for it to
take effect at all):

- .npmrc: min-release-age=3
- package.json: engines.npm and packageManager pinned to npm 11.12.1
- pre-commit.yml: installs npm 11.12.1 before npm ci
- npm-audit-signatures.yml: new workflow, verifies registry signatures
  and provenance attestations on package.json/package-lock.json changes

Regenerated package-lock.json with npm 11.12.1.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@nickytonline
nickytonline requested a review from a team as a code owner August 20, 2026 20:05
@nickytonline
nickytonline requested review from kenjenkins and removed request for a team August 20, 2026 20:05
@netlify

netlify Bot commented Aug 20, 2026

Copy link
Copy Markdown

Deploy Preview for pomerium-docs ready!

Name Link
🔨 Latest commit d99e310
🔍 Latest deploy log https://app.netlify.com/projects/pomerium-docs/deploys/6a884573d1a6d8000832a6d1
😎 Deploy Preview https://deploy-preview-2351--pomerium-docs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@nickytonline
nickytonline marked this pull request as draft August 20, 2026 20:05
@greptile-apps

greptile-apps Bot commented Aug 20, 2026

Copy link
Copy Markdown

Greptile Summary

The PR standardizes development and CI on Node 24 with npm 11 and adds a three-day package-release quarantine.

  • Adds a dependency-signature and provenance audit workflow.
  • Declares the supported Node and npm ranges.
  • Regenerates npm lockfile metadata for npm 11.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
.github/workflows/npm-audit-signatures.yml Adds a least-privilege workflow that installs dependencies without lifecycle scripts and audits registry signatures and provenance.
.npmrc Configures npm 11 to exclude packages published within the preceding three days.
.tool-versions Pins Node 24.19.0 so local and CI environments receive the intended npm 11 runtime.
package.json Raises the supported Node floor and constrains npm to major version 11.
package-lock.json Regenerates dependency metadata under npm 11, including removal of the problematic optional nested subtree.

Reviews (6): Last reviewed commit: "ci: drop packageManager pin and corepack..." | Re-trigger Greptile

@nickytonline

Copy link
Copy Markdown
Member Author

We're not using a netlify.toml so had to modify the build command in the Netlify UI. We already moved to npm a while back, but the build command was not updated.

Snapzy_2026-08-20_16-14-18_915

@nickytonline
nickytonline marked this pull request as ready for review August 20, 2026 20:16
npm ci was failing because postman-code-generators (a transitive dep
of docusaurus-theme-openapi-docs) shells out to `yarn install` from
its postinstall script. Node's bundled corepack shim for yarn refuses
to run once package.json declares a "packageManager" field (added in
1c198e6 for npm 11), even though that field only pins npm -- it just
needs `corepack enable` to be run first, as its own error message
says.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@nickytonline
nickytonline enabled auto-merge (squash) August 20, 2026 20:30

@kenjenkins kenjenkins 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.

I thought npm was bundled with nodejs? Do we need to bump the nodejs version in the .tool-versions file?

@nickytonline

Copy link
Copy Markdown
Member Author

I thought npm was bundled with nodejs? Do we need to bump the nodejs version in the .tool-versions file?

We can definitely bump to node 24 (Netlify supports it) and get npm 11 with it. I was just going the "standard" way what we did in other repos when we added npm 11.

Node 24 bundles npm 11 by default (24.19.0 ships npm 11.17.0),
matching the convention already used in pomerium/pomerium. This
makes the curl-based "install npm 11.12.1" workaround in
pre-commit.yml and npm-audit-signatures.yml unnecessary — it was
only needed because Node 22 bundles npm 10, and `corepack enable`
does not shim npm on its own (only yarn/pnpm).

- .tool-versions: nodejs 22.22.0 -> 24.19.0
- pre-commit.yml, npm-audit-signatures.yml: drop the manual npm
  install/verify steps, rely on Node's bundled npm
- package.json: bump engines.node floor to >=24.0.0 (the version
  where npm 11 becomes bundled), so it reflects what's actually
  required to avoid the npm 10 lockfile-resolution gap from #2350

Verified locally under node 24.19.0 (bundled npm 11.17.0): npm ci,
npm ci --ignore-scripts, and npm audit signatures --min-release-age=0
all pass.

Follow-up to #2351, in response to review feedback questioning why
Node wasn't just bumped to get npm 11 natively.

AI usage: Claude Code (Sonnet 5) investigated the fix, confirmed
against pomerium/pomerium's convention and Node's release metadata,
and verified the change locally; changes reviewed by Nick Taylor.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@nickytonline

Copy link
Copy Markdown
Member Author

I thought npm was bundled with nodejs? Do we need to bump the nodejs version in the .tool-versions file?

@kenjenkins, I just moved to Node.js 24. No need to stay on 22.

The `packageManager: "npm@11.12.1"` field wasn't doing anything:
Corepack only manages npm from it if you run `corepack enable npm`
(nothing here does that, only bare `corepack enable`), npm itself
doesn't validate its own version against the field, and Netlify's
docs confirm it uses this field via Corepack for Yarn/pnpm but not
for npm. It was also already stale (11.12.1 vs the 11.17.0 actually
bundled with Node 24.19.0) and would keep drifting with every Node
point release.

Removing it also removes the reason the `corepack enable` step in
pre-commit.yml existed: that step was only needed because our own
`packageManager` field is what triggered the disabled yarn shim's
check when postman-code-generators's postinstall shells out to
`yarn install`. With no `packageManager` field declared anywhere in
the ancestor chain, the shim doesn't trigger the check.

Verified with a clean copy of package.json/package-lock.json under
Node 24.19.0, Corepack explicitly disabled: `npm ci` (with scripts)
completes successfully, including postman-code-generators's
yarn-based postinstall populating its codegens/ folders. Reran
against the actual repo tree with the same result.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@nickytonline
nickytonline force-pushed the ntaylor/eng-4332-npm-11 branch from 9604f87 to d99e310 Compare August 21, 2026 12:32
Comment thread .npmrc

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.

I don't see a min-release-age in any of our other repos. Should we hold off on adding this for now, for consistency?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I had it on auto-merge. 😅 I took that from the issue Bobby had created initially I believe, but you're right. It's not in our other repos. I can rollback the .npmrc change.

@nickytonline
nickytonline merged commit 0decedb into main Aug 25, 2026
15 checks passed
@nickytonline
nickytonline deleted the ntaylor/eng-4332-npm-11 branch August 25, 2026 17:14
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.

2 participants