chore(pnpm): migrate recce to pnpm v11 + Node ≥24 (DRC-3439)#1374
Conversation
- Bump packageManager to pnpm@11.1.1 (exact semver + integrity hash) - Move overrides + onlyBuiltDependencies from js/package.json#pnpm into js/pnpm-workspace.yaml as overrides + unified allowBuilds map - Add 3 false entries to allowBuilds for previously-silently-skipped postinstalls (@parcel/watcher, @sentry/cli, esbuild) — preserves pre-migration behavior; flip to true if anything regresses - Bump 6 GH workflows to pnpm/action-setup@v6 with version: 11 - Delete deprecated build-statics.yaml (replaced by nightly.yaml, past its 2026-02-01 removal date) - Document pnpm v11 strictDepBuilds + allowBuilds gotchas in AGENTS.md (cross-references recce-cloud-infra/recce-cloud/pnpm-workspace.yaml) Follows the recce-cloud-infra migration (PR #1316). Out of scope: recce-landing (deferred), @vitejs/plugin-react 6.0 (deferred via Dependabot #1340 — requires Vite 8). Co-Authored-By: Claude <noreply@anthropic.com> Signed-off-by: Jared Scott <jared.scott@datarecce.io>
Code Review: PR #1374SHA Issues
Notes
|
There was a problem hiding this comment.
Pull request overview
Migrates the frontend toolchain to pnpm v11 (with Node.js ≥24) and updates repo/CI configuration accordingly, including moving pnpm workspace configuration into pnpm-workspace.yaml and regenerating the lockfile under pnpm 11.
Changes:
- Move pnpm
overridesand build allowlisting tojs/pnpm-workspace.yamland pinjs/package.json#packageManagerto pnpm@11.1.1. - Regenerate
js/pnpm-lock.yamlunder pnpm 11. - Update GitHub Actions workflows to use
pnpm/action-setup@v6and delete the deprecatedbuild-statics.yamlworkflow.
Reviewed changes
Copilot reviewed 10 out of 11 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| js/pnpm-workspace.yaml | Adds workspace-level overrides and allowBuilds configuration for pnpm v11. |
| js/pnpm-lock.yaml | Regenerated lockfile under pnpm 11 (includes resolution changes). |
| js/package.json | Pins Corepack packageManager to pnpm@11.1.1 and removes the old pnpm config block. |
| AGENTS.md | Documents pnpm v11 behaviors (strict dep builds + allowBuilds workflow). |
| .github/workflows/tests-python.yaml | Updates pnpm setup action/version for CI jobs that build frontend assets. |
| .github/workflows/tests-js.yaml | Updates pnpm setup action/version for JS lint/test/build CI. |
| .github/workflows/release.yaml | Updates pnpm setup action/version for release builds. |
| .github/workflows/release-ui.yaml | Updates pnpm setup action/version for UI publishing workflow. |
| .github/workflows/nightly.yaml | Updates pnpm setup action/version for nightly builds. |
| .github/workflows/address-dependabot.yaml | Updates pnpm setup action/version for dependabot consolidation workflow. |
| .github/workflows/build-statics.yaml | Deletes deprecated workflow in favor of the nightly replacement. |
Files not reviewed (1)
- js/pnpm-lock.yaml: Language not supported
Comments suppressed due to low confidence (2)
.github/workflows/tests-js.yaml:66
pnpm/action-setupis configured withversion: 11, which can float to different pnpm 11.x releases over time and diverge from the repo’s pinnedpackageManager(pnpm@11.1.1). Pin this to the exact version used by the workspace to keep CI installs reproducible and prevent lockfile churn.
- uses: pnpm/action-setup@v6
with:
version: 11
run_install: false
.github/workflows/tests-python.yaml:123
pnpm/action-setupis configured withversion: 11, which can float to different pnpm 11.x releases over time and diverge from the repo’s pinnedpackageManager(pnpm@11.1.1). Pin this to the exact version used by the workspace to keep CI installs reproducible and prevent lockfile churn.
- uses: pnpm/action-setup@v6
with:
version: 11
run_install: false
The actual packageManager integrity format uses `.` between `sha512` and the hash (e.g. `pnpm@11.1.1+sha512.d1fdf5f...`), not `:`. A future agent copy-pasting from the docs would hit corepack rejection — the exact failure mode this section was added to prevent. Co-Authored-By: Claude <noreply@anthropic.com> Signed-off-by: Jared Scott <jared.scott@datarecce.io>
|
Both ISSUEs addressed.
Notes 3 (allowBuilds |
Match the workspace's `packageManager` pin to keep CI installs reproducible. `version: 11` would float across pnpm 11.x patch releases; in practice corepack inside the project shadows that anyway via the `packageManager` pin, but having two different version strings in two places is the kind of drift waiting to happen that pnpm 11's defaults are designed to eliminate. Co-Authored-By: Claude <noreply@anthropic.com> Signed-off-by: Jared Scott <jared.scott@datarecce.io>
Code Review: PR #1374 (re-review)SHA All four Issues from the prior re-review are resolved by
Sweep for residual Cross-reference on new "pnpm@11.1.1 (pinned via Corepack)" claim in Quality gates skipped on this incremental: change is pure markdown, Notes from the prior review ( |
wcchang1115
left a comment
There was a problem hiding this comment.
See review comment for details. NO-GO: stale Copilot/agent docs (AGENTS.md:127, .github/copilot-instructions.md, .github/instructions/frontend-instructions.md, docs/architecture.md:12) still pin pnpm 10 / Node ≥20, contradicting the PR's 'Node ≥24 everywhere' invariant. Core pnpm v11 mechanics LGTM.
Addresses wcchang1115's NO-GO re-review on PR #1374 — four agent-facing docs still pinned the old pnpm 10 / Node ≥20 toolchain, contradicting the PR's "Node ≥24 everywhere" invariant. Copilot/agent custom-instruction files steer code suggestions, so leaving them stale would have actively worked against the migration. - AGENTS.md:127 — tech-stack table now reads "Node.js 24+". - .github/copilot-instructions.md — pnpm 10 → 11 install hint, Node >=20 → >=24 build-error hint, and the package.json layout comment. - .github/instructions/frontend-instructions.md — pnpm 10 → 11 in the package-manager directive, tech-stack list, file-structure layout, config notes (Uses pnpm@11.1.1 pinned via Corepack), CI checklist, and Node upgrade fix hint. - docs/architecture.md:12 — tech-stack table now reads "Node.js 24+". No-code/docs-only change. Historical references in docs/plans/* and the `pnpm 10 was silently skipping these` comment in js/pnpm-workspace.yaml intentionally preserved — they describe the pre-migration baseline. Signed-off-by: Jared Scott <jared.scott@reccehq.com> Co-Authored-By: Claude <noreply@anthropic.com> Signed-off-by: Jared Scott <jared.scott@datarecce.io>
|
All four stale-doc issues addressed in
Verification:
Notes 1–3 from the re-review are informational; no changes needed. Note 1 ( |
wcchang1115
left a comment
There was a problem hiding this comment.
Re-review for SHA b058a4d — all four prior NO-GO Issues resolved. Updated review comment: #1374 (comment)
…me extraction - Correct sister-repo PR references: #1376 → #1374 on lines 13 and 66. (#1376 is an unrelated docs PR; #1374 is the actual Dependabot consolidation re-bump.) Spotted by Copilot and @even-wei. - Harden the staged-version extraction (Copilot, @even-wei Note 1): add `head -1` so a future second `"@biomejs/biome":` occurrence (e.g., a pnpm.overrides entry) doesn't yield multi-line output, and fail-loud when extraction is empty so a package.json reformat or intentional dep removal can no longer silently disable the guard. `ALLOW_BIOME_BUMP=1` still overrides both the mismatch and the empty-extraction paths. - Align `--diff-filter=ACM` with the existing JS lint detector below for consistency (@even-wei Note 2). Verified locally via index-blob swap on macOS arm64: 1. 2.4.99 staged, no override → exit 1, updated error cites #1374 2. 2.4.99 staged + ALLOW_BIOME_BUMP=1 → exit 0 3. 2.4.15 staged (current) → exit 0 4. @biomejs/biome key removed → exit 1, "Could not extract" message 5. @biomejs/biome key removed + ALLOW_BIOME_BUMP=1 → exit 0 `bash -n` clean; `shellcheck -S warning` silent on the guard block. Signed-off-by: Jared Scott <jared.scott@reccehq.com> Co-Authored-By: Claude <noreply@anthropic.com> Signed-off-by: Jared Scott <jared.scott@datarecce.io>
…1404) * chore(husky): add pre-commit guard for pinned @biomejs/biome version The sister recce-cloud-infra repo has now been bitten twice (PRs #1333, #1376, #1382) by Dependabot consolidations silently re-bumping a deliberate @biomejs/biome pin past a known Mac arm64 stack-overflow bug in 2.4.12 through 2.4.15. The js/biome.json in this repo does not currently enable the affected nursery rules (noFloatingPromises, noMisusedPromises, noUnnecessaryConditions), so the bug has not bitten here yet, but the same consolidation pattern applies, and silent bumps are easy to miss in lockfile-heavy PRs. Add a pre-commit guard that reads the staged content of js/package.json, checks the @biomejs/biome version against an EXPECTED_BIOME constant (currently 2.4.15, the version this repo runs on today), and blocks the commit on a mismatch with a clear remediation message. Override with ALLOW_BIOME_BUMP=1 after verifying biome runs cleanly on macOS arm64 with the nursery rules enabled. No biome version change here, only the guard. When biome is deliberately bumped, update EXPECTED_BIOME in this hook in the same commit. Signed-off-by: Jared Scott <jared.scott@datarecce.io> * chore(husky): address PR #1404 review — fix infra PR refs, harden biome extraction - Correct sister-repo PR references: #1376 → #1374 on lines 13 and 66. (#1376 is an unrelated docs PR; #1374 is the actual Dependabot consolidation re-bump.) Spotted by Copilot and @even-wei. - Harden the staged-version extraction (Copilot, @even-wei Note 1): add `head -1` so a future second `"@biomejs/biome":` occurrence (e.g., a pnpm.overrides entry) doesn't yield multi-line output, and fail-loud when extraction is empty so a package.json reformat or intentional dep removal can no longer silently disable the guard. `ALLOW_BIOME_BUMP=1` still overrides both the mismatch and the empty-extraction paths. - Align `--diff-filter=ACM` with the existing JS lint detector below for consistency (@even-wei Note 2). Verified locally via index-blob swap on macOS arm64: 1. 2.4.99 staged, no override → exit 1, updated error cites #1374 2. 2.4.99 staged + ALLOW_BIOME_BUMP=1 → exit 0 3. 2.4.15 staged (current) → exit 0 4. @biomejs/biome key removed → exit 1, "Could not extract" message 5. @biomejs/biome key removed + ALLOW_BIOME_BUMP=1 → exit 0 `bash -n` clean; `shellcheck -S warning` silent on the guard block. Signed-off-by: Jared Scott <jared.scott@reccehq.com> Co-Authored-By: Claude <noreply@anthropic.com> Signed-off-by: Jared Scott <jared.scott@datarecce.io> --------- Signed-off-by: Jared Scott <jared.scott@datarecce.io> Signed-off-by: Jared Scott <jared.scott@reccehq.com> Co-authored-by: Claude <noreply@anthropic.com>
Summary
Migrates
reccefrom pnpm v10.30.3 → pnpm v11.1.1, baselines Node ≥24 everywhere, and adopts the v11 config layout. Follows recce-cloud-infra's migration (PR #1316).Linear: DRC-3439
Changes
Configuration migration
js/package.json#pnpmblock removed — content moved tojs/pnpm-workspace.yamljs/pnpm-workspace.yaml: gainsoverrides(46 entries, verbatim from the priorpackage.jsonblock) and a unifiedallowBuildsmapjs/package.json#packageManager: pinned to exactpnpm@11.1.1+sha512.<integrity>(corepack rejects barepnpm@11; the separator betweensha512and the hash is a., not:)js/pnpm-lock.yaml: regenerated under pnpm 11.1.1. Direct dep resolved versions unchanged (react@19.2.6,next@16.2.6,@mui/material@9.0.1,@sentry/nextjs@10.53.1). Transitive deps refreshed within their caret ranges as a side-effect of the regeneration — see "Lockfile drift" below.Lockfile drift (transitive deps)
Regenerating under pnpm 11 picked up the latest within-range versions for transitive deps that pnpm 10 had been freezing. Notable changes:
@sentry/react/@sentry-internal/*/@sentry/{browser,core}10.49.010.53.1@sentry/nextjs@10.53.1pin@amplitude/rrweb2.1.12.1.0@amplitude/unified@1.1.5pinned this transitive lower@amplitude/experiment-{core,js-client}0.13.0/1.21.00.13.1/1.21.1vite7.3.27.3.3@babel/{compat-data,helper-string-parser,parser}7.29.0/8.0.0-rc.3/7.29.27.29.3/8.0.0-rc.4/7.29.3@codemirror/{autocomplete,lint,search}6.20.1/6.9.5/6.6.06.20.2/6.9.6/6.7.0@inquirer/{confirm,core}6.0.12/11.1.96.0.13/11.1.10@mswjs/interceptors0.41.40.41.9@rolldown/binding-*@1.0.0(16 platform pkgs),@rolldown/pluginutils@1.0.0,@oxc-project/types@0.129.0All within their declared caret ranges; the quality gates (
pnpm lint/type:check/test3708 passed /build) cover them. Listing here so reviewers can see the actual change surface.allowBuildsdecisions@tailwindcss/oxidetrueonlyBuiltDependenciesmswtruesharptrueunrs-resolvertrue@parcel/watcherfalsefalseis safe. Flip totrueif regressions appear.@sentry/clifalse@sentry/cli-{darwin,linux,…}packages ship Mach-O / ELF binaries directly.esbuildfalse@esbuild/<platform>-<arch>packages ship native binaries directly.CI workflows (6 bumped + 1 deleted)
tests-js.yamlpnpm/action-setup@v4→@v6,version: 10→11(2 jobs)tests-python.yamlnightly.yamlrelease.yamlrelease-ui.yamladdress-dependabot.yamlbuild-statics.yamlnightly.yamlis the replacement)Documentation
AGENTS.md: new "pnpm v11 — strictDepBuilds + allowBuilds" section cross-referencing recce-cloud-infra's canonical examplesVerification
CI=true pnpm install --frozen-lockfile→ clean (no ignored builds, no placeholder lines appended)pnpm lint/pnpm type:check→ cleanpnpm test→ 3708 passed / 5 skipped / 156 files (matches pre-migration baseline)pnpm run build→ static export OKmake format/make flake8→ cleanpython3 -m pytest tests→ 1206 passed (matches baseline)Out of scope
recce-landing(separate work; the issue notes "leave on npm unless there's a concrete reason to migrate")@vitejs/plugin-react6.0 (deferred via Dependabot chore(deps): bump @vitejs/plugin-react from 5.2.0 to 6.0.1 in /js #1340 — requires Vite 8)Test plan
CI=true pnpm install --frozen-lockfileexits 0: set this to true or falselines inpnpm-workspace.yamlpnpm-lock.yamlmatch pre-migration (transitive deps refreshed within caret ranges — see Lockfile drift table)