Skip to content

Fix yarn berry security updates resolving to latest instead of target version#15091

Merged
kbukum1 merged 5 commits into
mainfrom
kbukum/fix-yarn-berry-security-update-resolution
May 23, 2026
Merged

Fix yarn berry security updates resolving to latest instead of target version#15091
kbukum1 merged 5 commits into
mainfrom
kbukum/fix-yarn-berry-security-update-resolution

Conversation

@kbukum1
Copy link
Copy Markdown
Contributor

@kbukum1 kbukum1 commented May 20, 2026

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.2 to 1.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:

  1. Run yarn up dep@target_version to install the exact version (gets correct checksum/deps)
  2. Rewrite the lockfile descriptor key from exact back to the range (e.g., axios@npm:1.15.2axios@npm:^1.15.2)
  3. Restore package.json and run yarn install to normalize the lockfile

This 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?

  • Extracted berry lockfile manipulation into BerryLockfileHandler — reusable class for parsing descriptors, finding keys, replacing declarations. Berry equivalent of yarn classic's replace-lockfile-declaration.ts, but in Ruby since it's just YAML manipulation (no tooling needed).
  • Protocol (e.g., npm:) is read dynamically from the lockfile, not hardcoded.
  • Git dependencies are skipped — they pin to commits/tags.
  • The package.json save/restore step is needed because yarn up dep@version modifies the manifest (strips ^/~). We restore it before the final yarn install so the lockfile gets proper range descriptors — same thing yarn classic does with originalPackageJson.
  • Smoke tests will need regeneration — the yarn berry ones now correctly pin to the target version instead of resolving to latest. This is the intended behavior change.

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?

  • Verified manually with yarn 4.12.0 and yarn 3.2.3 — pinning works, customer yarn install stays pinned
  • All unit tests pass (190 examples, 0 failures)
  • Two integration tests: security update with caret range (axios ^1.15.2 → pins 1.15.2) and version update with tilde range (lodash ~4.17.10 → pins 4.17.10)
  • Unit tests for BerryLockfileHandler cover scoped packages, composite keys, tilde/caret ranges, protocol extraction

Checklist

  • I have run the complete test suite to ensure all tests and linters pass.
  • I have thoroughly tested my code changes to ensure they work as expected, including adding additional tests for new functionality.
  • I have written clear and descriptive commit messages.
  • I have provided a detailed description of the changes in the pull request, including the problem it addresses, how it fixes the problem, and any relevant details about the implementation.
  • I have ensured that the code is well-documented and easy to understand.

Copilot AI review requested due to automatic review settings May 20, 2026 21:48
@kbukum1 kbukum1 requested a review from a team as a code owner May 20, 2026 21:48
@kbukum1 kbukum1 force-pushed the kbukum/fix-yarn-berry-security-update-resolution branch from 507b0a9 to 609dd22 Compare May 20, 2026 21:49
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 resolution to force top-level dependencies to resolve to the exact target version.
  • Introduce logic to infer the appropriate Yarn protocol (e.g., npm:) from the current yarn.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

Comment thread npm_and_yarn/lib/dependabot/npm_and_yarn/file_updater/yarn_lockfile_updater.rb Outdated
Comment thread npm_and_yarn/lib/dependabot/npm_and_yarn/file_updater/yarn_lockfile_updater.rb Outdated
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

  • Files reviewed: 3/4 changed files
  • Comments generated: 1

Comment thread npm_and_yarn/lib/dependabot/npm_and_yarn/file_updater/yarn_lockfile_updater.rb Outdated
@kbukum1 kbukum1 changed the title npm_and_yarn: Fix yarn berry security updates resolving to latest instead of target version Fix yarn berry security updates resolving to latest instead of target version May 20, 2026
@kbukum1 kbukum1 requested a review from Copilot May 20, 2026 22:35
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

  • Files reviewed: 3/4 changed files
  • Comments generated: 2

Comment thread npm_and_yarn/lib/dependabot/npm_and_yarn/file_updater/yarn_lockfile_updater.rb Outdated
@kbukum1 kbukum1 force-pushed the kbukum/fix-yarn-berry-security-update-resolution branch 4 times, most recently from 9fc2ee8 to 671496f Compare May 22, 2026 22:03
robaiken
robaiken previously approved these changes May 22, 2026
@kbukum1 kbukum1 force-pushed the kbukum/fix-yarn-berry-security-update-resolution branch from 671496f to 9e8bfb4 Compare May 22, 2026 22:26
@kbukum1 kbukum1 force-pushed the kbukum/fix-yarn-berry-security-update-resolution branch from b7aa55a to 7b6c714 Compare May 23, 2026 00:22
@kbukum1
Copy link
Copy Markdown
Contributor Author

kbukum1 commented May 23, 2026

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:

smoke-npm-yarn-berry.yaml (jquery)

Before (wrong) After (correct)
Dependabot target 3.6.3 3.6.3
Ignore condition >3.6.3 >3.6.3
Lockfile key jquery@npm:^3.6.3 jquery@npm:^3.6.3
Lockfile resolved 3.7.1 3.6.3

smoke-npm-yarn-berry-workspaces.yaml (@types/lodash)

Before (wrong) After (correct)
Dependabot target 4.14.191 4.14.191
Ignore condition >4.14.191 >4.14.191
Lockfile key @types/lodash@npm:^4.14.191 @types/lodash@npm:^4.14.191
Lockfile resolved 4.14.202 4.14.191

The smoke tests were recording the wrong behavior as expected. They need regeneration to reflect the correct pinned versions.

@kbukum1 kbukum1 requested a review from robaiken May 23, 2026 02:47
Copy link
Copy Markdown
Contributor

@AbhishekBhaskar AbhishekBhaskar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@kbukum1 kbukum1 merged commit 10db257 into main May 23, 2026
101 of 103 checks passed
@kbukum1 kbukum1 deleted the kbukum/fix-yarn-berry-security-update-resolution branch May 23, 2026 19:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants