fix: write packageManagerDependencies when devEngines.packageManager is set without onFail#11681
Conversation
|
💖 Thanks for opening this pull request! 💖 |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (3)
✅ Files skipped from review due to trivial changes (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📜 Recent review details⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
🧰 Additional context used📓 Path-based instructions (1)**/*.{ts,tsx,js,jsx}📄 CodeRabbit inference engine (AGENTS.md)
Files:
🧠 Learnings (1)📚 Learning: 2026-05-14T09:04:00.133ZApplied to files:
🔇 Additional comments (1)
📝 WalkthroughWalkthroughThis PR ensures syncEnvLockfile records the current pnpm version in pnpm-lock.yaml when pinning is enabled and the env lockfile is missing or lacks a pnpm entry; tests and a changeset were added. ChangesLockfile sync behavior fix
Sequence Diagram(s)sequenceDiagram
participant syncEnvLockfile
participant resolvePackageManagerIntegrities
participant pnpm_lock_yaml
syncEnvLockfile->>resolvePackageManagerIntegrities: request integrities (envLockfile or undefined)
resolvePackageManagerIntegrities->>pnpm_lock_yaml: write importers['.'].packageManagerDependencies.pnpm { specifier, version }
pnpm_lock_yaml-->>syncEnvLockfile: persist confirmation
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related issues
Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
7d95512 to
23a73cb
Compare
|
Isn't this covered by #11682? |
…kageManager is set
When `devEngines.packageManager.pnpm` is set without `onFail: "download"`,
`pnpm install` ran `syncEnvLockfile` instead of `switchCliVersion`. That sync
returned early whenever the env lockfile did not already record a
`packageManagerDependencies.pnpm` entry, so the resolved pnpm version was
never recorded on first install — contradicting the documented behavior
("The resolved version is stored in pnpm-lock.yaml") and forcing users to
add `onFail: "download"` purely to trigger the lockfile write.
Drop the two early-returns that only fired when the env lockfile was
missing or empty. The resolution proceeds whenever (a) the project pins a
pnpm version via `devEngines.packageManager` (or a v12+ `packageManager`
field) and (b) the running pnpm satisfies that pin. The existing
"already-resolved" no-op path still skips work when the lockfile already
records a satisfying version, so steady-state installs don't churn.
Closes pnpm#11674 (part 1). Part 3 (pruning `@pnpm/exe` platform entries when
`onFail: "download"` is removed) is left for a follow-up — it needs a
state-transition signal the codebase doesn't yet track.
23a73cb to
d6c2f01
Compare
Summary
Partially closes #11674 — addresses part 1 (the main complaint).
When
devEngines.packageManager.pnpmis set withoutonFail: "download",pnpm installpreviously ransyncEnvLockfileinstead ofswitchCliVersion. The sync function returned early when the env lockfile lacked apackageManagerDependencies.pnpmentry — so the resolved pnpm version was never recorded on the first install, contradicting the docs ("The resolved version is stored in pnpm-lock.yaml") and forcing users to addonFail: "download"purely to trigger the lockfile write.This PR drops the two early-returns that only fired when the env lockfile was missing or empty. Resolution proceeds whenever:
devEngines.packageManager(or a v12+packageManagerfield) — gated byshouldPersistLockfile, unchanged.semver.satisfies, unchanged.The existing "already-resolved" no-op path still skips work when the lockfile records a satisfying version, so steady-state installs don't churn.
Repro (from the issue)
```json
{
"private": true,
"devEngines": {
"packageManager": { "name": "pnpm", "version": ">=11.0.0" }
},
"dependencies": { "is-odd": "^3.0.1" }
}
```
Before: `pnpm-lock.yaml` has no `packageManagerDependencies` after install.
After: `pnpm-lock.yaml` has `packageManagerDependencies.pnpm` (and `@pnpm/exe`, see deferred-work note below) with the resolved version.
Out of scope (deferred to follow-up)
The issue's part 3 asks for pruning the `@pnpm/exe` platform-specific entries when `onFail: "download"` is removed. That needs a state-transition signal that doesn't exist in the codebase today (we'd have to know that `onFail` used to be `download`). Filing that as a follow-up after this PR lands.
A related minor consequence: in non-download mode, `resolvePackageManagerIntegrities` still resolves and writes `@pnpm/exe` alongside `pnpm`. The user's issue acknowledges these entries are useful in download mode and clutter otherwise — short-term that clutter is the cost of fixing the main bug. Long-term, gating the `@pnpm/exe` resolution on `onFail === 'download'` would clean this up, but it's a separate refactor.
Test plan
Local Jest could not run due to an unrelated `module is already linked` failure under `experimental-vm-modules` on Node 22/24 in my environment (reproduces on a pristine `main` checkout) — happy to rerun once CI exercises the change.
pacquet parity note
pacquet currently only ports `install` and does not yet implement `devEngines.packageManager` lockfile-sync. Once it grows that surface, the same behavior should be mirrored. Flagging here per `CLAUDE.md`.
Written by an agent (Claude Code, claude-opus-4-7).
Summary by CodeRabbit
Bug Fixes
Tests
Documentation