From 9c959f54380edcdda07ea65b14105d82fd2c1a6f Mon Sep 17 00:00:00 2001 From: Christian Kaltenbach Date: Fri, 14 Aug 2026 15:34:08 +0200 Subject: [PATCH] PFM-ISSUE-34453 - github-actions: correct the node-version claim - most branches are on npm 11 Wording and documentation only; no predicate, exit code or control flow changes. bats 74/74, shellcheck clean. The previous correction (#164) said "runners pinned to node 18.19.1 are on npm 10" and "nothing fails in CI today". That generalised from release/25.2 - the branch checked out at the time - and from cplace-paw-fe, whose pipelines pin 25.2. Measured from the workflow files themselves: release/25.2 node 18.19.1 npm 10 release/25.3 25.4 26.1 26.2 26.3 master node 22.15.0 npm 11 So six of the seven branches were on the npm that drops the registry's path prefix, and un-normalized lockfiles there were failing - which is what design.md's Dimension 9 claimed in the first place. cplace-vwg-ptm-fe run 31167462200 is the report: E404 on update-browserslist-db, inside the composite's own npm ci, on node 22.15.0, against release/26.2. The advisory's job summary, the README, design.md and both overview editions now carry the per-branch table rather than a single sentence, so the fact cannot be generalised wrongly again. design.md keeps both corrections visible: the original claim, the over-correction, and this one. Verified after the rollout on the branches that run npm 11: cplace-paw-fe snapshot runs on release/25.4 (added 542 packages) and release/26.1 (added 558 packages), node 22.15.0, zero npm errors. Co-Authored-By: Claude Opus 5 (1M context) --- .../design.md | 25 ++++++++++++++----- .../overview.html | 20 +++++++++------ .../overview.md | 21 +++++++++++----- tools/scripts/lockfile/README.md | 23 ++++++++++++----- .../scripts/lockfile/warn-foreign-registry.sh | 5 ++-- 5 files changed, 66 insertions(+), 28 deletions(-) diff --git a/specs/2026-08-10_normalize-package-lock-resolved-urls/design.md b/specs/2026-08-10_normalize-package-lock-resolved-urls/design.md index 848ede9..b2116da 100644 --- a/specs/2026-08-10_normalize-package-lock-resolved-urls/design.md +++ b/specs/2026-08-10_normalize-package-lock-resolved-urls/design.md @@ -472,14 +472,27 @@ through the proxy): | **10.2.4** | runner, node 18.19.1 | installs | the **proxy** — the rewrite preserves its path prefix | | **11.3.0** | developer machine, node 22.15.0 | **`E404`** | — prefix dropped | -Every pipeline pins node 18.19.1 (this repo's reusable workflows; paw-fe's `.nvmrc`), so all of them are on npm 10, +~~Every pipeline pins node 18.19.1 (this repo's reusable workflows; paw-fe's `.nvmrc`), so all of them are on npm 10, and paw-fe's run history contains no failure of this shape. The original `E404` was real — it was reproduced on a -developer machine, where npm is newer. +developer machine, where npm is newer.~~ -**The consequence is a sequencing one:** the prefix drop is a *regression in newer npm*, so nothing breaks in CI today -and everything un-normalized breaks the moment runners move to node 24 / npm 11 -(`specs/2026-06-05_node24-workflow-migration`). Normalization is a **prerequisite for that migration**, not a cleanup -after it. +**Corrected again 2026-08-14, later the same day — the "not failing today" reading was wrong.** The node version is +pinned **per branch** by the reusable workflows, and only `release/25.2` is still on the old one: + +| branch | node pinned | npm | un-normalized behaviour | +| --- | --- | --- | --- | +| `release/25.2` | 18.19.1 | 10 | works without the flag | +| `release/25.3`, `25.4`, `26.1`, `26.2`, `26.3`, `master` | 22.15.0 | **11** | **fails** without the flag | + +The first correction generalised from `release/25.2` — the branch checked out at the time — and from `cplace-paw-fe`, +whose pipelines pin `25.2`. Six of the seven branches were on npm 11 and therefore **were** failing, which is what +Dimension 9 originally claimed. Confirmed by a real report: `cplace-vwg-ptm-fe` +[run 31167462200](https://github.com/collaborationFactory/cplace-vwg-ptm-fe/actions/runs/31167462200) failed on +`release/26.2` with `E404 … update-browserslist-db`, inside the composite's own `npm ci`, on node 22.15.0. + +**The consequence is still a sequencing one, but sharper:** the prefix drop is a regression in newer npm, and most +branches already run it. Normalization was overdue rather than pre-emptive, and it remains a **prerequisite** for the +rest of `specs/2026-06-05_node24-workflow-migration`. **And the mitigation's cost is unconditional.** Measured in the same runs: under `replace-registry-host=never` the tarball came from `registry.npmjs.org` (proxy fetches: 0) on *both* npm versions. On npm 11 that buys compatibility; diff --git a/specs/2026-08-10_normalize-package-lock-resolved-urls/overview.html b/specs/2026-08-10_normalize-package-lock-resolved-urls/overview.html index 12c662a..d31693b 100644 --- a/specs/2026-08-10_normalize-package-lock-resolved-urls/overview.html +++ b/specs/2026-08-10_normalize-package-lock-resolved-urls/overview.html @@ -316,13 +316,16 @@

The fix

The fix has two parts, and they attack the same rewrite from opposite ends.

- The version qualifier is load-bearing. Measured 2026-08-14 with a one-package fixture, on a - runner and locally: npm 10.2.4 — node 18.19.1, what every pipeline pins today — rewrites the - host onto the configured registry correctly and installs through the proxy, while - npm 11.3.0 — developer machines, and any runner on node 24 — drops the prefix and fails. The - prefix drop is a regression in newer npm: nothing is failing in CI today, and everything - un-normalized fails the moment runners move to node 24. That makes this work a prerequisite for the Node 24 - migration rather than a cleanup after it. + The version qualifier is load-bearing. Measured 2026-08-14 with a one-package fixture, on + a runner and locally: npm 10.2.4 rewrites the host onto the configured registry correctly and + installs through the proxy, while npm 11.3.0 drops the prefix and fails. The prefix + drop is a regression in newer npm — and which npm a pipeline gets is decided + per branch by the reusable workflows: only release/25.2 still pins node 18.19.1 + (npm 10); release/25.3, 25.4, 26.1, 26.2, + 26.3 and master all pin node 22.15.0, which is npm 11. Six of the seven branches + were therefore already failing on un-normalized lockfiles — as cplace-vwg-ptm-fe reported against + release/26.2: E404 on update-browserslist-db, inside the composite's own + npm ci. This work is a prerequisite for the rest of the Node 24 migration, not a cleanup after it.

@@ -448,7 +451,8 @@

replace-registry-host=never

- Lane 1 is npm 11; on npm 10.2.4 the same rewrite lands on the proxy correctly and installs. Lane 2 removes + Lane 1 is npm 11 — what release/25.3 and every newer branch pin; on npm 10.2.4 + (release/25.2 only) the same rewrite lands on the proxy correctly and installs. Lane 2 removes the rewrite; lane 3 removes the need for it. The pairing is what makes the rollout lazy rather than a coordinated switchover: on a normalized lockfile the flag changes nothing, so the two compose in either order and the flag can come out per branch — once the advisory stops reporting anywhere. diff --git a/specs/2026-08-10_normalize-package-lock-resolved-urls/overview.md b/specs/2026-08-10_normalize-package-lock-resolved-urls/overview.md index 0d6764d..7ae4caf 100644 --- a/specs/2026-08-10_normalize-package-lock-resolved-urls/overview.md +++ b/specs/2026-08-10_normalize-package-lock-resolved-urls/overview.md @@ -25,12 +25,20 @@ request 404s, and because that prefix is the `JFROG_URL` secret, CI prints the w | npm | un-normalized entry, no mitigation | tarball served by | | --- | --- | --- | -| 10.2.4 — node 18.19.1, what every pipeline pins today | installs | the **proxy**; the rewrite keeps the path prefix | -| 11.3.0 — developer machines, and any runner on node 24 | **`E404`** | — prefix dropped | +| 10.2.4 | installs | the **proxy**; the rewrite keeps the path prefix | +| 11.3.0 | **`E404`** | — prefix dropped | -So the prefix drop is a **regression in newer npm**: nothing is failing in CI today, and everything un-normalized -fails the moment runners move to node 24. That makes this work a **prerequisite for the Node 24 migration** rather -than a cleanup after it. +The prefix drop is a **regression in newer npm** — and which npm a pipeline gets is decided **per branch** by the +reusable workflows: + +| branch | node pinned | npm | un-normalized behaviour | +| --- | --- | --- | --- | +| `release/25.2` | 18.19.1 | 10 | works without the flag | +| `release/25.3`, `25.4`, `26.1`, `26.2`, `26.3`, `master` | 22.15.0 | **11** | **fails** without the flag | + +Six of the seven branches were already on npm 11, so un-normalized lockfiles **were** failing there — as +`cplace-vwg-ptm-fe` reported against `release/26.2`: `E404` on `update-browserslist-db`, inside the composite's own +`npm ci`. This work is a **prerequisite for the rest of the Node 24 migration**, not a cleanup after it. The fix has two parts, attacking the same rewrite from opposite ends: @@ -77,7 +85,8 @@ flowchart TB class C2,C3,C4 ok; ``` -Lane 1 is npm 11; on npm 10.2.4 the same rewrite lands on the proxy correctly and installs. Lane 2 removes the +Lane 1 is npm 11 — which is what `release/25.3` and every newer branch pin; on npm 10.2.4 (`release/25.2` only) +the same rewrite lands on the proxy correctly and installs. Lane 2 removes the rewrite; lane 3 removes the *need* for it. Because the flag is a no-op on a normalized lockfile, the two compose in either order and the flag can be dropped **per branch** rather than in a coordinated switchover — once the advisory stops reporting anywhere. diff --git a/tools/scripts/lockfile/README.md b/tools/scripts/lockfile/README.md index 7556a1b..55c341d 100644 --- a/tools/scripts/lockfile/README.md +++ b/tools/scripts/lockfile/README.md @@ -55,21 +55,32 @@ This tells npm to fetch each `resolved` URL **verbatim** rather than rewriting i It makes an un-normalized lockfile install on any npm version, so it protects **consumer** repositories too, not just this one. JFrog URLs stay authenticated by the secret, so it introduces no dependency on anonymous JFrog access. -**The rewrite it disables is only broken on newer npm.** Measured 2026-08-14 with a one-package fixture, on a runner -and locally: +**The rewrite it disables is broken on npm 11, not on npm 10.** Measured 2026-08-14 with a one-package fixture, on a +runner and locally: | npm | un-normalized entry, no mitigation | tarball served by | | --- | --- | --- | -| 10.2.4 (node 18.19.1 — what every pipeline pins today) | installs | the **proxy** — the rewrite keeps its path prefix | -| 11.3.0 (developer machines; any runner on node 24) | **`E404`**, masked as `***` | — prefix dropped | +| 10.2.4 | installs | the **proxy** — the rewrite keeps its path prefix | +| 11.3.0 | **`E404`**, masked as `***` | — prefix dropped | + +**Which npm a pipeline gets is decided per branch, and most branches are on the broken one.** The reusable workflows +pin the node version, and only `release/25.2` is still on the old one: + +| branch | node pinned | npm | un-normalized behaviour | +| --- | --- | --- | --- | +| `release/25.2` | 18.19.1 | 10 | worked without the flag | +| `release/25.3`, `25.4`, `26.1`, `26.2`, `26.3`, `master` | 22.15.0 | 11 | **failed** without the flag | + +That is not hypothetical: `cplace-vwg-ptm-fe` reported exactly this against `release/26.2` — `E404` on +`update-browserslist-db`, inside the composite's own `npm ci`, on node 22.15.0. **It is a mitigation, not the fix**, and it is not free on either version. Under it, an entry still pointing at `registry.npmjs.org` is fetched *directly from npmjs*, bypassing the proxy — no Xray, no curation. On npm 10 that is its only effect, because the rewrite it disables was working. On npm 11 it buys compatibility and spends proxy routing. Normalizing buys both: the entry resolves through the proxy on every version, flag or no flag. -**This is why the Node 24 migration depends on the rollout, not the other way round.** Nothing fails in CI today; -everything un-normalized fails the moment runners move to npm 11. +**The Node 24 migration and this rollout are the same problem.** Six of the seven branches already run npm 11, which +is why un-normalized lockfiles were failing there before this landed. Because of that, `use-npmrc` also runs `warn-foreign-registry.sh` against the consumer's own `package-lock.json` and emits a `::warning` annotation plus a job summary listing the offending package paths. **Those warnings are the diff --git a/tools/scripts/lockfile/warn-foreign-registry.sh b/tools/scripts/lockfile/warn-foreign-registry.sh index a26ca42..c20a130 100755 --- a/tools/scripts/lockfile/warn-foreign-registry.sh +++ b/tools/scripts/lockfile/warn-foreign-registry.sh @@ -87,8 +87,9 @@ main() { printf 'What would happen without that flag depends on the npm version: **npm 10.2.4** rewrites the ' printf 'host onto the configured registry correctly, and the entry resolves *through* the proxy; ' printf '**npm 11.3.0** drops the path prefix and fails with an `E404` masked as `***`. Both measured ' - printf '2026-08-14. Runners pinned to node 18.19.1 are on npm 10; developer machines, and any runner ' - printf 'moving to node 24, are not.\n\n' + printf '2026-08-14. Only `release/25.2` still pins node 18.19.1 (npm 10) - `release/25.3` and every ' + printf 'newer branch pin node 22.15.0, which is npm 11. So most pipelines are on the version that ' + printf 'fails, and un-normalized entries there depend on this flag.\n\n' printf 'Fix by normalizing the lockfile onto the proxy (PFM-ISSUE-34453) - it then resolves through ' printf 'the proxy on every npm version, with or without the flag, and the mitigation can be removed ' printf 'once no lockfile reports this.\n\n'