Skip to content

Commit 61b0e74

Browse files
committed
npm_and_yarn: add --no-save to pnpm deep-update fallback
pnpm update <dep> --depth Infinity --lockfile-only rewrites caret ranges in package.json and the matching specifier: lines in pnpm-lock.yaml to ^<currently-resolved-version> for every direct dep whose resolved version is newer than its declared range floor. Dependabot returns only the lockfile from this flow, so the package.json mutations are discarded while the lockfile keeps specifier: entries that no longer match the manifest, and a downstream frozen-lockfile install rejects the PR. Adding --no-save tells pnpm to leave package.json ranges alone while still resolving and writing the lockfile graph for the target transitive dependency. Verified locally to: still bump the target transitive in the lockfile, produce zero specifier: rewrites, produce zero package.json mutations. Fixes #15104
1 parent 10db257 commit 61b0e74

2 files changed

Lines changed: 15 additions & 8 deletions

File tree

npm_and_yarn/lib/dependabot/npm_and_yarn/native_helpers.rb

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -72,14 +72,21 @@ def self.run_pnpm_audit_fix_command
7272
sig { params(dependency_name: String, recursive: T::Boolean).returns(String) }
7373
def self.run_pnpm_deep_update_command(dependency_name, recursive: false)
7474
# `pnpm update --depth Infinity <dep>` traverses the full dependency
75-
# graph, allowing transitive dependencies to be updated in the lockfile
76-
# without modifying any package.json (unlike `pnpm audit --fix`).
77-
# `-r --include-workspace-root` is required for workspace repos so the
78-
# update is applied across all packages.
75+
# graph so transitive dependencies can be updated in the lockfile.
76+
# `--no-save` is required: without it, pnpm rewrites caret ranges in
77+
# `package.json` and the matching `specifier:` lines in
78+
# `pnpm-lock.yaml` to `^<currently-resolved-version>` for every
79+
# direct dependency whose resolved version is newer than its
80+
# declared range floor. Dependabot only returns the lockfile from
81+
# this flow, so those package.json mutations are discarded while
82+
# the lockfile keeps `specifier:` entries that no longer match the
83+
# manifest, which a downstream frozen-lockfile install rejects.
84+
# `-r --include-workspace-root` is required for workspace repos so
85+
# the update is applied across all packages.
7986
flags = recursive ? "-r --include-workspace-root " : ""
8087
Helpers.run_pnpm_command(
81-
"#{flags}update #{dependency_name} --depth Infinity --lockfile-only",
82-
fingerprint: "#{flags}update <dependency_name> --depth Infinity --lockfile-only"
88+
"#{flags}update #{dependency_name} --depth Infinity --lockfile-only --no-save",
89+
fingerprint: "#{flags}update <dependency_name> --depth Infinity --lockfile-only --no-save"
8390
)
8491
end
8592

npm_and_yarn/spec/dependabot/npm_and_yarn/file_updater/pnpm_lockfile_updater_spec.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -772,8 +772,8 @@
772772
.ordered
773773
expect(Dependabot::NpmAndYarn::Helpers).to receive(:run_pnpm_command)
774774
.with(
775-
"-r --include-workspace-root update prettier --depth Infinity --lockfile-only",
776-
{ fingerprint: "-r --include-workspace-root update <dependency_name> --depth Infinity --lockfile-only" }
775+
"-r --include-workspace-root update prettier --depth Infinity --lockfile-only --no-save",
776+
{ fingerprint: "-r --include-workspace-root update <dependency_name> --depth Infinity --lockfile-only --no-save" }
777777
)
778778
.ordered
779779
.and_return("")

0 commit comments

Comments
 (0)