Fix yarn berry security updates resolving to latest instead of target version#15091
Conversation
507b0a9 to
609dd22
Compare
There was a problem hiding this comment.
Pull request overview
This PR addresses Yarn Berry (v2+) security updates where Dependabot’s intended target (minimum safe) version can be bypassed by Yarn resolving the updated semver range to a newer “latest-in-range” version, causing PR title/version mismatches. It does so by pinning exact Yarn Berry resolutions prior to running yarn install, using the dependency protocol inferred from the existing yarn.lock.
Changes:
- Add a Yarn Berry pre-install step that uses
yarn set resolutionto force top-level dependencies to resolve to the exact target version. - Introduce logic to infer the appropriate Yarn protocol (e.g.,
npm:) from the currentyarn.lock, and skip pinning when it can’t be determined or when the dependency is git-sourced. - Add fixture-based specs and a new Yarn Berry security-update fixture project to validate the lockfile resolves to the exact target version.
Show a summary per file
| File | Description |
|---|---|
| npm_and_yarn/lib/dependabot/npm_and_yarn/file_updater/yarn_lockfile_updater.rb | Pins exact Yarn Berry resolutions before install and infers the protocol from existing lockfiles. |
| npm_and_yarn/spec/dependabot/npm_and_yarn/file_updater/yarn_lockfile_updater_spec.rb | Adds specs covering the security update pinning path and skip conditions. |
| npm_and_yarn/spec/fixtures/projects/yarn_berry/security_update/package.json | New Yarn Berry fixture project manifest for a security update scenario. |
| npm_and_yarn/spec/fixtures/projects/yarn_berry/security_update/yarn.lock | New Yarn Berry fixture lockfile used to validate protocol inference and exact resolution behavior. |
Copilot's findings
- Files reviewed: 3/4 changed files
- Comments generated: 5
9fc2ee8 to
671496f
Compare
671496f to
9e8bfb4
Compare
b7aa55a to
7b6c714
Compare
|
Just a note: the yarn berry smoke test failures are expected and correct. Both smoke tests have ignore conditions, so Dependabot selects a specific target version. Before this fix, yarn berry was ignoring that and resolving to latest in the range:
The smoke tests were recording the wrong behavior as expected. They need regeneration to reflect the correct pinned versions. |
What are you trying to accomplish?
Yarn berry ignores Dependabot's selected target version when resolving lockfile entries. For example, when Dependabot targets
1.15.2(security fix or due to ignore conditions/cooldown), yarn resolves^1.15.2to1.16.x(latest in range). This means the lockfile ends up with a different version than what Dependabot intended — breaking security updates, ignore conditions, and cooldown.The fix follows the same pattern yarn classic already uses via
replaceLockfileDeclaration:yarn up dep@target_versionto install the exact version (gets correct checksum/deps)axios@npm:1.15.2→axios@npm:^1.15.2)package.jsonand runyarn installto normalize the lockfileThis only kicks in when yarn resolved to a different version than what Dependabot selected — normal updates where the target matches latest are unaffected.
Related: github/dependabot-updates#13436
Anything you want to highlight for special attention from reviewers?
BerryLockfileHandler— reusable class for parsing descriptors, finding keys, replacing declarations. Berry equivalent of yarn classic'sreplace-lockfile-declaration.ts, but in Ruby since it's just YAML manipulation (no tooling needed).npm:) is read dynamically from the lockfile, not hardcoded.package.jsonsave/restore step is needed becauseyarn up dep@versionmodifies the manifest (strips^/~). We restore it before the finalyarn installso the lockfile gets proper range descriptors — same thing yarn classic does withoriginalPackageJson.Note on smoke tests: The failing yarn berry smoke tests are expected. Previously they were wrong — the lockfile was resolving to the latest version in the range instead of respecting Dependabot's selected target. Now they'll correctly show the pinned version.
How will you know you've accomplished your goal?
yarn installstays pinnedaxios ^1.15.2→ pins1.15.2) and version update with tilde range (lodash ~4.17.10→ pins4.17.10)BerryLockfileHandlercover scoped packages, composite keys, tilde/caret ranges, protocol extractionChecklist