Skip to content

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

Open
cameronapak wants to merge 4 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 4 commits into
mainfrom
chore/pnpm-11-upgrade-supply-chain-protection

Conversation

@cameronapak

@cameronapak cameronapak commented May 12, 2026

Copy link
Copy Markdown
Collaborator

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 from 9.0.0 to 11.1.1 and adds supply-chain protection (minimumReleaseAge: 4320) to block packages published within the last 3 days, while handling all required pnpm 11 breaking changes.

  • Moves pnpm.overrides from package.json to pnpm-workspace.yaml so they apply to auto-installed peers, and adds allowBuilds for the three packages (esbuild, @parcel/watcher, msw) that need native build scripts.
  • Removes explicit version: 9.0.0 pins from all CI workflows so pnpm/action-setup@v4 reads the single source of truth from the packageManager field (now with SHA-512 integrity hash).
  • Bumps Node from 20 → 22 across CI and raises engines.node to >=22.0.0, matching pnpm 11's runtime requirement.

Confidence Score: 5/5

Safe to merge — this is a well-scoped tooling upgrade with all pnpm 11 breaking changes explicitly handled.

All three workflow files correctly delegate pnpm version resolution to the packageManager field, overrides are properly migrated to pnpm-workspace.yaml, allowBuilds covers the packages that need build scripts, and the minimumReleaseAge supply-chain guard is correctly configured. The only nit is that engines.node could be tightened to match what pnpm 11 actually requires, as documented in AGENTS.md.

package.json — engines.node could be tightened from >=22.0.0 to >=22.13.0 to match the runtime requirement documented in AGENTS.md.

Important Files Changed

Filename Overview
pnpm-workspace.yaml Adds minimumReleaseAge (3-day cooldown), moves overrides from package.json, and adds allowBuilds for esbuild/@parcel/watcher/msw — all correct pnpm 11 patterns.
package.json Bumps packageManager to pnpm@11.1.1 with SHA-512 integrity hash, raises engines.node to >=22.0.0, removes pnpm.overrides block, and adds @internal/eslint-config and eslint-plugin-storybook as root devDeps.
.github/workflows/ci.yml Removes explicit pnpm version pins from all 4 jobs (letting action-setup@v4 read from packageManager field) and bumps Node from 20 to 22.
.github/workflows/release.yml Removes pnpm version pin — action-setup@v4 now reads from packageManager. Node version (24) was pre-existing and unchanged.
.github/workflows/storybook.yml Removes pnpm version pin and bumps Node from 20 to 22; runs inside a Playwright container so no pnpm cache is configured (pre-existing behaviour).
AGENTS.md Updates pnpm and Node version references and documents supply-chain protection rules, allowBuilds rationale, and the minimumReleaseAge --force escape hatch.
.npmrc Only change is removing a comment line — no functional change.
pnpm-lock.yaml Regenerated for pnpm 11; @swc/core is no longer resolved as a satisfied tsup peer, which shifts tsup to esbuild as its transformer.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Developer or CI pushes code] --> B[pnpm action-setup v4]
    B --> |reads packageManager field| C[pnpm 11.1.1 installed]
    C --> D{pnpm install}
    D --> |package published less than 3 days ago| E[Blocked by minimumReleaseAge]
    D --> |package published 3 or more days ago| F[Install proceeds]
    D --> |workspace packages| F
    F --> G{allowBuilds check}
    G --> |esbuild, parcel-watcher, msw| H[Build scripts allowed]
    G --> |all other packages| I[Build scripts blocked]
    H --> J[overrides applied from pnpm-workspace.yaml]
    I --> J
    J --> |react 19.1.2 and vite 5.4.21 plus| K[Dependency tree resolved]
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
    A[Developer or CI pushes code] --> B[pnpm action-setup v4]
    B --> |reads packageManager field| C[pnpm 11.1.1 installed]
    C --> D{pnpm install}
    D --> |package published less than 3 days ago| E[Blocked by minimumReleaseAge]
    D --> |package published 3 or more days ago| F[Install proceeds]
    D --> |workspace packages| F
    F --> G{allowBuilds check}
    G --> |esbuild, parcel-watcher, msw| H[Build scripts allowed]
    G --> |all other packages| I[Build scripts blocked]
    H --> J[overrides applied from pnpm-workspace.yaml]
    I --> J
    J --> |react 19.1.2 and vite 5.4.21 plus| K[Dependency tree resolved]
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

Reviews (4): Last reviewed commit: "Merge branch 'main' into chore/pnpm-11-u..." | 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

changeset-bot Bot commented May 12, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 54e7f03

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
@cameronapak

Copy link
Copy Markdown
Collaborator Author

Hey @jhampton, Can I get your feedback on this PR? Mainly around the idea of it. I just want to make sure that with the rise of supply chain attacks, that we are protected on our repos. So I just want to share this with you and let me know so that I can hear your feedback (any feedback)

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