dependabot-npm_and_yarn 0.351.0 → 0.352.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.
data/helpers/package.json CHANGED
@@ -21,9 +21,9 @@
21
21
  "patch-package": "^8.0.0"
22
22
  },
23
23
  "devDependencies": {
24
- "eslint": "^9.31.0",
24
+ "eslint": "^9.39.1",
25
25
  "eslint-config-prettier": "^10.1.8",
26
- "jest": "^30.0.5",
27
- "prettier": "^3.6.2"
26
+ "jest": "^30.2.0",
27
+ "prettier": "^3.7.4"
28
28
  }
29
29
  }
@@ -113,11 +113,14 @@ module Dependabot
113
113
 
114
114
  sig { void }
115
115
  def run_npm_lockfile_generation
116
+ # Set dependency files and credentials for automatic env variable injection
117
+ Helpers.dependency_files = dependency_files
118
+ Helpers.credentials = credentials
119
+
116
120
  # Use --package-lock-only to generate lockfile without installing node_modules
117
121
  # Use --ignore-scripts to prevent running any scripts
118
122
  # Use --force to ignore platform checks
119
- # Use --dry-run false because global .npmrc may have dry-run: true set
120
- command = "install --package-lock-only --ignore-scripts --force --dry-run false"
123
+ command = "install --package-lock-only --ignore-scripts --force"
121
124
  Helpers.run_npm_command(command, fingerprint: command)
122
125
  end
123
126
 
@@ -40,7 +40,7 @@ module Dependabot
40
40
 
41
41
  T.must(
42
42
  @package_json = T.let(
43
- T.must(dependency_files.find { |f| f.name.end_with?(MANIFEST_FILENAME) }),
43
+ T.must(dependency_files.find { |f| f.name.end_with?(NpmAndYarn::MANIFEST_FILENAME) }),
44
44
  T.nilable(Dependabot::DependencyFile)
45
45
  )
46
46
  )
@@ -139,6 +139,10 @@ module Dependabot
139
139
  return lockfile.content if npmrc_disables_lockfile?
140
140
  return lockfile.content unless updatable_dependencies.any?
141
141
 
142
+ # Set dependency files and credentials for automatic env variable injection
143
+ Helpers.dependency_files = dependency_files
144
+ Helpers.credentials = credentials
145
+
142
146
  @updated_lockfile_content ||= T.let(
143
147
  SharedHelpers.in_a_temporary_directory do
144
148
  write_temporary_dependency_files
@@ -339,8 +343,6 @@ module Dependabot
339
343
  #
340
344
  # Other npm flags:
341
345
  # - `--force` ignores checks for platform (os, cpu) and engines
342
- # - `--dry-run=false` the updater sets a global .npmrc with `dry-run: true`
343
- # to work around an issue in npm 6, we don't want that here
344
346
  # - `--ignore-scripts` disables prepare and prepack scripts which are
345
347
  # run when installing git dependencies
346
348
  # - `--save-optional` when updating optional dependencies to ensure they
@@ -351,8 +353,6 @@ module Dependabot
351
353
  "install",
352
354
  *install_args,
353
355
  "--force",
354
- "--dry-run",
355
- "false",
356
356
  "--ignore-scripts",
357
357
  "--package-lock-only"
358
358
  ]
@@ -365,8 +365,6 @@ module Dependabot
365
365
  "install",
366
366
  install_args.empty? ? "" : "<install_args>",
367
367
  "--force",
368
- "--dry-run",
369
- "false",
370
368
  "--ignore-scripts",
371
369
  "--package-lock-only"
372
370
  ]
@@ -375,25 +373,7 @@ module Dependabot
375
373
 
376
374
  fingerprint = fingerprint_args.join(" ")
377
375
 
378
- env = build_registry_env_variables
379
-
380
- Helpers.run_npm_command(command, fingerprint: fingerprint, env: env)
381
- end
382
-
383
- sig { returns(T.nilable(T::Hash[String, String])) }
384
- def build_registry_env_variables
385
- return nil unless Dependabot::Experiments.enabled?(:enable_private_registry_for_corepack)
386
-
387
- registry_helper = NpmAndYarn::RegistryHelper.new(
388
- {
389
- npmrc: dependency_files.find { |f| f.name.end_with?(".npmrc") },
390
- yarnrc: dependency_files.find { |f| f.name.end_with?(".yarnrc") && !f.name.end_with?(".yarnrc.yml") },
391
- yarnrc_yml: dependency_files.find { |f| f.name.end_with?(".yarnrc.yml") }
392
- },
393
- credentials
394
- )
395
-
396
- registry_helper.find_corepack_env_variables
376
+ Helpers.run_npm_command(command, fingerprint: fingerprint)
397
377
  end
398
378
 
399
379
  sig { params(dependency: Dependabot::Dependency).returns(String) }
@@ -143,6 +143,10 @@ module Dependabot
143
143
  .returns(String)
144
144
  end
145
145
  def run_pnpm_update(pnpm_lock:, updated_pnpm_workspace_content: nil)
146
+ # Set dependency files and credentials for automatic env variable injection
147
+ Helpers.dependency_files = dependency_files
148
+ Helpers.credentials = credentials
149
+
146
150
  SharedHelpers.in_a_temporary_repo_directory(base_dir, repo_contents_path) do
147
151
  File.write(".npmrc", npmrc_content(pnpm_lock))
148
152
 
@@ -89,6 +89,10 @@ module Dependabot
89
89
 
90
90
  sig { params(yarn_lock: Dependabot::DependencyFile).returns(String) }
91
91
  def updated_yarn_lock(yarn_lock)
92
+ # Set dependency files and credentials for automatic env variable injection
93
+ Helpers.dependency_files = dependency_files
94
+ Helpers.credentials = credentials
95
+
92
96
  base_dir = T.must(dependency_files.first).directory
93
97
  SharedHelpers.in_a_temporary_repo_directory(base_dir, repo_contents_path) do
94
98
  write_temporary_dependency_files(yarn_lock)
@@ -5,6 +5,8 @@ require "dependabot/dependency"
5
5
  require "dependabot/file_parsers"
6
6
  require "dependabot/file_parsers/base"
7
7
  require "dependabot/shared_helpers"
8
+ require "dependabot/npm_and_yarn/registry_helper"
9
+ require "dependabot/experiments"
8
10
  require "sorbet-runtime"
9
11
 
10
12
  module Dependabot
@@ -12,6 +14,32 @@ module Dependabot
12
14
  module Helpers # rubocop:disable Metrics/ModuleLength
13
15
  extend T::Sig
14
16
 
17
+ # Thread-local storage for dependency files and credentials
18
+ # This allows automatic env variable injection without passing parameters everywhere
19
+ class << self
20
+ extend T::Sig
21
+
22
+ sig { params(files: T::Array[Dependabot::DependencyFile]).void }
23
+ def dependency_files=(files)
24
+ Thread.current[:npm_and_yarn_dependency_files] = files
25
+ end
26
+
27
+ sig { returns(T.nilable(T::Array[Dependabot::DependencyFile])) }
28
+ def dependency_files
29
+ T.cast(Thread.current[:npm_and_yarn_dependency_files], T.nilable(T::Array[Dependabot::DependencyFile]))
30
+ end
31
+
32
+ sig { params(creds: T::Array[Dependabot::Credential]).void }
33
+ def credentials=(creds)
34
+ Thread.current[:npm_and_yarn_credentials] = creds
35
+ end
36
+
37
+ sig { returns(T.nilable(T::Array[Dependabot::Credential])) }
38
+ def credentials
39
+ T.cast(Thread.current[:npm_and_yarn_credentials], T.nilable(T::Array[Dependabot::Credential]))
40
+ end
41
+ end
42
+
15
43
  YARN_PATH_NOT_FOUND =
16
44
  /^.*(?<error>The "yarn-path" option has been set \(in [^)]+\), but the specified location doesn't exist)/
17
45
 
@@ -268,13 +296,14 @@ module Dependabot
268
296
  ).returns(String)
269
297
  end
270
298
  def self.run_npm_command(command, fingerprint: command, env: nil)
299
+ merged_env = merge_corepack_env(env)
271
300
  if Dependabot::Experiments.enabled?(:enable_corepack_for_npm_and_yarn)
272
301
  package_manager_run_command(
273
302
  NpmPackageManager::NAME,
274
303
  command,
275
304
  fingerprint: fingerprint,
276
305
  output_observer: ->(output) { command_observer(output) },
277
- env: env
306
+ env: merged_env
278
307
  )
279
308
  else
280
309
  Dependabot::SharedHelpers.run_shell_command(
@@ -510,6 +539,35 @@ module Dependabot
510
539
  raise
511
540
  end
512
541
 
542
+ sig { params(env: T.nilable(T::Hash[String, String])).returns(T.nilable(T::Hash[String, String])) }
543
+ def self.merge_corepack_env(env)
544
+ corepack_env = build_corepack_env_variables
545
+ return env if corepack_env.nil? || corepack_env.empty?
546
+ return corepack_env if env.nil?
547
+
548
+ corepack_env.merge(env)
549
+ end
550
+
551
+ sig { returns(T.nilable(T::Hash[String, String])) }
552
+ def self.build_corepack_env_variables
553
+ return nil unless Dependabot::Experiments.enabled?(:enable_private_registry_for_corepack)
554
+ return nil if dependency_files.nil? || credentials.nil?
555
+
556
+ files = T.must(dependency_files)
557
+ creds = T.must(credentials)
558
+
559
+ registry_helper = RegistryHelper.new(
560
+ {
561
+ npmrc: files.find { |f| f.name.end_with?(".npmrc") },
562
+ yarnrc: files.find { |f| f.name.end_with?(".yarnrc") && !f.name.end_with?(".yarnrc.yml") },
563
+ yarnrc_yml: files.find { |f| f.name.end_with?(".yarnrc.yml") }
564
+ },
565
+ creds
566
+ )
567
+
568
+ registry_helper.find_corepack_env_variables
569
+ end
570
+
513
571
  private_class_method :run_single_yarn_command
514
572
 
515
573
  sig { params(pnpm_lock: DependencyFile).returns(T.nilable(String)) }
@@ -25,16 +25,12 @@ module Dependabot
25
25
  def self.run_npm8_subdependency_update_command(dependency_names)
26
26
  # NOTE: npm options
27
27
  # - `--force` ignores checks for platform (os, cpu) and engines
28
- # - `--dry-run=false` the updater sets a global .npmrc with dry-run: true to
29
- # work around an issue in npm 6, we don't want that here
30
28
  # - `--ignore-scripts` disables prepare and prepack scripts which are run
31
29
  # when installing git dependencies
32
30
  command = [
33
31
  "update",
34
32
  *dependency_names,
35
33
  "--force",
36
- "--dry-run",
37
- "false",
38
34
  "--ignore-scripts",
39
35
  "--package-lock-only"
40
36
  ].join(" ")
@@ -43,8 +39,6 @@ module Dependabot
43
39
  "update",
44
40
  "<dependency_names>",
45
41
  "--force",
46
- "--dry-run",
47
- "false",
48
42
  "--ignore-scripts",
49
43
  "--package-lock-only"
50
44
  ].join(" ")
@@ -46,7 +46,8 @@ module Dependabot
46
46
  env_variables[COREPACK_NPM_REGISTRY_ENV] = registry
47
47
  end
48
48
 
49
- env_variables[COREPACK_NPM_TOKEN_ENV] = registry_info[:auth_token] if registry_info[:auth_token]
49
+ # NOTE: We only set the registry, not the token
50
+ # The token should be configured in .npmrc for security
50
51
 
51
52
  env_variables
52
53
  end
@@ -87,7 +88,15 @@ module Dependabot
87
88
 
88
89
  @credentials.each do |cred|
89
90
  next unless cred["type"] == "npm_registry" # Skip if not an npm registry
90
- next unless cred["replaces-base"] # Skip if not a reverse-proxy registry
91
+
92
+ # Handle both Credential objects and plain hashes
93
+ replaces_base = if cred.respond_to?(:replaces_base?)
94
+ cred.replaces_base?
95
+ else
96
+ cred["replaces-base"]
97
+ end
98
+
99
+ next unless replaces_base # Skip if not a reverse-proxy registry
91
100
 
92
101
  # Set the registry if it's not already set
93
102
  registries[:registry] ||= cred["registry"]
@@ -95,10 +104,9 @@ module Dependabot
95
104
  # Set the token if it's not already set
96
105
  registries[:auth_token] ||= cred["token"]
97
106
  end
107
+
98
108
  registries
99
109
  end
100
-
101
- # Find registry and token in .npmrc or .yarnrc file
102
110
  sig do
103
111
  params(
104
112
  file: T.nilable(Dependabot::DependencyFile),
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.351.0
4
+ version: 0.352.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.351.0
18
+ version: 0.352.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.351.0
25
+ version: 0.352.0
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: debug
28
28
  requirement: !ruby/object:Gem::Requirement
@@ -361,7 +361,7 @@ licenses:
361
361
  - MIT
362
362
  metadata:
363
363
  bug_tracker_uri: https://github.com/dependabot/dependabot-core/issues
364
- changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.351.0
364
+ changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.352.0
365
365
  rdoc_options: []
366
366
  require_paths:
367
367
  - lib