Skip to content

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

Open
cameronapak wants to merge 3 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 3 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 with supply-chain hardening: a 3-day minimumReleaseAge cooldown, allowBuilds approval list, and packageManager hash pinning via corepack. The pnpm 11 breaking change of moving overrides from package.json to pnpm-workspace.yaml is handled correctly, as is the Node.js bump from 20 → 22 and the removal of hardcoded version pins from all CI workflows.

  • pnpm 11 migration: pnpm.overrides moved to pnpm-workspace.yaml, allowBuilds added for esbuild, @parcel/watcher, and msw; @internal/eslint-config and eslint-plugin-storybook promoted to root devDependencies for workspace resolution.
  • Supply-chain protection: minimumReleaseAge: 4320 (3-day cooldown, stricter than pnpm 11's new default of 1 day) blocks packages published fewer than 3 days ago from being installed.
  • Incomplete migration: The .npmrc non-auth settings (auto-install-peers, strict-peer-dependencies, public-hoist-pattern) are silently ignored by pnpm 11 per the official migration guide and need to be moved to pnpm-workspace.yaml.

Confidence Score: 4/5

Safe to merge after addressing the incomplete .npmrc migration — the remaining settings are currently silently ignored by pnpm 11.

The core pnpm 11 breaking changes (overrides, allowBuilds, workspace hoisting) are handled correctly and CI passes. However, .npmrc non-auth settings are a documented required migration step in the pnpm 11 guide — auto-install-peers, strict-peer-dependencies, and public-hoist-pattern are silently ignored by pnpm 11 and need to be moved to pnpm-workspace.yaml before the migration is complete.

.npmrc and pnpm-workspace.yaml — the three non-auth settings from .npmrc need to be ported to pnpm-workspace.yaml as camelCase keys.

Important Files Changed

Filename Overview
.npmrc Three non-auth settings (auto-install-peers, strict-peer-dependencies, public-hoist-pattern) are silently ignored in pnpm 11 but have not been migrated to pnpm-workspace.yaml
pnpm-workspace.yaml Adds minimumReleaseAge (4320 min = 3 days), moves overrides from package.json, adds allowBuilds; missing the npmrc-migrated settings (autoInstallPeers, strictPeerDependencies, publicHoistPattern)
package.json Bumps packageManager to pnpm@11.1.1 with sha512 hash, engines to node>=22/pnpm>=11, removes pnpm.overrides (migrated to pnpm-workspace.yaml), adds @internal/eslint-config and eslint-plugin-storybook as root devDeps
.github/workflows/ci.yml Removes hardcoded pnpm version pins (pnpm/action-setup@v4 now reads from packageManager field) and bumps all jobs from node-version 20 to 22
.github/workflows/release.yml Removes hardcoded pnpm version pin; pnpm/action-setup@v4 will read from packageManager field
.github/workflows/storybook.yml Removes hardcoded pnpm version pin and bumps node-version from 20 to 22
AGENTS.md Updates pnpm/Node version references and adds supply-chain protection documentation

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[pnpm 11 config sources] --> B{Setting type?}
    B -->|Auth / registry| C[.npmrc ✅ still read]
    B -->|All other settings| D[pnpm-workspace.yaml ✅ read]
    B -->|All other settings| E[.npmrc ❌ silently ignored in pnpm 11]

    D --> F[minimumReleaseAge: 4320]
    D --> G[overrides: react, vite…]
    D --> H[allowBuilds: esbuild, msw…]
    D --> I["❌ MISSING: autoInstallPeers\nstrictPeerDependencies\npublicHoistPattern"]

    E --> J["auto-install-peers=true\nstrict-peer-dependencies=false\npublic-hoist-pattern[]=*eslint*\npublic-hoist-pattern[]=*prettier*\npublic-hoist-pattern[]=@types/*"]

    style E fill:#ffcccc,stroke:#cc0000
    style I fill:#ffcccc,stroke:#cc0000
    style J fill:#ffcccc,stroke:#cc0000
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 Fix All in Codex

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
.npmrc:1-5
**Non-auth `.npmrc` settings silently ignored in pnpm 11**

pnpm 11 only reads auth/registry settings from `.npmrc`. All other settings — `auto-install-peers`, `strict-peer-dependencies`, and `public-hoist-pattern` — are **silently ignored** with no warning. The official pnpm 11 migration guide explicitly calls this out as a required step: "Move pnpm settings out of `.npmrc` into `pnpm-workspace.yaml`". These three settings need to be added to `pnpm-workspace.yaml` as camelCase keys (`autoInstallPeers`, `strictPeerDependencies`, `publicHoistPattern`) to take effect. Without the `publicHoistPattern` entries, eslint, prettier, and `@types/*` packages are no longer hoisted to the workspace root, which can break editor tooling and any package that resolves them from the root `node_modules`.

Reviews (3): 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
Copy link
Copy Markdown

changeset-bot Bot commented May 12, 2026

⚠️ No Changeset found

Latest commit: 1dc8978

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.

1 participant