dependabot-npm_and_yarn 0.380.0 → 0.381.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/dependabot/npm_and_yarn/file_parser/json_lock.rb +1 -1
- data/lib/dependabot/npm_and_yarn/file_updater/yarn_lockfile_updater.rb +42 -12
- data/lib/dependabot/npm_and_yarn/file_updater.rb +5 -2
- data/lib/dependabot/npm_and_yarn/helpers.rb +45 -7
- data/lib/dependabot/npm_and_yarn/update_checker/latest_version_finder.rb +10 -4
- metadata +4 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a70ee3c0913d6a9622b867d20d898019ad3453701dd1a18e1c01b62887d52351
|
|
4
|
+
data.tar.gz: 80f0ce022e8e6a30f4f72bb7928f0a865abbe05f8868b873d3a84077ab139e02
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c56af922ead64141beb7c8fefea2b706d84e90007fd33620f9892fb80d11fcc6e9eb239fa0d0220d0d93b92177de0c780048ccb17dd9ef4ae2409886beb7cda8
|
|
7
|
+
data.tar.gz: f3d511e27a4e5ca500c869e0de11729544f4323ea4776c275df99f750b947936b17dad15166571d5515c0e5d524b57eb5c7079876923cebb019a5bf288690612
|
|
@@ -21,7 +21,7 @@ module Dependabot
|
|
|
21
21
|
sig { returns(T::Hash[String, T.untyped]) }
|
|
22
22
|
def parsed
|
|
23
23
|
json_obj = JSON.parse(T.must(@dependency_file.content))
|
|
24
|
-
@parsed ||= T.let(json_obj, T.untyped)
|
|
24
|
+
@parsed ||= T.let(json_obj, T.nilable(T::Hash[String, T.untyped]))
|
|
25
25
|
rescue JSON::ParserError
|
|
26
26
|
raise Dependabot::DependencyFileNotParseable, @dependency_file.path
|
|
27
27
|
end
|
|
@@ -30,15 +30,23 @@ module Dependabot
|
|
|
30
30
|
dependencies: T::Array[Dependabot::Dependency],
|
|
31
31
|
dependency_files: T::Array[Dependabot::DependencyFile],
|
|
32
32
|
repo_contents_path: T.nilable(String),
|
|
33
|
-
credentials: T::Array[Dependabot::Credential]
|
|
33
|
+
credentials: T::Array[Dependabot::Credential],
|
|
34
|
+
security_updates_only: T::Boolean
|
|
34
35
|
)
|
|
35
36
|
.void
|
|
36
37
|
end
|
|
37
|
-
def initialize(
|
|
38
|
+
def initialize(
|
|
39
|
+
dependencies:,
|
|
40
|
+
dependency_files:,
|
|
41
|
+
repo_contents_path:,
|
|
42
|
+
credentials:,
|
|
43
|
+
security_updates_only: false
|
|
44
|
+
)
|
|
38
45
|
@dependencies = dependencies
|
|
39
46
|
@dependency_files = dependency_files
|
|
40
47
|
@repo_contents_path = repo_contents_path
|
|
41
48
|
@credentials = credentials
|
|
49
|
+
@security_updates_only = T.let(security_updates_only, T::Boolean)
|
|
42
50
|
@error_handler = T.let(
|
|
43
51
|
YarnErrorHandler.new(
|
|
44
52
|
dependencies: dependencies,
|
|
@@ -222,7 +230,7 @@ module Dependabot
|
|
|
222
230
|
# the lockfile.
|
|
223
231
|
|
|
224
232
|
if top_level_dependency_updates.all? { |dep| requirements_changed?(dep[:name]) }
|
|
225
|
-
Helpers.run_yarn_command("install #{yarn_berry_args}".strip)
|
|
233
|
+
Helpers.run_yarn_command("install #{yarn_berry_args}".strip, env: yarn_time_gate_env)
|
|
226
234
|
|
|
227
235
|
# Yarn berry resolves ranges to the latest matching version, which
|
|
228
236
|
# may differ from Dependabot's target. If the lockfile resolved to a
|
|
@@ -237,7 +245,8 @@ module Dependabot
|
|
|
237
245
|
|
|
238
246
|
Helpers.run_yarn_command(
|
|
239
247
|
"up -R #{updates.join(' ')} #{yarn_berry_args}".strip,
|
|
240
|
-
fingerprint: "up -R <dependency_names> #{yarn_berry_args}".strip
|
|
248
|
+
fingerprint: "up -R <dependency_names> #{yarn_berry_args}".strip,
|
|
249
|
+
env: yarn_time_gate_env
|
|
241
250
|
)
|
|
242
251
|
end
|
|
243
252
|
{ yarn_lock.name => File.read(yarn_lock.name) }
|
|
@@ -291,7 +300,8 @@ module Dependabot
|
|
|
291
300
|
|
|
292
301
|
Helpers.run_yarn_command(
|
|
293
302
|
"up #{dep_name}@#{version} #{yarn_berry_args}".strip,
|
|
294
|
-
fingerprint: "up <dep>@<version> #{yarn_berry_args}".strip
|
|
303
|
+
fingerprint: "up <dep>@<version> #{yarn_berry_args}".strip,
|
|
304
|
+
env: yarn_time_gate_env
|
|
295
305
|
)
|
|
296
306
|
|
|
297
307
|
reqs.each do |req|
|
|
@@ -304,7 +314,7 @@ module Dependabot
|
|
|
304
314
|
# Restore package.json and re-install to normalize lockfile descriptors,
|
|
305
315
|
# same as yarn classic's replaceLockfileDeclaration flow.
|
|
306
316
|
restore_package_jsons(saved_package_jsons)
|
|
307
|
-
Helpers.run_yarn_command("install #{yarn_berry_args}".strip)
|
|
317
|
+
Helpers.run_yarn_command("install #{yarn_berry_args}".strip, env: yarn_time_gate_env)
|
|
308
318
|
end
|
|
309
319
|
|
|
310
320
|
sig { returns(T::Hash[String, String]) }
|
|
@@ -353,6 +363,24 @@ module Dependabot
|
|
|
353
363
|
{ yarn_lock.name => updated_content }
|
|
354
364
|
end
|
|
355
365
|
|
|
366
|
+
sig { returns(T::Boolean) }
|
|
367
|
+
def security_updates_only?
|
|
368
|
+
@security_updates_only
|
|
369
|
+
end
|
|
370
|
+
|
|
371
|
+
# Returns an env hash that disables Yarn Berry's npmMinimalAgeGate for security updates.
|
|
372
|
+
# npmMinimalAgeGate was introduced in Yarn 4.10.0. Setting the corresponding
|
|
373
|
+
# YARN_NPM_MINIMAL_AGE_GATE env var on older Yarn Berry releases (or Yarn classic) raises
|
|
374
|
+
# "Unrecognized or legacy configuration settings found: npmMinimalAgeGate" and aborts the
|
|
375
|
+
# install, so we gate on a version check.
|
|
376
|
+
sig { returns(T.nilable(T::Hash[String, String])) }
|
|
377
|
+
def yarn_time_gate_env
|
|
378
|
+
return nil unless security_updates_only?
|
|
379
|
+
return nil unless Helpers.yarn_berry_supports_minimal_age_gate?
|
|
380
|
+
|
|
381
|
+
{ "YARN_NPM_MINIMAL_AGE_GATE" => "0" }
|
|
382
|
+
end
|
|
383
|
+
|
|
356
384
|
sig { returns(String) }
|
|
357
385
|
def yarn_berry_args
|
|
358
386
|
@yarn_berry_args ||= T.let(
|
|
@@ -535,13 +563,15 @@ module Dependabot
|
|
|
535
563
|
def write_temporary_dependency_files(yarn_lock, update_package_json: true)
|
|
536
564
|
write_lockfiles
|
|
537
565
|
|
|
538
|
-
if Helpers.yarn_berry?(yarn_lock)
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
566
|
+
if Helpers.yarn_berry?(yarn_lock)
|
|
567
|
+
if yarnrc_yml_file
|
|
568
|
+
yarnrc_yml_sanitize_content = sanitize_yarnrc_content(yarnrc_yml_content)
|
|
569
|
+
File.write(".yarnrc.yml", yarnrc_yml_sanitize_content)
|
|
570
|
+
end
|
|
571
|
+
elsif yarnrc_specifies_private_reg?
|
|
572
|
+
File.write(".yarnrc", yarnrc_content)
|
|
544
573
|
end
|
|
574
|
+
File.write(".npmrc", npmrc_content)
|
|
545
575
|
|
|
546
576
|
package_files.each do |file|
|
|
547
577
|
path = file.name
|
|
@@ -5,6 +5,7 @@ require "dependabot/file_updaters"
|
|
|
5
5
|
require "dependabot/file_updaters/base"
|
|
6
6
|
require "dependabot/file_updaters/vendor_updater"
|
|
7
7
|
require "dependabot/file_updaters/artifact_updater"
|
|
8
|
+
require "dependabot/errors"
|
|
8
9
|
require "dependabot/npm_and_yarn/dependency_files_filterer"
|
|
9
10
|
require "dependabot/npm_and_yarn/sub_dependency_files_filterer"
|
|
10
11
|
require "sorbet-runtime"
|
|
@@ -22,6 +23,7 @@ module Dependabot
|
|
|
22
23
|
|
|
23
24
|
class NoChangeError < StandardError
|
|
24
25
|
extend T::Sig
|
|
26
|
+
include Dependabot::HasSentryContext
|
|
25
27
|
|
|
26
28
|
sig { params(message: String, error_context: T::Hash[Symbol, T.untyped]).void }
|
|
27
29
|
def initialize(message:, error_context:)
|
|
@@ -29,7 +31,7 @@ module Dependabot
|
|
|
29
31
|
@error_context = error_context
|
|
30
32
|
end
|
|
31
33
|
|
|
32
|
-
sig { returns(T::Hash[Symbol, T.untyped]) }
|
|
34
|
+
sig { override.returns(T::Hash[Symbol, T.untyped]) }
|
|
33
35
|
def sentry_context
|
|
34
36
|
{ extra: @error_context }
|
|
35
37
|
end
|
|
@@ -440,7 +442,8 @@ module Dependabot
|
|
|
440
442
|
dependencies: dependencies,
|
|
441
443
|
dependency_files: dependency_files,
|
|
442
444
|
repo_contents_path: repo_contents_path,
|
|
443
|
-
credentials: credentials
|
|
445
|
+
credentials: credentials,
|
|
446
|
+
security_updates_only: options.fetch(:security_updates_only, false)
|
|
444
447
|
),
|
|
445
448
|
T.nilable(Dependabot::NpmAndYarn::FileUpdater::YarnLockfileUpdater)
|
|
446
449
|
)
|
|
@@ -248,6 +248,31 @@ module Dependabot
|
|
|
248
248
|
yarn_major_version >= 4
|
|
249
249
|
end
|
|
250
250
|
|
|
251
|
+
sig { returns(T::Boolean) }
|
|
252
|
+
def self.yarn_berry_supports_minimal_age_gate?
|
|
253
|
+
version = Version.new(run_single_yarn_command("--version"))
|
|
254
|
+
supported = version >= Version.new("4.10.0")
|
|
255
|
+
if supported
|
|
256
|
+
Dependabot.logger.info(
|
|
257
|
+
"Yarn #{version} supports npmMinimalAgeGate. " \
|
|
258
|
+
"Setting YARN_NPM_MINIMAL_AGE_GATE=0 to bypass the release-age gate for security updates."
|
|
259
|
+
)
|
|
260
|
+
else
|
|
261
|
+
Dependabot.logger.info(
|
|
262
|
+
"Yarn #{version} does not support npmMinimalAgeGate (requires 4.10.0+). " \
|
|
263
|
+
"YARN_NPM_MINIMAL_AGE_GATE will not be set."
|
|
264
|
+
)
|
|
265
|
+
end
|
|
266
|
+
supported
|
|
267
|
+
rescue StandardError => e
|
|
268
|
+
Dependabot.logger.warn(
|
|
269
|
+
"Could not determine Yarn version to check npmMinimalAgeGate support: #{e.message}. " \
|
|
270
|
+
"Assuming unsupported (returning false). YARN_NPM_MINIMAL_AGE_GATE will not be set, " \
|
|
271
|
+
"so the registry's release-age gate may still block security updates."
|
|
272
|
+
)
|
|
273
|
+
false
|
|
274
|
+
end
|
|
275
|
+
|
|
251
276
|
sig { returns(T.nilable(String)) }
|
|
252
277
|
def self.setup_yarn_berry
|
|
253
278
|
# Always disable immutable installs so yarn's CI detection doesn't prevent updates.
|
|
@@ -362,10 +387,16 @@ module Dependabot
|
|
|
362
387
|
end
|
|
363
388
|
|
|
364
389
|
# Setup yarn and run a single yarn command returning stdout/stderr
|
|
365
|
-
sig
|
|
366
|
-
|
|
390
|
+
sig do
|
|
391
|
+
params(
|
|
392
|
+
command: String,
|
|
393
|
+
fingerprint: T.nilable(String),
|
|
394
|
+
env: T.nilable(T::Hash[String, String])
|
|
395
|
+
).returns(String)
|
|
396
|
+
end
|
|
397
|
+
def self.run_yarn_command(command, fingerprint: nil, env: nil)
|
|
367
398
|
setup_yarn_berry
|
|
368
|
-
run_single_yarn_command(command, fingerprint: fingerprint)
|
|
399
|
+
run_single_yarn_command(command, fingerprint: fingerprint, env: env)
|
|
369
400
|
end
|
|
370
401
|
|
|
371
402
|
# Run single pnpm command returning stdout/stderr
|
|
@@ -382,14 +413,21 @@ module Dependabot
|
|
|
382
413
|
end
|
|
383
414
|
|
|
384
415
|
# Run single yarn command returning stdout/stderr
|
|
385
|
-
sig
|
|
386
|
-
|
|
416
|
+
sig do
|
|
417
|
+
params(
|
|
418
|
+
command: String,
|
|
419
|
+
fingerprint: T.nilable(String),
|
|
420
|
+
env: T.nilable(T::Hash[String, String])
|
|
421
|
+
).returns(String)
|
|
422
|
+
end
|
|
423
|
+
def self.run_single_yarn_command(command, fingerprint: nil, env: nil)
|
|
387
424
|
if Dependabot::Experiments.enabled?(:enable_corepack_for_npm_and_yarn)
|
|
388
|
-
package_manager_run_command(YarnPackageManager::NAME, command, fingerprint: fingerprint)
|
|
425
|
+
package_manager_run_command(YarnPackageManager::NAME, command, fingerprint: fingerprint, env: env)
|
|
389
426
|
else
|
|
390
427
|
Dependabot::SharedHelpers.run_shell_command(
|
|
391
428
|
"yarn #{command}",
|
|
392
|
-
fingerprint: "yarn #{fingerprint || command}"
|
|
429
|
+
fingerprint: "yarn #{fingerprint || command}",
|
|
430
|
+
env: env
|
|
393
431
|
)
|
|
394
432
|
end
|
|
395
433
|
end
|
|
@@ -259,14 +259,20 @@ module Dependabot
|
|
|
259
259
|
sig { params(_block: T.untyped).returns(T.nilable(Dependabot::Version)) }
|
|
260
260
|
def with_custom_registry_rescue(&_block)
|
|
261
261
|
yield
|
|
262
|
-
rescue Excon::Error::Socket, Excon::Error::Timeout, RegistryError
|
|
263
|
-
raise unless package_fetcher.custom_registry?
|
|
262
|
+
rescue Excon::Error::Socket, Excon::Error::Timeout, RegistryError => e
|
|
263
|
+
raise unless package_fetcher.custom_registry? || eof_socket_error?(e)
|
|
264
264
|
|
|
265
|
-
# Custom registries can be flaky
|
|
266
|
-
#
|
|
265
|
+
# Custom registries can be flaky, and the global npm registry can
|
|
266
|
+
# occasionally terminate connections (EOFError). Don't abort the update
|
|
267
|
+
# flow for these transient failures; quietly return `nil` here.
|
|
267
268
|
nil
|
|
268
269
|
end
|
|
269
270
|
|
|
271
|
+
sig { params(error: StandardError).returns(T::Boolean) }
|
|
272
|
+
def eof_socket_error?(error)
|
|
273
|
+
error.is_a?(Excon::Error::Socket) && error.socket_error.is_a?(EOFError)
|
|
274
|
+
end
|
|
275
|
+
|
|
270
276
|
sig { returns(T::Boolean) }
|
|
271
277
|
def valid_npm_details?
|
|
272
278
|
!!package_details&.releases&.any?
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: dependabot-npm_and_yarn
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.381.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Dependabot
|
|
@@ -15,14 +15,14 @@ dependencies:
|
|
|
15
15
|
requirements:
|
|
16
16
|
- - '='
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
|
-
version: 0.
|
|
18
|
+
version: 0.381.0
|
|
19
19
|
type: :runtime
|
|
20
20
|
prerelease: false
|
|
21
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
22
22
|
requirements:
|
|
23
23
|
- - '='
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
|
-
version: 0.
|
|
25
|
+
version: 0.381.0
|
|
26
26
|
- !ruby/object:Gem::Dependency
|
|
27
27
|
name: debug
|
|
28
28
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -374,7 +374,7 @@ licenses:
|
|
|
374
374
|
- MIT
|
|
375
375
|
metadata:
|
|
376
376
|
bug_tracker_uri: https://github.com/dependabot/dependabot-core/issues
|
|
377
|
-
changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.
|
|
377
|
+
changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.381.0
|
|
378
378
|
rdoc_options: []
|
|
379
379
|
require_paths:
|
|
380
380
|
- lib
|