dependabot-github_actions 0.212.0 → 0.214.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: b99470ea707631aca82d807b49067151dfcae50d66c60edc46d745c9616a0d74
4
- data.tar.gz: 199d27e6b67a81fe6f6728ab6a88800851788388b419b0b2df1ca6568c38b71b
3
+ metadata.gz: b3804334c168c6ac968941c3fd695443875744a48e66825e0247a10089003b77
4
+ data.tar.gz: 92571e11e014c22477a152c8035d77022df7faad94b303677788e937d31d6231
5
5
  SHA512:
6
- metadata.gz: 3a39a5301c8164912dca155d1f76237ee7023c332dd39d1aee61f9d57bfb222e8b67f41604a25806f9aca6bd8862bcbeff21243e54a3afac416e9027afd42ae1
7
- data.tar.gz: 9ea44575276134e6b20f23ac77db0d91b6e2b7d5bba7f52006ed7715cd6864825e53933ae9559bfeb3d2e317c2e8b652d3709247ea203f14e635fc047fdb939f
6
+ metadata.gz: 6397641d12b9fb86fbc34fec837b05c3669f9ebb3a96dd27fa2912098ac1f158dcf6f39995065a417013ba22e169931a4886c2e15109bcf446a4f83191ec03a4
7
+ data.tar.gz: d706bb33be9d40cd470c6977a6268887fddacbf799ea30b604a5569ac50347589b8acf25ad6f9d924ccd78c9ce31b515fe8564118dc1705825e6c73055265e6d
@@ -6,7 +6,7 @@ require "dependabot/file_fetchers/base"
6
6
  module Dependabot
7
7
  module GithubActions
8
8
  class FileFetcher < Dependabot::FileFetchers::Base
9
- FILENAME_PATTERN = /^(\.github|action.ya?ml)$/.freeze
9
+ FILENAME_PATTERN = /^(\.github|action.ya?ml)$/
10
10
 
11
11
  def self.required_files_in?(filenames)
12
12
  filenames.any? { |f| f.match?(FILENAME_PATTERN) }
@@ -26,9 +26,16 @@ module Dependabot
26
26
  return fetched_files if fetched_files.any?
27
27
 
28
28
  if incorrectly_encoded_workflow_files.none?
29
+ expected_paths =
30
+ if directory == "/"
31
+ File.join(directory, "action.yml") + " or /.github/workflows/<anything>.yml"
32
+ else
33
+ File.join(directory, "<anything>.yml")
34
+ end
35
+
29
36
  raise(
30
37
  Dependabot::DependencyFileNotFound,
31
- File.join(directory, "action.yml") + " or /.github/workflows/<anything>.yml"
38
+ expected_paths
32
39
  )
33
40
  else
34
41
  raise(
@@ -41,16 +48,22 @@ module Dependabot
41
48
  def workflow_files
42
49
  return @workflow_files if defined? @workflow_files
43
50
 
44
- @workflow_files = [fetch_file_if_present("action.yml"), fetch_file_if_present("action.yaml")].compact
51
+ @workflow_files = []
45
52
 
46
53
  # In the special case where the root directory is defined we also scan
47
54
  # the .github/workflows/ folder.
48
- return @workflow_files unless directory == "/"
55
+ if directory == "/"
56
+ @workflow_files += [fetch_file_if_present("action.yml"), fetch_file_if_present("action.yaml")].compact
57
+
58
+ workflows_dir = ".github/workflows"
59
+ else
60
+ workflows_dir = "."
61
+ end
49
62
 
50
63
  @workflow_files +=
51
- repo_contents(dir: ".github/workflows", raise_errors: false).
64
+ repo_contents(dir: workflows_dir, raise_errors: false).
52
65
  select { |f| f.type == "file" && f.name.match?(/\.ya?ml$/) }.
53
- map { |f| fetch_file_from_host(".github/workflows/#{f.name}") }
66
+ map { |f| fetch_file_from_host("#{workflows_dir}/#{f.name}") }
54
67
  end
55
68
 
56
69
  def referenced_local_workflow_files
@@ -21,7 +21,7 @@ module Dependabot
21
21
  (?<repo>[\w.-]+)
22
22
  (?<path>/[^\@]+)?
23
23
  @(?<ref>.+)
24
- }x.freeze
24
+ }x
25
25
 
26
26
  def parse
27
27
  dependency_set = DependencySet.new
@@ -94,7 +94,7 @@ module Dependabot
94
94
  git_checker = Dependabot::GitCommitChecker.new(dependency: dep, credentials: credentials)
95
95
  next unless git_checker.pinned_ref_looks_like_commit_sha?
96
96
 
97
- resolved = git_checker.local_tag_for_pinned_version
97
+ resolved = git_checker.local_tag_for_pinned_sha
98
98
  next if resolved.nil? || !version_class.correct?(resolved)
99
99
 
100
100
  # Build a Dependency with the resolved version, and rely on DependencySet's merge
@@ -65,17 +65,41 @@ module Dependabot
65
65
  gsub(/@.*+/, "@#{new_req.fetch(:source).fetch(:ref)}")
66
66
 
67
67
  # Replace the old declaration that's preceded by a non-word character
68
- # and followed by a whitespace character (comments) or EOL
68
+ # and followed by a whitespace character (comments) or EOL.
69
+ # If the declaration is followed by a comment that lists the version associated
70
+ # with the SHA source ref, then update the comment to the human-readable new version.
71
+ # However, if the comment includes additional text beyond the version, for safety
72
+ # we skip updating the comment in case it's a custom note, todo, warning etc of some kind.
73
+ # See the related unit tests for examples.
69
74
  updated_content =
70
75
  updated_content.
71
76
  gsub(
72
- /(?<=\W|"|')#{Regexp.escape(old_declaration)}(?=\s|"|'|$)/,
73
- new_declaration
74
- )
77
+ /(?<=\W|"|')#{Regexp.escape(old_declaration)}(?<comment>\s+#.*)?(?=\s|"|'|$)/
78
+ ) do |match|
79
+ comment = Regexp.last_match(:comment)
80
+ match.gsub!(old_declaration, new_declaration)
81
+ if comment && (updated_comment = updated_version_comment(comment, new_req))
82
+ match.gsub!(comment, updated_comment)
83
+ end
84
+ match
85
+ end
75
86
  end
76
87
 
77
88
  updated_content
78
89
  end
90
+
91
+ def updated_version_comment(comment, new_req)
92
+ raise "No comment!" unless comment
93
+
94
+ comment = comment.rstrip
95
+ return unless dependency.previous_version && dependency.version
96
+ return unless comment.end_with? dependency.previous_version
97
+
98
+ git_checker = Dependabot::GitCommitChecker.new(dependency: dependency, credentials: credentials)
99
+ return unless git_checker.ref_looks_like_commit_sha?(new_req.fetch(:source).fetch(:ref))
100
+
101
+ comment.gsub(dependency.previous_version, dependency.version)
102
+ end
79
103
  end
80
104
  end
81
105
  end
@@ -7,7 +7,7 @@ module Dependabot
7
7
  module GithubActions
8
8
  # Lifted from the bundler package manager
9
9
  class Requirement < Gem::Requirement
10
- # For consistency with other langauges, we define a requirements array.
10
+ # For consistency with other languages, we define a requirements array.
11
11
  # Ruby doesn't have an `OR` separator for requirements, so it always
12
12
  # contains a single element.
13
13
  def self.requirements_array(requirement_string)
@@ -2,6 +2,7 @@
2
2
 
3
3
  require "dependabot/update_checkers"
4
4
  require "dependabot/update_checkers/base"
5
+ require "dependabot/update_checkers/version_filters"
5
6
  require "dependabot/errors"
6
7
  require "dependabot/github_actions/version"
7
8
  require "dependabot/github_actions/requirement"
@@ -23,6 +24,15 @@ module Dependabot
23
24
  dependency.version
24
25
  end
25
26
 
27
+ def lowest_security_fix_version
28
+ @lowest_security_fix_version ||= fetch_lowest_security_fix_version
29
+ end
30
+
31
+ def lowest_resolvable_security_fix_version
32
+ # Resolvability isn't an issue for GitHub Actions.
33
+ lowest_security_fix_version
34
+ end
35
+
26
36
  def updated_requirements # rubocop:disable Metrics/PerceivedComplexity
27
37
  previous = dependency_source_details
28
38
  updated = updated_source
@@ -42,6 +52,12 @@ module Dependabot
42
52
 
43
53
  private
44
54
 
55
+ def active_advisories
56
+ security_advisories.select do |advisory|
57
+ advisory.vulnerable?(version_class.new(git_commit_checker.most_specific_tag_equivalent_to_pinned_ref))
58
+ end
59
+ end
60
+
45
61
  def latest_version_resolvable_with_full_unlock?
46
62
  # Full unlock checks aren't relevant for GitHub Actions
47
63
  false
@@ -65,7 +81,7 @@ module Dependabot
65
81
  # we want to update that tag.
66
82
  if git_commit_checker.pinned_ref_looks_like_version? && latest_version_tag
67
83
  latest_version = latest_version_tag.fetch(:version)
68
- return version_class.new(dependency.version) if shortened_semver_eq?(dependency.version, latest_version.to_s)
84
+ return current_version if shortened_semver_eq?(dependency.version, latest_version.to_s)
69
85
 
70
86
  return latest_version
71
87
  end
@@ -82,45 +98,85 @@ module Dependabot
82
98
  nil
83
99
  end
84
100
 
85
- def latest_commit_for_pinned_ref
86
- @latest_commit_for_pinned_ref ||=
87
- SharedHelpers.in_a_temporary_repo_directory("/", repo_contents_path) do
88
- ref_branch = find_container_branch(current_commit)
101
+ def fetch_lowest_security_fix_version
102
+ # TODO: Support Docker sources
103
+ return unless git_dependency?
104
+
105
+ fetch_lowest_security_fix_version_for_git_dependency
106
+ end
107
+
108
+ def fetch_lowest_security_fix_version_for_git_dependency
109
+ lowest_security_fix_version_tag.fetch(:version)
110
+ end
89
111
 
90
- git_commit_checker.head_commit_for_local_branch(ref_branch)
112
+ def lowest_security_fix_version_tag
113
+ @lowest_security_fix_version_tag ||= begin
114
+ tags_matching_precision = git_commit_checker.local_tags_for_allowed_versions_matching_existing_precision
115
+ lowest_fixed_version = find_lowest_secure_version(tags_matching_precision)
116
+ if lowest_fixed_version
117
+ lowest_fixed_version
118
+ else
119
+ tags = git_commit_checker.local_tags_for_allowed_versions
120
+ find_lowest_secure_version(tags)
91
121
  end
122
+ end
92
123
  end
93
124
 
94
- def latest_version_tag
95
- @latest_version_tag ||= begin
96
- return git_commit_checker.local_tag_for_latest_version if dependency.version.nil?
125
+ def find_lowest_secure_version(tags)
126
+ relevant_tags = Dependabot::UpdateCheckers::VersionFilters.filter_vulnerable_versions(tags, security_advisories)
127
+ relevant_tags = filter_lower_tags(relevant_tags)
97
128
 
98
- latest_tags = git_commit_checker.local_tags_for_latest_version_commit_sha
129
+ relevant_tags.min_by { |tag| tag.fetch(:version) }
130
+ end
99
131
 
100
- # Find the latest version with the same precision as the pinned version.
101
- # Falls back to a version with the closest precision if no exact match.
102
- current_dots = dependency.version.split(".").length
103
- latest_tags.max do |a, b|
104
- next a[:version] <=> b[:version] unless shortened_semver_version_eq?(a[:version], b[:version])
132
+ def latest_commit_for_pinned_ref
133
+ @latest_commit_for_pinned_ref ||= begin
134
+ head_commit_for_ref_sha = git_commit_checker.head_commit_for_pinned_ref
135
+ if head_commit_for_ref_sha
136
+ head_commit_for_ref_sha
137
+ else
138
+ url = dependency_source_details[:url]
139
+ source = Source.from_url(url)
140
+
141
+ SharedHelpers.in_a_temporary_directory(File.dirname(source.repo)) do |temp_dir|
142
+ repo_contents_path = File.join(temp_dir, File.basename(source.repo))
105
143
 
106
- a_dots = a[:version].to_s.split(".").length
107
- b_dots = b[:version].to_s.split(".").length
108
- a_diff = (a_dots - current_dots).abs
109
- b_diff = (b_dots - current_dots).abs
110
- next -(a_diff <=> b_diff) unless a_diff == b_diff
144
+ SharedHelpers.run_shell_command("git clone --no-recurse-submodules #{url} #{repo_contents_path}")
111
145
 
112
- # preference to a less specific version if we have a tie
113
- next 1 if a_dots < current_dots
146
+ Dir.chdir(repo_contents_path) do
147
+ ref_branch = find_container_branch(dependency_source_details[:ref])
114
148
 
115
- -1
149
+ git_commit_checker.head_commit_for_local_branch(ref_branch)
150
+ end
151
+ end
116
152
  end
117
153
  end
118
154
  end
119
155
 
156
+ def latest_version_tag
157
+ @latest_version_tag ||= begin
158
+ return git_commit_checker.local_tag_for_latest_version if dependency.version.nil?
159
+
160
+ git_commit_checker.local_ref_for_latest_version_matching_existing_precision
161
+ end
162
+ end
163
+
164
+ def filter_lower_tags(tags_array)
165
+ return tags_array unless current_version
166
+
167
+ tags_array.
168
+ select { |tag| tag.fetch(:version) > current_version }
169
+ end
170
+
120
171
  def updated_source
121
172
  # TODO: Support Docker sources
122
173
  return dependency_source_details unless git_dependency?
123
174
 
175
+ if vulnerable? &&
176
+ (new_tag = lowest_security_fix_version_tag)
177
+ return dependency_source_details.merge(ref: new_tag.fetch(:tag))
178
+ end
179
+
124
180
  # Update the git tag if updating a pinned version
125
181
  if git_commit_checker.pinned_ref_looks_like_version? &&
126
182
  (new_tag = latest_version_tag) &&
@@ -179,7 +235,8 @@ module Dependabot
179
235
  dependency: dependency,
180
236
  credentials: credentials,
181
237
  ignored_versions: ignored_versions,
182
- raise_on_ignored: raise_on_ignored
238
+ raise_on_ignored: raise_on_ignored,
239
+ consider_version_branches_pinned: true
183
240
  )
184
241
  end
185
242
 
@@ -193,25 +250,18 @@ module Dependabot
193
250
  other_split[0..base_split.length - 1] == base_split
194
251
  end
195
252
 
196
- def shortened_semver_version_eq?(base_version, other_version)
197
- base = base_version.to_s
198
- other = other_version.to_s
199
-
200
- shortened_semver_eq?(base, other) || shortened_semver_eq?(other, base)
201
- end
202
-
203
253
  def find_container_branch(sha)
204
- SharedHelpers.run_shell_command("git fetch #{current_commit}")
205
-
206
- branches_including_ref = SharedHelpers.run_shell_command("git branch --contains #{sha}").split("\n")
254
+ branches_including_ref = SharedHelpers.run_shell_command(
255
+ "git branch --remotes --contains #{sha}"
256
+ ).split("\n").map { |branch| branch.strip.gsub("origin/", "") }
207
257
 
208
- current_branch = branches_including_ref.find { |line| line.start_with?("* ") }
258
+ current_branch = branches_including_ref.find { |branch| branch.start_with?("HEAD -> ") }
209
259
 
210
260
  if current_branch
211
- current_branch.delete_prefix("* ")
261
+ current_branch.delete_prefix("HEAD -> ")
212
262
  elsif branches_including_ref.size > 1
213
263
  # If there are multiple non default branches including the pinned SHA, then it's unclear how we should proceed
214
- raise "Multiple ambiguous branches (#{branches_including_ref.join(', ')}) include #{current_commit}!"
264
+ raise "Multiple ambiguous branches (#{branches_including_ref.join(', ')}) include #{sha}!"
215
265
  else
216
266
  branches_including_ref.first
217
267
  end
@@ -22,6 +22,3 @@ Dependabot::PullRequestCreator::Labeler.
22
22
  require "dependabot/dependency"
23
23
  Dependabot::Dependency.
24
24
  register_production_check("github_actions", ->(_) { true })
25
-
26
- require "dependabot/utils"
27
- Dependabot::Utils.register_always_clone("github_actions")
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dependabot-github_actions
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.212.0
4
+ version: 0.214.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dependabot
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-09-06 00:00:00.000000000 Z
11
+ date: 2022-12-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dependabot-common
@@ -16,42 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 0.212.0
19
+ version: 0.214.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: 0.212.0
27
- - !ruby/object:Gem::Dependency
28
- name: debase
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - '='
32
- - !ruby/object:Gem::Version
33
- version: 0.2.3
34
- type: :development
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - '='
39
- - !ruby/object:Gem::Version
40
- version: 0.2.3
41
- - !ruby/object:Gem::Dependency
42
- name: debase-ruby_core_source
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - '='
46
- - !ruby/object:Gem::Version
47
- version: 0.10.16
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - '='
53
- - !ruby/object:Gem::Version
54
- version: 0.10.16
26
+ version: 0.214.0
55
27
  - !ruby/object:Gem::Dependency
56
28
  name: debug
57
29
  requirement: !ruby/object:Gem::Requirement
@@ -86,14 +58,14 @@ dependencies:
86
58
  requirements:
87
59
  - - "~>"
88
60
  - !ruby/object:Gem::Version
89
- version: 3.12.0
61
+ version: 4.0.0
90
62
  type: :development
91
63
  prerelease: false
92
64
  version_requirements: !ruby/object:Gem::Requirement
93
65
  requirements:
94
66
  - - "~>"
95
67
  - !ruby/object:Gem::Version
96
- version: 3.12.0
68
+ version: 4.0.0
97
69
  - !ruby/object:Gem::Dependency
98
70
  name: rake
99
71
  requirement: !ruby/object:Gem::Requirement
@@ -142,42 +114,28 @@ dependencies:
142
114
  requirements:
143
115
  - - "~>"
144
116
  - !ruby/object:Gem::Version
145
- version: 1.36.0
117
+ version: 1.39.0
146
118
  type: :development
147
119
  prerelease: false
148
120
  version_requirements: !ruby/object:Gem::Requirement
149
121
  requirements:
150
122
  - - "~>"
151
123
  - !ruby/object:Gem::Version
152
- version: 1.36.0
124
+ version: 1.39.0
153
125
  - !ruby/object:Gem::Dependency
154
126
  name: rubocop-performance
155
127
  requirement: !ruby/object:Gem::Requirement
156
128
  requirements:
157
129
  - - "~>"
158
130
  - !ruby/object:Gem::Version
159
- version: 1.14.2
160
- type: :development
161
- prerelease: false
162
- version_requirements: !ruby/object:Gem::Requirement
163
- requirements:
164
- - - "~>"
165
- - !ruby/object:Gem::Version
166
- version: 1.14.2
167
- - !ruby/object:Gem::Dependency
168
- name: ruby-debug-ide
169
- requirement: !ruby/object:Gem::Requirement
170
- requirements:
171
- - - "~>"
172
- - !ruby/object:Gem::Version
173
- version: 0.7.3
131
+ version: 1.15.0
174
132
  type: :development
175
133
  prerelease: false
176
134
  version_requirements: !ruby/object:Gem::Requirement
177
135
  requirements:
178
136
  - - "~>"
179
137
  - !ruby/object:Gem::Version
180
- version: 0.7.3
138
+ version: 1.15.0
181
139
  - !ruby/object:Gem::Dependency
182
140
  name: simplecov
183
141
  requirement: !ruby/object:Gem::Requirement
@@ -275,14 +233,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
275
233
  requirements:
276
234
  - - ">="
277
235
  - !ruby/object:Gem::Version
278
- version: 2.7.0
236
+ version: 3.1.0
279
237
  required_rubygems_version: !ruby/object:Gem::Requirement
280
238
  requirements:
281
239
  - - ">="
282
240
  - !ruby/object:Gem::Version
283
- version: 2.7.0
241
+ version: 3.1.0
284
242
  requirements: []
285
- rubygems_version: 3.1.6
243
+ rubygems_version: 3.3.7
286
244
  signing_key:
287
245
  specification_version: 4
288
246
  summary: GitHub Actions support for dependabot-common