dependabot-docker 0.296.0 → 0.296.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7d73f1ca0edd3883c63fc068f9193b5cad4cd1d7ab3aa3284b6baaf2b82710e6
4
- data.tar.gz: 43d31badacfcaf0de6c5fbbf99afcb967e8be37dcf3eac5d86583b8e8e962c4d
3
+ metadata.gz: 8143dd1e38323ca8d27cb0e0e229af3ae6d7291a945860fe495efb7c68707649
4
+ data.tar.gz: 37a0909536317744ba22fb800752fe4bc80565571a4f73dcbab7dede3e087d16
5
5
  SHA512:
6
- metadata.gz: 546df875ae2acc06f1801a2daf554fb85ae10df63f6b91e0db1c330b2cb608d3a454afbc4dab4125b97fe5faa63c6130466df40434de55457d955315161fdf4b
7
- data.tar.gz: 8848b1add1aa64b5a30e2eea1166dcede4371313e2c31960a02500c24f6df209cd148bd23a2072815c72821bd66e76174f5048977ee6fa2deb33fc9fd724f866
6
+ metadata.gz: 9543d1404fafc293c74e4c6ca95e957ca5a44a1c2a4c6926be8247e3b9f263794afb1ad782793017d801f0e0c1e6b18990e16d841f2e9b64ea432ce21aad4a6b
7
+ data.tar.gz: 6abbd8372171744ddf1d4317091ca43f9b09262ccb6e0e33777b996dfa90b0fabd42c9565881a990f11a795a1f2a73e8fb84f97a33026cc8cc92cac557034223
@@ -1,7 +1,8 @@
1
- # typed: true
1
+ # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require "docker_registry2"
5
+ require "sorbet-runtime"
5
6
 
6
7
  require "dependabot/update_checkers"
7
8
  require "dependabot/update_checkers/base"
@@ -14,21 +15,28 @@ require "dependabot/docker/utils/credentials_finder"
14
15
 
15
16
  module Dependabot
16
17
  module Docker
18
+ # rubocop:disable Metrics/ClassLength
17
19
  class UpdateChecker < Dependabot::UpdateCheckers::Base
20
+ extend T::Sig
21
+
22
+ sig { override.returns(T.nilable(T.any(String, Gem::Version))) }
18
23
  def latest_version
19
- latest_version_from(dependency.version)
24
+ latest_version_from(T.must(dependency.version))
20
25
  end
21
26
 
27
+ sig { override.returns(T.nilable(T.any(String, Gem::Version))) }
22
28
  def latest_resolvable_version
23
29
  # Resolvability isn't an issue for Docker containers.
24
30
  latest_version
25
31
  end
26
32
 
33
+ sig { override.returns(T.nilable(String)) }
27
34
  def latest_resolvable_version_with_no_unlock
28
35
  # No concept of "unlocking" for Docker containers
29
36
  dependency.version
30
37
  end
31
38
 
39
+ sig { override.returns(T::Array[T::Hash[Symbol, T.untyped]]) }
32
40
  def updated_requirements
33
41
  dependency.requirements.map do |req|
34
42
  updated_source = req.fetch(:source).dup
@@ -50,16 +58,19 @@ module Dependabot
50
58
 
51
59
  private
52
60
 
61
+ sig { override.returns(T::Boolean) }
53
62
  def latest_version_resolvable_with_full_unlock?
54
63
  # Full unlock checks aren't relevant for Dockerfiles
55
64
  false
56
65
  end
57
66
 
67
+ sig { override.returns(T::Array[Dependabot::Dependency]) }
58
68
  def updated_dependencies_after_full_unlock
59
69
  raise NotImplementedError
60
70
  end
61
71
 
62
- def version_can_update?(*)
72
+ sig { params(requirements_to_unlock: T.nilable(Symbol)).returns(T::Boolean) }
73
+ def version_can_update?(requirements_to_unlock:) # rubocop:disable Lint/UnusedMethodArgument
63
74
  if digest_requirements.any?
64
75
  !digest_up_to_date?
65
76
  else
@@ -67,6 +78,7 @@ module Dependabot
67
78
  end
68
79
  end
69
80
 
81
+ sig { returns(T::Boolean) }
70
82
  def version_up_to_date?
71
83
  if digest_requirements.any?
72
84
  version_tag_up_to_date? && digest_up_to_date?
@@ -75,6 +87,7 @@ module Dependabot
75
87
  end
76
88
  end
77
89
 
90
+ sig { returns(T::Boolean) }
78
91
  def version_tag_up_to_date?
79
92
  version = dependency.version
80
93
  return false unless version
@@ -86,6 +99,7 @@ module Dependabot
86
99
  comparable_version_from(latest_tag) <= comparable_version_from(version_tag)
87
100
  end
88
101
 
102
+ sig { returns(T::Boolean) }
89
103
  def digest_up_to_date?
90
104
  digest_requirements.all? do |req|
91
105
  next true unless updated_digest
@@ -94,21 +108,24 @@ module Dependabot
94
108
  end
95
109
  end
96
110
 
111
+ sig { params(version: String).returns(String) }
97
112
  def latest_version_from(version)
98
113
  latest_tag_from(version).name
99
114
  end
100
115
 
116
+ sig { params(version: String).returns(Dependabot::Docker::Tag) }
101
117
  def latest_tag_from(version)
102
- @tags ||= {}
103
- return @tags[version] if @tags.key?(version)
118
+ @tags ||= T.let({}, T.nilable(T::Hash[String, Dependabot::Docker::Tag]))
119
+ return T.must(@tags[version]) if @tags.key?(version)
104
120
 
105
121
  @tags[version] = fetch_latest_tag(Tag.new(version))
106
122
  end
107
123
 
108
124
  # NOTE: It's important that this *always* returns a tag (even if
109
125
  # it's the existing one) as it is what we later check the digest of.
126
+ sig { params(version_tag: Dependabot::Docker::Tag).returns(Dependabot::Docker::Tag) }
110
127
  def fetch_latest_tag(version_tag)
111
- return Tag.new(latest_digest) if version_tag.digest? && latest_digest
128
+ return Tag.new(T.must(latest_digest)) if version_tag.digest? && latest_digest
112
129
  return version_tag unless version_tag.comparable?
113
130
 
114
131
  # Prune out any downgrade tags before checking for pre-releases
@@ -148,10 +165,18 @@ module Dependabot
148
165
  end
149
166
  end
150
167
 
168
+ sig { params(original_tag: Dependabot::Docker::Tag).returns(T::Array[Dependabot::Docker::Tag]) }
151
169
  def comparable_tags_from_registry(original_tag)
152
170
  tags_from_registry.select { |tag| tag.comparable_to?(original_tag) }
153
171
  end
154
172
 
173
+ sig do
174
+ params(
175
+ candidate_tags: T::Array[Dependabot::Docker::Tag],
176
+ version_tag: Dependabot::Docker::Tag
177
+ )
178
+ .returns(T::Array[Dependabot::Docker::Tag])
179
+ end
155
180
  def remove_version_downgrades(candidate_tags, version_tag)
156
181
  current_version = comparable_version_from(version_tag)
157
182
 
@@ -160,18 +185,33 @@ module Dependabot
160
185
  end
161
186
  end
162
187
 
188
+ sig do
189
+ params(
190
+ candidate_tags: T::Array[Dependabot::Docker::Tag],
191
+ version_tag: Dependabot::Docker::Tag
192
+ )
193
+ .returns(T::Array[Dependabot::Docker::Tag])
194
+ end
163
195
  def remove_prereleases(candidate_tags, version_tag)
164
196
  return candidate_tags if prerelease?(version_tag)
165
197
 
166
198
  candidate_tags.reject { |tag| prerelease?(tag) }
167
199
  end
168
200
 
201
+ sig do
202
+ params(
203
+ candidate_tags: T::Array[Dependabot::Docker::Tag],
204
+ version_tag: Dependabot::Docker::Tag
205
+ )
206
+ .returns(T::Array[Dependabot::Docker::Tag])
207
+ end
169
208
  def remove_precision_changes(candidate_tags, version_tag)
170
209
  candidate_tags.select do |tag|
171
210
  tag.same_precision?(version_tag)
172
211
  end
173
212
  end
174
213
 
214
+ sig { returns(T.nilable(Dependabot::Docker::Tag)) }
175
215
  def latest_tag
176
216
  return unless latest_digest
177
217
 
@@ -182,16 +222,21 @@ module Dependabot
182
222
  .find { |t| digest_of(t.name) == latest_digest }
183
223
  end
184
224
 
225
+ sig { returns(T.nilable(String)) }
185
226
  def updated_digest
186
- @updated_digest ||= if latest_tag_from(dependency.version).digest?
187
- latest_digest
188
- else
189
- digest_of(latest_version)
190
- end
227
+ @updated_digest ||= T.let(
228
+ if latest_tag_from(T.must(dependency.version)).digest?
229
+ latest_digest
230
+ else
231
+ digest_of(T.cast(latest_version, String))
232
+ end,
233
+ T.nilable(String)
234
+ )
191
235
  end
192
236
 
237
+ sig { returns(T::Array[Dependabot::Docker::Tag]) }
193
238
  def tags_from_registry
194
- @tags_from_registry ||=
239
+ @tags_from_registry ||= T.let(
195
240
  begin
196
241
  client = docker_registry_client
197
242
 
@@ -202,7 +247,9 @@ module Dependabot
202
247
  raise if attempt > 3
203
248
 
204
249
  retry
205
- end
250
+ end,
251
+ T.nilable(T::Array[Dependabot::Docker::Tag])
252
+ )
206
253
  rescue DockerRegistry2::RegistryAuthenticationException,
207
254
  RestClient::Forbidden
208
255
  raise PrivateSourceAuthenticationFailure, registry_hostname
@@ -210,25 +257,28 @@ module Dependabot
210
257
  RestClient::Exceptions::ReadTimeout
211
258
  raise if using_dockerhub?
212
259
 
213
- raise PrivateSourceTimedOut, registry_hostname
260
+ raise PrivateSourceTimedOut, T.must(registry_hostname)
214
261
  rescue RestClient::ServerBrokeConnection,
215
262
  RestClient::TooManyRequests
216
263
  raise PrivateSourceBadResponse, registry_hostname
217
264
  end
218
265
 
266
+ sig { returns(T.nilable(String)) }
219
267
  def latest_digest
220
268
  return unless tags_from_registry.map(&:name).include?("latest")
221
269
 
222
270
  digest_of("latest")
223
271
  end
224
272
 
273
+ sig { params(tag: String).returns(T.nilable(String)) }
225
274
  def digest_of(tag)
226
- @digests ||= {}
275
+ @digests ||= T.let({}, T.nilable(T::Hash[String, T.nilable(String)]))
227
276
  return @digests[tag] if @digests.key?(tag)
228
277
 
229
278
  @digests[tag] = fetch_digest_of(tag)
230
279
  end
231
280
 
281
+ sig { params(tag: String).returns(T.nilable(String)) }
232
282
  def fetch_digest_of(tag)
233
283
  docker_registry_client.manifest_digest(docker_repo_name, tag)&.delete_prefix("sha256:")
234
284
  rescue *transient_docker_errors => e
@@ -246,6 +296,7 @@ module Dependabot
246
296
  raise PrivateSourceBadResponse, registry_hostname
247
297
  end
248
298
 
299
+ sig { returns(T::Array[T.class_of(StandardError)]) }
249
300
  def transient_docker_errors
250
301
  [
251
302
  RestClient::Exceptions::Timeout,
@@ -257,15 +308,16 @@ module Dependabot
257
308
  ]
258
309
  end
259
310
 
311
+ sig { params(tag: Dependabot::Docker::Tag).returns(T::Boolean) }
260
312
  def prerelease?(tag)
261
313
  return true if tag.looks_like_prerelease?
262
314
 
263
315
  # Compare the numeric version against the version of the `latest` tag.
264
316
  return false unless latest_tag
265
317
 
266
- if comparable_version_from(tag) > comparable_version_from(latest_tag)
318
+ if comparable_version_from(tag) > comparable_version_from(T.must(latest_tag))
267
319
  Dependabot.logger.info \
268
- "The `latest` tag points to the same image as the `#{latest_tag.name}` image, " \
320
+ "The `latest` tag points to the same image as the `#{T.must(latest_tag).name}` image, " \
269
321
  "so dependabot is treating `#{tag.name}` as a pre-release. " \
270
322
  "The `latest` tag needs to point to `#{tag.name}` for Dependabot to consider it."
271
323
 
@@ -275,10 +327,12 @@ module Dependabot
275
327
  end
276
328
  end
277
329
 
330
+ sig { params(tag: Dependabot::Docker::Tag).returns(Dependabot::Version) }
278
331
  def comparable_version_from(tag)
279
332
  version_class.new(tag.numeric_version)
280
333
  end
281
334
 
335
+ sig { returns(T.nilable(String)) }
282
336
  def registry_hostname
283
337
  if dependency.requirements.first&.dig(:source, :registry)
284
338
  return T.must(dependency.requirements.first).dig(:source, :registry)
@@ -287,18 +341,25 @@ module Dependabot
287
341
  credentials_finder.base_registry
288
342
  end
289
343
 
344
+ sig { returns(T::Boolean) }
290
345
  def using_dockerhub?
291
346
  registry_hostname == "registry.hub.docker.com"
292
347
  end
293
348
 
349
+ sig { returns(T.nilable(Dependabot::Credential)) }
294
350
  def registry_credentials
295
351
  credentials_finder.credentials_for_registry(registry_hostname)
296
352
  end
297
353
 
354
+ sig { returns(Dependabot::Docker::Utils::CredentialsFinder) }
298
355
  def credentials_finder
299
- @credentials_finder ||= Utils::CredentialsFinder.new(credentials)
356
+ @credentials_finder ||= T.let(
357
+ Utils::CredentialsFinder.new(credentials),
358
+ T.nilable(Dependabot::Docker::Utils::CredentialsFinder)
359
+ )
300
360
  end
301
361
 
362
+ sig { returns(String) }
302
363
  def docker_repo_name
303
364
  return dependency.name unless using_dockerhub?
304
365
  return dependency.name unless dependency.name.split("/").count < 2
@@ -310,8 +371,9 @@ module Dependabot
310
371
  DEFAULT_DOCKER_OPEN_TIMEOUT_IN_SECONDS = 2
311
372
  DEFAULT_DOCKER_READ_TIMEOUT_IN_SECONDS = 5
312
373
 
374
+ sig { returns(DockerRegistry2::Registry) }
313
375
  def docker_registry_client
314
- @docker_registry_client ||=
376
+ @docker_registry_client ||= T.let(
315
377
  DockerRegistry2::Registry.new(
316
378
  "https://#{registry_hostname}",
317
379
  user: registry_credentials&.fetch("username", nil),
@@ -319,17 +381,28 @@ module Dependabot
319
381
  read_timeout: docker_read_timeout_in_seconds,
320
382
  open_timeout: docker_open_timeout_in_seconds,
321
383
  http_options: { proxy: ENV.fetch("HTTPS_PROXY", nil) }
322
- )
384
+ ),
385
+ T.nilable(DockerRegistry2::Registry)
386
+ )
323
387
  end
324
388
 
389
+ sig { returns(Integer) }
325
390
  def docker_open_timeout_in_seconds
326
391
  ENV.fetch("DEPENDABOT_DOCKER_OPEN_TIMEOUT_IN_SECONDS", DEFAULT_DOCKER_OPEN_TIMEOUT_IN_SECONDS).to_i
327
392
  end
328
393
 
394
+ sig { returns(Integer) }
329
395
  def docker_read_timeout_in_seconds
330
396
  ENV.fetch("DEPENDABOT_DOCKER_READ_TIMEOUT_IN_SECONDS", DEFAULT_DOCKER_READ_TIMEOUT_IN_SECONDS).to_i
331
397
  end
332
398
 
399
+ sig do
400
+ params(
401
+ candidate_tags: T::Array[Dependabot::Docker::Tag],
402
+ version_tag: Dependabot::Docker::Tag
403
+ )
404
+ .returns(T::Array[Dependabot::Docker::Tag])
405
+ end
333
406
  def sort_tags(candidate_tags, version_tag)
334
407
  candidate_tags.sort do |tag_a, tag_b|
335
408
  if comparable_version_from(tag_a) > comparable_version_from(tag_b)
@@ -346,6 +419,7 @@ module Dependabot
346
419
  end
347
420
  end
348
421
 
422
+ sig { params(candidate_tags: T::Array[Dependabot::Docker::Tag]).returns(T::Array[Dependabot::Docker::Tag]) }
349
423
  def filter_ignored(candidate_tags)
350
424
  filtered =
351
425
  candidate_tags
@@ -363,22 +437,29 @@ module Dependabot
363
437
  filtered
364
438
  end
365
439
 
440
+ sig { params(tags: T::Array[Dependabot::Docker::Tag]).returns(T::Array[Dependabot::Docker::Tag]) }
366
441
  def filter_lower_versions(tags)
367
442
  tags.select do |tag|
368
443
  comparable_version_from(tag) > comparable_version_from(version_tag)
369
444
  end
370
445
  end
371
446
 
447
+ sig { returns(T::Array[T::Hash[Symbol, T.untyped]]) }
372
448
  def digest_requirements
373
449
  dependency.requirements.select do |requirement|
374
450
  requirement.dig(:source, :digest)
375
451
  end
376
452
  end
377
453
 
454
+ sig { returns(Dependabot::Docker::Tag) }
378
455
  def version_tag
379
- @version_tag ||= Tag.new(T.must(dependency.version))
456
+ @version_tag ||= T.let(
457
+ Tag.new(T.must(dependency.version)),
458
+ T.nilable(Dependabot::Docker::Tag)
459
+ )
380
460
  end
381
461
  end
462
+ # rubocop:enable Metrics/ClassLength
382
463
  end
383
464
  end
384
465
 
@@ -22,14 +22,14 @@ module Dependabot
22
22
  @credentials = credentials
23
23
  end
24
24
 
25
- sig { params(registry_hostname: String).returns(T.nilable(Dependabot::Credential)) }
25
+ sig { params(registry_hostname: T.nilable(String)).returns(T.nilable(Dependabot::Credential)) }
26
26
  def credentials_for_registry(registry_hostname)
27
27
  registry_details =
28
28
  credentials
29
29
  .select { |cred| cred["type"] == "docker_registry" }
30
30
  .find { |cred| cred.fetch("registry") == registry_hostname }
31
31
  return unless registry_details
32
- return registry_details unless registry_hostname.match?(AWS_ECR_URL)
32
+ return registry_details unless registry_hostname&.match?(AWS_ECR_URL)
33
33
 
34
34
  build_aws_credentials(registry_details)
35
35
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dependabot-docker
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.296.0
4
+ version: 0.296.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dependabot
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-02-06 00:00:00.000000000 Z
11
+ date: 2025-02-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dependabot-common
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 0.296.0
19
+ version: 0.296.1
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.296.0
26
+ version: 0.296.1
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: debug
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -259,7 +259,7 @@ licenses:
259
259
  - MIT
260
260
  metadata:
261
261
  bug_tracker_uri: https://github.com/dependabot/dependabot-core/issues
262
- changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.296.0
262
+ changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.296.1
263
263
  post_install_message:
264
264
  rdoc_options: []
265
265
  require_paths: