chore: migrate to pnpm (#4762)
* chore: migrate package manager from yarn to pnpm Switch from Yarn Classic (1.22, EOL) to pnpm for stricter dependency isolation, better lockfile integrity, and continued upstream security fixes. Repo-level changes: - Add pnpm-workspace.yaml; remove the `workspaces` field from package.json (pnpm uses the yaml exclusively) - Delete yarn.lock and .yarnrc; commit pnpm-lock.yaml - Set packageManager to pnpm@11.1.0 with sha512 integrity for corepack - Add engines.pnpm so npm/yarn invocations get a clear engine warning - Add pnpm to .mise.toml - lerna.json: npmClient -> pnpm - Root scripts (reinstall, start) and husky pre-commit hook switched from yarn to pnpm - Add @types/node to root devDependencies so tsconfig "types": ["node"] resolves under pnpm's strict layout (was previously hoisted from workspaces in yarn classic) Workspace packages: all internal cross-package deps switched to the `workspace:^` protocol so pnpm links the local copy. External dep versions are unchanged. Install scripts: - pnpm 11 denies install scripts by default; allowlist is in pnpm-workspace.yaml (allowBuilds). Three known builders are listed with explicit `false` decisions; security hardening commits may flip individual entries with a documented reason. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * ci: switch CI workflows, Dockerfiles, and docs to pnpm CI workflows: - All jobs add a pnpm/action-setup@v4 step before setup-node so the node cache uses the pnpm store. pnpm version is sourced from package.json `packageManager` field. - yarn install --frozen-lockfile -> pnpm install --frozen-lockfile - commitlint job invokes the CLI via `node @commitlint/cli/cli.js` because pnpm's strict layout does not symlink workspace binaries to the root node_modules/.bin/ (matches the .husky/commit-msg pattern). - baseline-apt job installs Node from apt and pnpm via corepack (corepack ships with Node >=16.10). Dockerfiles: - Dockerfile.ci and Dockerfile.dev enable corepack and call pnpm. - npm pack of the published @commitlint/* packages is unchanged (it fetches from the registry, independent of the local lockfile). Docs: - README and CONTRIBUTING switched to pnpm commands. - CONTRIBUTING adds an admonition for contributors with pre-pnpm local clones: a one-time node_modules cleanup and pointers to mise / corepack / direct pnpm install. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore: declare @commitlint/utils where pkg-check is used @commitlint/load and @commitlint/top-level have pkg/deps scripts that invoke the pkg-check / dep-check binaries provided by @packages/utils (published name: @commitlint/utils) but neither package listed it as a devDependency. Resolves today only because yarn classic hoists the binary to the root; under pnpm's strict layout it is not visible from the workspace. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(utils): use pnpm pack in pkg-check The hardcoded `yarn pack --filename` invocation in pkg-check fails without yarn on PATH. Switch to `pnpm pack --pack-destination` and parse the produced filename from stdout — pnpm prints the absolute path of the tarball, so the basename is joined with the temp dir we passed as the destination. Note: pkg-check is invoked manually at release time, not in CI. The PRELUDE-based import test has separate pre-existing issues under pnpm's tarball contents; addressing those is out of scope for this commit. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * ci: install pnpm via npm in baseline-apt job Ubuntu's stock corepack (bundled with apt-installed Node) trips on the dynamic ESM imports pnpm 11 uses at launch and throws ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING. Skip corepack for this job and install pnpm directly via npm, pulling the version from the packageManager field so it stays in sync. This keeps the job honest about what we're testing — "stock apt plus one explicit pnpm install" — instead of pretending stock Ubuntu corepack works with current pnpm. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore: tighten pnpm supply-chain settings Three additions to .npmrc, each defensive against a different failure class: - strict-dep-builds=true: turn the "unapproved install script" warning into a hard error. A new transitive dep that ships a postinstall now blocks install until someone explicitly decides whether to allow it in pnpm-workspace.yaml's allowBuilds. - verify-deps-before-run=error: refuse to run pnpm scripts when node_modules diverges from the lockfile. Catches the "edited package.json, forgot to reinstall" class of drift. - resolution-mode=time-based: when resolving a version range, prefer the version that was current as of the most-recent direct dep publish. Limits exposure to a compromised brand-new release of a transitive dep. All three are config-only; the existing lockfile and node_modules state already satisfy them, so install + build + test pass unchanged (1188/1188). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(renovate): rename stale ignoreDeps entry @commitlint/test-environment no longer exists — the package was renamed to vitest-environment-commitlint. Renovate was silently ignoring nothing; rename the entry so the internal-package safety net actually covers it. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(renovate): config:recommended + weekly lockfile maintenance - Rename the deprecated config:base preset to config:recommended (renovate's recommended modern equivalent). - Enable lockFileMaintenance with a weekly Monday-morning schedule. Pairs with resolution-mode=time-based: the periodic refresh becomes the explicit moment new transitive versions get adopted, instead of drifting in on each direct-dep range bump. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore: address copilot review feedback Four small nits, none of which change behaviour for the green path: - README: the inline comment for `pnpm start` claimed "run tests, again on change" but the script maps to `tsc -b --watch`. Reword to match reality. - .npmrc: drop legacy-peer-deps=true. It was added in 2022 for npm/yarn-era peer-dep handling; pnpm 11 auto-installs peers, the full suite passes without it, and corepack now blocks accidental `npm install` so the legacy flag has no remaining purpose. - package.json: tighten engines.pnpm from >=10 to >=11. The repo uses pnpm-11-only features (allowBuilds in pnpm-workspace.yaml, verify-deps-before-run=error). - .mise.toml: pin Node to 22.12.0 to match engines.node, instead of the looser "22" which mise resolves to the latest 22.x at install. Lockfile reshuffles slightly under resolution-mode=time-based now that legacy-peer-deps is gone — net reduction in graph size. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore: enforce node engines via pnpm instead of pinning in mise Replace the exact node = "22.12.0" pin (rejects auto-bumped patch releases) with the broader node = "22" plus engine-strict=true in .npmrc. mise serves the latest 22.x stable (currently well above 22.12), and pnpm now hard-fails install when engines.node / engines.pnpm aren't met — turning those fields from soft advisories into real floors. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(mise): relax pnpm pin to major-only Same reasoning as the node = "22" relaxation: the exact in-project pnpm version is already enforced by the packageManager field + corepack + engines.pnpm + engine-strict. mise just needs "some modern 11.x", not a specific patch. Removes the false-positive "missing: pnpm@11.1.0" warning when contributors already have another 11.x installed. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * ci: bump pnpm/action-setup v4 -> v6 pnpm 11.1.0 requires Node >=22.13. action-setup@v4 runs on a bundled Node 20, so its `npm install -g pnpm@11.1.0` step fails with ERR_PNPM_UNSUPPORTED_ENGINE before it ever touches the matrix Node. v6 ships Node 24 and resolves it; also clears the deprecation warning about Node 20 actions. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
E
escapedcat committed
1329a25fd6f13b993fdf4e8c1b5a25ff2bf7ee07
Parent: f8be069
Committed by GitHub <noreply@github.com>
on 5/12/2026, 1:48:55 PM