Skip to content

chore: upgrade pnpm 9 → 11 with supply-chain protection#235

Open
cameronapak wants to merge 2 commits into
mainfrom
chore/pnpm-11-upgrade-supply-chain-protection
Open

chore: upgrade pnpm 9 → 11 with supply-chain protection#235
cameronapak wants to merge 2 commits into
mainfrom
chore/pnpm-11-upgrade-supply-chain-protection

Conversation

@cameronapak
Copy link
Copy Markdown
Collaborator

@cameronapak cameronapak commented May 12, 2026

The recent news of seeing more and more supply-chain attacks via npm has caused me to want to make sure we're as secure as can be. That's what this PR does.

Summary

  • Upgrade pnpm 9.0.0 → 11.1.1 with minimumReleaseAge: 4320 (3-day cooldown) to mitigate supply-chain attacks on new package versions
  • Move overrides from package.jsonpnpm-workspace.yaml (pnpm 11 breaking change — overrides in package.json no longer enforce for auto-installed peers)
  • Remove version pins from all CI workflows — pnpm/action-setup@v4 now reads from packageManager field (single source of truth)

Changes

File Change
package.json packageManager: "pnpm@11.1.1", engines.pnpm: ">=11.0.0", removed pnpm.overrides, added @internal/eslint-config + eslint-plugin-storybook as root devDeps
pnpm-workspace.yaml Added minimumReleaseAge, overrides, allowBuilds
.github/workflows/ci.yml Removed 4x version: 9.0.0 pins
.github/workflows/release.yml Removed version: 9.0.0 pin
.github/workflows/storybook.yml Removed version: 9.0.0 pin
AGENTS.md Updated pnpm version refs, added supply-chain protection docs

pnpm 11 breaking changes handled

  • Overrides must live in pnpm-workspace.yaml (not package.json) to enforce for auto-installed peers
  • Build scripts require allowBuilds approval (esbuild, @parcel/watcher, msw)
  • Workspace packages not hoisted to root — @internal/eslint-config and eslint-plugin-storybook must be root devDependencies
  • minimumReleaseAge blocks packages published < 3 days ago; override with --force if needed urgently

Verification

  • pnpm lint — all 7 packages pass
  • pnpm typecheck — all 6 packages pass
  • pnpm test — 88 tests pass (core: 288, hooks: 261, ui: 88)

Greptile Summary

This PR upgrades pnpm 9 → 11.1.1 across the monorepo, migrating overrides to pnpm-workspace.yaml, adding a 3-day minimumReleaseAge supply-chain guard, and bumping all CI workflows from Node 20 → 22 with pnpm version now read from the packageManager field.

  • pnpm-workspace.yaml: Receives the overrides block previously in package.json, a minimumReleaseAge: 4320 guard, and allowBuilds entries for esbuild, @parcel/watcher, and msw (all required for pnpm 11's stricter postinstall approval).
  • CI workflows: All four jobs in ci.yml, plus release.yml and storybook.yml, drop their hardcoded version: 9.0.0 pins — pnpm/action-setup@v4 now reads the version from the packageManager field, establishing a single source of truth.
  • pnpm-lock.yaml: Resolution changes include vite bumped to 7.3.3, esbuild bumped to 0.27.7, and @swc/core / terser dropped as satisfied tsup/vite peers (noted in a previous review comment).

Confidence Score: 5/5

Safe to merge — the toolchain upgrade is well-scoped and all tests, lint, and typecheck pass.

The changes are a clean toolchain bump with no application logic touched. Overrides, allowBuilds, and minimumReleaseAge are correctly configured for pnpm 11. The only discrepancy is that engines.node declares >=22.0.0 while AGENTS.md notes pnpm 11 actually needs >=22.13 — this surfaces as a pnpm-level error rather than silent misbehavior, so it does not block merging.

package.json — the engines.node floor (22.0.0) is looser than pnpm 11's actual Node requirement (22.13); worth tightening before a developer runs into a confusing error.

Important Files Changed

Filename Overview
package.json Bumps packageManager to pnpm@11.1.1 with SHA512 integrity hash, raises engines.node to >=22.0.0/pnpm to >=11.0.0, removes pnpm.overrides block, and hoists @internal/eslint-config + eslint-plugin-storybook to root devDeps. engines.node is too permissive vs pnpm 11's actual Node >=22.13 requirement.
pnpm-workspace.yaml Adds minimumReleaseAge supply-chain guard (4320 min = 3 days), migrates overrides from package.json, and adds allowBuilds for esbuild/@parcel/watcher/msw; all correctly formatted for pnpm 11.
.github/workflows/ci.yml Removes hardcoded pnpm version pins (now read from packageManager field), bumps Node from 20 to 22 across all four jobs.
.github/workflows/release.yml Removes hardcoded pnpm 9.0.0 pin; pnpm version now sourced from packageManager field automatically.
.github/workflows/storybook.yml Removes hardcoded pnpm 9.0.0 pin, bumps Node from 20 to 22; no other changes.
AGENTS.md Updates Node/pnpm version refs, documents supply-chain protection and pnpm 11 breaking changes; internally notes the Node >=22.13 pnpm requirement which contradicts the engines.node >=22.0.0 in package.json.
.npmrc Removes a now-stale comment line; no functional change.
pnpm-lock.yaml Reflects dependency graph changes from pnpm 11 resolution: vite bumped to 7.3.3, esbuild bumped to 0.27.7, terser and @swc/core dropped as resolved peers, new workspace-level eslint packages added.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["packageManager field\npnpm@11.1.1+sha512"] --> B["pnpm/action-setup@v4\n(reads packageManager)"]
    B --> C["pnpm install\n--frozen-lockfile"]
    C --> D{"minimumReleaseAge\n4320 min check"}
    D -->|"Package < 3 days old"| E["Install blocked\n(use --force to override)"]
    D -->|"Package >= 3 days old"| F["Proceed with install"]
    F --> G["allowBuilds check\n(@parcel/watcher, esbuild, msw)"]
    G --> H["overrides enforced\n(pnpm-workspace.yaml)\nreact 19.1.2 / vite >=5.4.21"]
    H --> I["Build & Test\npnpm build / pnpm test"]
Loading

Comments Outside Diff (1)

  1. pnpm-lock.yaml, line 194-195 (link)

    P2 @swc/core no longer resolved as a tsup peer

    Across every package (root, packages/core, packages/hooks, packages/ui), tsup@8.5.0 previously resolved with @swc/core@1.13.5 as a satisfied peer; after this upgrade it resolves without it. This means tsup will now use esbuild as its transformer instead of SWC. If any package's tsup.config.ts explicitly sets esbuildOptions or SWC-specific options, behaviour changes silently. The test suite passing is reassuring, but it's worth confirming no tsup.config references experimentalDts or similar options that behaved differently under SWC.

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: pnpm-lock.yaml
    Line: 194-195
    
    Comment:
    **`@swc/core` no longer resolved as a `tsup` peer**
    
    Across every package (`root`, `packages/core`, `packages/hooks`, `packages/ui`), `tsup@8.5.0` previously resolved with `@swc/core@1.13.5` as a satisfied peer; after this upgrade it resolves without it. This means tsup will now use esbuild as its transformer instead of SWC. If any package's `tsup.config.ts` explicitly sets esbuildOptions or SWC-specific options, behaviour changes silently. The test suite passing is reassuring, but it's worth confirming no `tsup.config` references `experimentalDts` or similar options that behaved differently under SWC.
    
    How can I resolve this? If you propose a fix, please make it concise.

    Fix in Claude Code Fix in Cursor

Fix All in Claude Code Fix All in Cursor

Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 1
package.json:7
**`engines.node` contradicts pnpm 11's actual minimum**

`AGENTS.md` (updated in this same PR) explicitly notes "pnpm 11 requires Node >= 22.13", but `engines.node` here is set to `>=22.0.0`. A developer who installs Node 22.0.0–22.12.x will see the engines constraint pass, then receive an opaque failure from pnpm 11 refusing to run. Consider tightening this to `>=22.13.0` to surface the real constraint upfront.

Reviews (2): Last reviewed commit: "fix: bump Node to 22 in CI, remove redun..." | Re-trigger Greptile

- Upgrade pnpm 9.0.0 → 11.1.1 (packageManager, engines, corepack)
- Add minimumReleaseAge: 4320 (3-day cooldown) to pnpm-workspace.yaml
- Move overrides from package.json → pnpm-workspace.yaml (pnpm 11 requirement)
- Add @internal/eslint-config and eslint-plugin-storybook as root devDeps
- Add allowBuilds for esbuild, @parcel/watcher, msw
- Remove version pins from CI workflows (reads from packageManager field)
- Update AGENTS.md with pnpm 11 refs and supply-chain docs
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 12, 2026

⚠️ No Changeset found

Latest commit: fcc24a0

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Comment thread pnpm-workspace.yaml Outdated
@cameronapak cameronapak marked this pull request as draft May 12, 2026 15:02
- Bump node-version from 20 → 22 in ci.yml and storybook.yml (pnpm 11 requires Node >= 22.13)
- Bump engines.node from >=20 → >=22 in package.json
- Remove minimumReleaseAgeExclude — workspace packages bypass the gate inherently
- Update AGENTS.md Node requirement references
@cameronapak cameronapak marked this pull request as ready for review May 12, 2026 15:26
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.

1 participant