dependabot-github_actions 0.390.0 → 0.392.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 915f664971e3665b0f6ee89557dc064b19fac2a49600250d2762a286fca20da7
4
- data.tar.gz: a02dc5897d62ee777fac539862d8e0cd728695d43f31ad531e1dc8c5a65db287
3
+ metadata.gz: 6a530d98ee5deaf59ae4a5fae27332419200128915c4586da2be88280572b200
4
+ data.tar.gz: 1a0809f4f2a0c74c16ffe96834d05f89a27ade9e2da665e7548f52b5d842d044
5
5
  SHA512:
6
- metadata.gz: b1d0fe90498dbae54af7ee1105a98c20a56128633d1ab72e11530e890726130f009fb581d616bda816985aa39a6dd1f7605ca94999e10e05a468d8f1ffecf752
7
- data.tar.gz: 76a7272475cb1ffcf7964f74f08ac3cfa80efe4612932f8d520b456c3fead93bfa195770420e494d7e1265b2bf0d2237e6b85e9143ed52bf02d52ed985db5ecb
6
+ metadata.gz: 1aced24aa66cc77c90d02bd74cf45daa7f06b471e1dd9c711ad1895a35d0ddc717d8448e37287b9306bbd0f6c0b6db761dfc88b930452b931311907a0537d641
7
+ data.tar.gz: 1d05ded519f6eedcef7d9dee3192b0fca26d47f8b9c0c83f5fe0848489741ff55be0c806f603f56e05a27e62fa54f0d38a3367685d12b4dad98a381fcc1be81a
@@ -4,47 +4,44 @@
4
4
  module Dependabot
5
5
  module GithubActions
6
6
  # Reference to the GitHub.com domain
7
- GITHUB_COM = T.let("github.com", String)
7
+ GITHUB_COM = "github.com"
8
8
 
9
9
  # Regular expression to match a GitHub repository reference
10
- GITHUB_REPO_REFERENCE = T.let(
11
- %r{
10
+ GITHUB_REPO_REFERENCE = %r{
12
11
  ^(?<owner>[\w.-]+)/
13
12
  (?<repo>[\w.-]+)
14
13
  (?<path>/[^\@]+)?
15
14
  @(?<ref>.+)
16
- }x,
17
- Regexp
18
- )
15
+ }x
19
16
 
20
17
  # The ecosystem name for GitHub Actions
21
- ECOSYSTEM = T.let("github_actions", String)
18
+ ECOSYSTEM = "github_actions"
22
19
 
23
20
  # The pattern to match manifest files
24
21
  MANIFEST_FILE_PATTERN = /\.ya?ml$/
25
22
  # The name of the manifest file
26
- MANIFEST_FILE_YML = T.let("action.yml", String)
23
+ MANIFEST_FILE_YML = "action.yml"
27
24
  # The name of the manifest file
28
- MANIFEST_FILE_YAML = T.let("action.yaml", String)
25
+ MANIFEST_FILE_YAML = "action.yaml"
29
26
  # The pattern to match any .yml or .yaml file
30
- ANYTHING_YML = T.let("<anything>.yml", String)
27
+ ANYTHING_YML = "<anything>.yml"
31
28
  # The path to the workflow directory
32
- WORKFLOW_DIRECTORY = T.let(".github/workflows", String)
29
+ WORKFLOW_DIRECTORY = ".github/workflows"
33
30
  # The path to the config .yml file
34
31
  CONFIG_YMLS = T.let("#{WORKFLOW_DIRECTORY}/#{ANYTHING_YML}".freeze, String)
35
32
 
36
33
  # The basename of the per-repo Actions lockfile generated by gh-actions-lock
37
- LOCKFILE_NAME = T.let("actions.lock", String)
34
+ LOCKFILE_NAME = "actions.lock"
38
35
  # The repo-relative path to the Actions lockfile
39
36
  LOCKFILE_PATH = T.let("#{WORKFLOW_DIRECTORY}/#{LOCKFILE_NAME}".freeze, String)
40
37
  # The only lockfile schema version this ecosystem understands.
41
- SUPPORTED_LOCKFILE_VERSION = T.let("v0.0.2", String)
38
+ SUPPORTED_LOCKFILE_VERSION = "v0.0.2"
42
39
 
43
- OWNER_KEY = T.let("owner", String)
44
- REPO_KEY = T.let("repo", String)
45
- PATH_KEY = T.let("path", String)
46
- REF_KEY = T.let("ref", String)
47
- USES_KEY = T.let("uses", String)
48
- STEPS_KEY = T.let("steps", String)
40
+ OWNER_KEY = "owner"
41
+ REPO_KEY = "repo"
42
+ PATH_KEY = "path"
43
+ REF_KEY = "ref"
44
+ USES_KEY = "uses"
45
+ STEPS_KEY = "steps"
49
46
  end
50
47
  end
@@ -12,10 +12,7 @@ module Dependabot
12
12
 
13
13
  # A missing commit has no containing branch, so callers can handle it like
14
14
  # an empty branch lookup without masking unrelated subprocess failures.
15
- COMMIT_NOT_FOUND_REGEX = T.let(
16
- /no such commit|malformed object name|bad object|not a valid object name/i,
17
- Regexp
18
- )
15
+ COMMIT_NOT_FOUND_REGEX = /no such commit|malformed object name|bad object|not a valid object name/i
19
16
 
20
17
  sig { params(sha: String).returns(T.nilable(String)) }
21
18
  def self.find(sha)
@@ -1,4 +1,4 @@
1
- # typed: strict
1
+ # typed: strong
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require "sorbet-runtime"
@@ -144,21 +144,21 @@ module Dependabot
144
144
  updated_requirement_pairs =
145
145
  dependency.requirements.zip(T.must(dependency.previous_requirements))
146
146
  .reject do |new_req, old_req|
147
- next true if new_req[:file] != file.name
147
+ next true if new_req.file != file.name
148
148
 
149
- new_req[:source] == T.must(old_req)[:source]
149
+ new_req.source == T.must(old_req).source
150
150
  end
151
151
 
152
152
  updated_content = T.must(file.content)
153
153
 
154
154
  updated_requirement_pairs.each do |new_req, old_req|
155
155
  # TODO: Support updating Docker sources
156
- next unless new_req.fetch(:source).fetch(:type) == "git"
156
+ next unless new_req.source_string("type") == "git"
157
157
 
158
- old_ref = T.must(old_req).fetch(:source).fetch(:ref)
159
- new_ref = new_req.fetch(:source).fetch(:ref)
158
+ old_ref = T.must(T.must(old_req).source_string("ref"))
159
+ new_ref = T.must(new_req.source_string("ref"))
160
160
 
161
- old_declaration = T.must(old_req).fetch(:metadata).fetch(:declaration_string)
161
+ old_declaration = T.must(T.must(old_req).metadata_string("declaration_string"))
162
162
  new_declaration =
163
163
  old_declaration
164
164
  .gsub(/@.*+/, "@#{new_ref}")
@@ -24,8 +24,8 @@ module Dependabot
24
24
  extend T::Sig
25
25
 
26
26
  JsonObject = T.type_alias { T::Hash[String, Object] }
27
- FIXED_FINDING_CATEGORIES = T.let(%w(onboarding-required ref-changed stale).freeze, T::Array[String])
28
- UNRESOLVABLE_CATEGORIES = T.let(%w(impostor-commit lockfile-forgery).freeze, T::Array[String])
27
+ FIXED_FINDING_CATEGORIES = %w(onboarding-required ref-changed stale).freeze
28
+ UNRESOLVABLE_CATEGORIES = %w(impostor-commit lockfile-forgery).freeze
29
29
 
30
30
  sig { params(credentials: T::Array[Dependabot::Credential]).void }
31
31
  def initialize(credentials)
@@ -17,7 +17,7 @@ module Dependabot
17
17
 
18
18
  # Placeholder satisfies go-gh's "token must be present" check in hosted mode
19
19
  # where the proxy supplies real auth. Mirrors git's installation-token username.
20
- DUMMY_TOKEN = T.let("x-access-token", String)
20
+ DUMMY_TOKEN = "x-access-token"
21
21
 
22
22
  sig do
23
23
  params(credentials: T::Array[Dependabot::Credential])
@@ -21,16 +21,16 @@ module Dependabot
21
21
  ParsedObject = T.type_alias { T::Hash[String, Object] }
22
22
 
23
23
  # Every commit must carry an explicit hash-algorithm prefix.
24
- ALGO_PREFIXES = T.let(%w(sha1- sha256-).freeze, T::Array[String])
24
+ ALGO_PREFIXES = %w(sha1- sha256-).freeze
25
25
 
26
26
  # Keys gh-actions-lock requires on every `dependencies` entry. A missing key
27
27
  # makes the engine silently discard the whole lockfile in memory and report
28
28
  # every workflow as un-onboarded.
29
- REQUIRED_DEPENDENCY_KEYS = T.let(%w(ref commit owner_id repo_id).freeze, T::Array[String])
29
+ REQUIRED_DEPENDENCY_KEYS = %w(ref commit owner_id repo_id).freeze
30
30
 
31
31
  sig { params(content: String).void }
32
32
  def initialize(content)
33
- @content = T.let(content, String)
33
+ @content = content
34
34
  @data = T.let(parse, ParsedObject)
35
35
  end
36
36
 
@@ -15,14 +15,9 @@ module Dependabot
15
15
 
16
16
  sig { override.returns(T.nilable(Dependabot::Source)) }
17
17
  def look_up_source
18
- info = dependency.requirements.filter_map { |r| r[:source] }.first
19
-
20
- url =
21
- if info.nil?
22
- "https://#{source_hostname}/#{dependency.name}"
23
- else
24
- info[:url] || info.fetch("url")
25
- end
18
+ requirement = dependency.requirements.find(&:source_hash)
19
+ url = requirement&.source_string("url") ||
20
+ "https://#{source_hostname}/#{dependency.name}"
26
21
  Source.from_url(url)
27
22
  end
28
23
 
@@ -13,10 +13,10 @@ module Dependabot
13
13
  extend T::Sig
14
14
 
15
15
  # The package manager name for GitHub Actions
16
- NAME = T.let("github_actions", String)
16
+ NAME = "github_actions"
17
17
 
18
18
  # The version of the package manager
19
- VERSION = T.let("1.0.0", String)
19
+ VERSION = "1.0.0"
20
20
 
21
21
  sig { void }
22
22
  def initialize
@@ -131,9 +131,7 @@ module Dependabot
131
131
  if latest_tag&.fetch(:version) == selected_release
132
132
  latest_tag
133
133
  else
134
- T.must(package_details_fetcher)
135
- .allowed_version_tags_with_release_dates
136
- .find { |tag_hash| tag_hash.fetch(:version) == selected_release }
134
+ tag_for_version(selected_release)
137
135
  end
138
136
  end
139
137
  end,
@@ -224,14 +222,23 @@ module Dependabot
224
222
  tags_in_cooldown = Set.new(select_version_tags_in_cooldown_period(allowed_versions_with_dates))
225
223
  return release if tags_in_cooldown.empty?
226
224
 
227
- # Walk through all allowed version tags in descending order (newest first)
225
+ # Only consider tags with the same precision as the pinned ref, so a `v1` style
226
+ # pin falls back to another major-only tag rather than being rewritten to a fully
227
+ # qualified version such as `v1.5.5`.
228
+ candidates = tags_matching_pinned_precision(allowed_versions_with_dates)
229
+
230
+ # Walk through the candidate version tags in descending order (newest first)
228
231
  # and return the first one NOT in cooldown
229
- allowed_versions_with_dates.each do |tag_info|
232
+ candidates.each do |tag_info|
230
233
  tag_name = tag_info.fetch(:tag)
231
234
  next if tags_in_cooldown.include?(tag_name)
232
235
 
233
- # Found a version not in cooldown, return it
234
236
  version = tag_info.fetch(:version)
237
+ # Candidates are sorted descending, so once we drop below the pinned version
238
+ # every remaining candidate would be a downgrade.
239
+ break if pinned_version && version < pinned_version
240
+
241
+ # Found a version not in cooldown, return it
235
242
  Dependabot.logger.info("Found acceptable version outside cooldown: #{version}")
236
243
  return version
237
244
  end
@@ -241,6 +248,46 @@ module Dependabot
241
248
  nil
242
249
  end
243
250
 
251
+ # Tags whose version has the same number of segments as the currently pinned
252
+ # version. Returns every tag when the pin isn't a version we can reason about
253
+ # (e.g. a commit SHA), since precision has no meaning in that case.
254
+ sig do
255
+ params(tags: T::Array[T::Hash[Symbol, T.untyped]])
256
+ .returns(T::Array[T::Hash[Symbol, T.untyped]])
257
+ end
258
+ def tags_matching_pinned_precision(tags)
259
+ pinned = pinned_version
260
+ return tags unless pinned
261
+
262
+ pinned_precision = precision(pinned.to_s)
263
+ tags.select { |tag_info| precision(tag_info.fetch(:version).to_s) == pinned_precision }
264
+ end
265
+
266
+ # Resolves a version back to its tag. Versions compare equal across precisions
267
+ # (`2` == `2.0.0`), so tags matching the pinned precision are preferred to avoid
268
+ # rewriting e.g. a `v2` pin to `v2.0.0`.
269
+ sig { params(version: Dependabot::Version).returns(T.nilable(T::Hash[Symbol, T.untyped])) }
270
+ def tag_for_version(version)
271
+ all_tags = T.must(package_details_fetcher).allowed_version_tags_with_release_dates
272
+ matching_precision = tags_matching_pinned_precision(all_tags)
273
+
274
+ matching_precision.find { |tag_hash| tag_hash.fetch(:version) == version } ||
275
+ all_tags.find { |tag_hash| tag_hash.fetch(:version) == version }
276
+ end
277
+
278
+ sig { returns(T.nilable(Dependabot::Version)) }
279
+ def pinned_version
280
+ version = dependency.version
281
+ return nil unless version && Dependabot::GithubActions::Version.correct?(version)
282
+
283
+ Dependabot::GithubActions::Version.new(version)
284
+ end
285
+
286
+ sig { params(version: String).returns(Integer) }
287
+ def precision(version)
288
+ version.split(".").length
289
+ end
290
+
244
291
  sig do
245
292
  params(
246
293
  tags_with_dates: T.nilable(
@@ -65,24 +65,14 @@ module Dependabot
65
65
  sig { override.returns(T::Array[Dependabot::DependencyRequirement]) }
66
66
  def updated_requirements
67
67
  updated_reqs = dependency.requirements.map do |req|
68
- source = T.cast(req.source, GitSource)
68
+ source = req.source_hash
69
69
  updated = updated_ref(source, onboarded: onboarded_requirement?(req))
70
70
  next req unless updated
71
71
 
72
- current = source[:ref]
73
-
74
- # Maintain a short git hash only if it matches the latest
75
- if req[:type] == "git" &&
76
- git_commit_checker.ref_looks_like_commit_sha?(updated) &&
77
- git_commit_checker.ref_looks_like_commit_sha?(T.must(current)) &&
78
- updated.start_with?(T.must(current))
79
- next req
80
- end
81
-
82
- new_source = source.merge(ref: updated)
83
- req.merge(source: new_source)
72
+ new_source = source_with_ref(T.must(source), updated)
73
+ Dependabot::DependencyRequirement.create(req.merge(source: new_source))
84
74
  end
85
- wrap_requirements(updated_reqs)
75
+ updated_reqs
86
76
  end
87
77
 
88
78
  private
@@ -171,9 +161,7 @@ module Dependabot
171
161
  @git_metadata_fetcher ||= T.let(
172
162
  Dependabot::GitMetadataFetcher.new(
173
163
  url: T.must(
174
- dependency.requirements.filter_map do |requirement|
175
- T.cast(requirement.source, T.nilable(GitSource))&.fetch(:url, nil)
176
- end.first
164
+ dependency.requirements.filter_map { |requirement| requirement.source_string("url") }.first
177
165
  ),
178
166
  credentials: credentials
179
167
  ),
@@ -248,20 +236,24 @@ module Dependabot
248
236
  end
249
237
 
250
238
  sig do
251
- params(source: T.nilable(GitSource), onboarded: T::Boolean)
239
+ params(
240
+ source: T.nilable(Dependabot::DependencyRequirement::ObjectHash),
241
+ onboarded: T::Boolean
242
+ )
252
243
  .returns(T.nilable(String))
253
244
  end
254
245
  def updated_ref(source, onboarded: false)
255
246
  # TODO: Support Docker sources
256
247
  return unless git_commit_checker.git_dependency?
257
248
 
258
- finder = onboarded ? latest_version_finder_for(source) : T.must(latest_version_finder)
249
+ git_source = source && symbolize_source(source)
250
+ finder = onboarded ? latest_version_finder_for(git_source) : T.must(latest_version_finder)
259
251
 
260
252
  if vulnerable? && (new_tag = finder.lowest_security_fix_release)
261
253
  return new_tag.fetch(:tag)
262
254
  end
263
255
 
264
- source_git_commit_checker = git_helper.git_commit_checker_for(source)
256
+ source_git_commit_checker = git_helper.git_commit_checker_for(git_source)
265
257
 
266
258
  # Return the git tag if updating a pinned version
267
259
  if source_git_commit_checker.pinned_ref_looks_like_version? &&
@@ -279,6 +271,35 @@ module Dependabot
279
271
  nil
280
272
  end
281
273
 
274
+ sig do
275
+ params(source: Dependabot::DependencyRequirement::ObjectHash)
276
+ .returns(GitSource)
277
+ end
278
+ def symbolize_source(source)
279
+ T.cast(source.to_h { |key, value| [key.to_sym, value] }, GitSource)
280
+ end
281
+
282
+ sig do
283
+ params(
284
+ source: Dependabot::DependencyRequirement::ObjectHash,
285
+ ref: String
286
+ ).returns(Dependabot::DependencyRequirement::ObjectHash)
287
+ end
288
+ def source_with_ref(source, ref)
289
+ updated = source.dup
290
+ key = if source.key?(:ref)
291
+ :ref
292
+ elsif source.key?("ref")
293
+ "ref"
294
+ elsif source.keys.any?(Symbol)
295
+ :ref
296
+ else
297
+ "ref"
298
+ end
299
+ updated[key] = ref
300
+ updated
301
+ end
302
+
282
303
  sig do
283
304
  params(source_checker: Dependabot::GitCommitChecker, finder: LatestVersionFinder)
284
305
  .returns(T.nilable(String))
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dependabot-github_actions
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.390.0
4
+ version: 0.392.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.390.0
18
+ version: 0.392.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.390.0
25
+ version: 0.392.0
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: debug
28
28
  requirement: !ruby/object:Gem::Requirement
@@ -266,7 +266,7 @@ licenses:
266
266
  - MIT
267
267
  metadata:
268
268
  bug_tracker_uri: https://github.com/dependabot/dependabot-core/issues
269
- changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.390.0
269
+ changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.392.0
270
270
  rdoc_options: []
271
271
  require_paths:
272
272
  - lib