dependabot-docker 0.395.0 → 0.397.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:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b43ff0be6b23394fc47285dce19edb7b8e90bcc6a859243315758559dbd5fac4
|
|
4
|
+
data.tar.gz: 0b12ca42143a2d08547b575d4b4373ce4cf0490f22fc41f8c2fb2ff4a944ef4f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 338d342f4d99ee355295af0581139e6a121c580bcc636d54cd8bde653b4169b569e80b5371ab1b0bd321e421df07fb13f4275eea8e4aebe2384a55afc014e18d
|
|
7
|
+
data.tar.gz: a7feda400c5b1fc35e0ac60b36d37c7bfa57295416ff1e230fe656311700573b4fae9d0ac0097702e8325d94a2f245ba56f668ddca145c2df3f63c8f49ef8bee
|
|
@@ -145,7 +145,11 @@ module Dependabot
|
|
|
145
145
|
repo = img_hash.fetch("repository", nil)
|
|
146
146
|
return [] unless repo.is_a?(String)
|
|
147
147
|
|
|
148
|
-
|
|
148
|
+
tag = tag_value.to_s
|
|
149
|
+
# Helm template expressions cannot be resolved without rendering the chart.
|
|
150
|
+
return [] if tag.include?("{{")
|
|
151
|
+
|
|
152
|
+
match = tag.match(TAG_WITH_DIGEST)
|
|
149
153
|
return [] unless match
|
|
150
154
|
|
|
151
155
|
tag_details = match.named_captures
|
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
require "sorbet-runtime"
|
|
5
5
|
require "dependabot/file_fetchers"
|
|
6
6
|
require "dependabot/file_fetchers/base"
|
|
7
|
-
require "dependabot/notices"
|
|
8
7
|
require "dependabot/shared/shared_file_updater"
|
|
9
8
|
|
|
10
9
|
module Dependabot
|
|
@@ -29,21 +28,6 @@ module Dependabot
|
|
|
29
28
|
def container_image_regex
|
|
30
29
|
%r{^#{FROM_REGEX}\s+(docker\.io/)?}o
|
|
31
30
|
end
|
|
32
|
-
|
|
33
|
-
sig { override.returns(T::Array[Dependabot::Notice]) }
|
|
34
|
-
def notices
|
|
35
|
-
return [] unless dependencies.any? { |dependency| dependency.metadata[:docker_cooldown_date_unavailable] }
|
|
36
|
-
|
|
37
|
-
[Dependabot::Notice.new(
|
|
38
|
-
mode: Dependabot::Notice::NoticeMode::WARN,
|
|
39
|
-
type: "docker_cooldown_date_unavailable",
|
|
40
|
-
package_manager_name: "docker",
|
|
41
|
-
title: "Docker cooldown was not applied",
|
|
42
|
-
description: "Cooldown could not be applied because no publication date was available from the registry.",
|
|
43
|
-
show_in_pr: true,
|
|
44
|
-
show_alert: false
|
|
45
|
-
)]
|
|
46
|
-
end
|
|
47
31
|
end
|
|
48
32
|
end
|
|
49
33
|
end
|
|
@@ -2,7 +2,10 @@
|
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
4
|
require "docker_registry2"
|
|
5
|
+
require "excon"
|
|
6
|
+
require "json"
|
|
5
7
|
require "sorbet-runtime"
|
|
8
|
+
require "uri"
|
|
6
9
|
|
|
7
10
|
begin
|
|
8
11
|
require "rest-client"
|
|
@@ -36,6 +39,7 @@ end
|
|
|
36
39
|
require "dependabot/update_checkers"
|
|
37
40
|
require "dependabot/update_checkers/base"
|
|
38
41
|
require "dependabot/update_checkers/cooldown_calculation"
|
|
42
|
+
require "dependabot/registry_client"
|
|
39
43
|
require "dependabot/errors"
|
|
40
44
|
require "dependabot/docker/tag"
|
|
41
45
|
require "dependabot/docker/file_parser"
|
|
@@ -444,7 +448,10 @@ module Dependabot
|
|
|
444
448
|
# If we can't determine publication details, skip cooldown for this tag and use it
|
|
445
449
|
# rather than blocking the update when the registry doesn't support the required API calls
|
|
446
450
|
if !details || !details.released_at
|
|
447
|
-
mark_cooldown_date_unavailable
|
|
451
|
+
Dependabot::UpdateCheckers::CooldownCalculation.mark_cooldown_date_unavailable(
|
|
452
|
+
dependency,
|
|
453
|
+
cooldown_days: cooldown_days_for(tag)
|
|
454
|
+
)
|
|
448
455
|
return [tag]
|
|
449
456
|
end
|
|
450
457
|
|
|
@@ -468,25 +475,8 @@ module Dependabot
|
|
|
468
475
|
|
|
469
476
|
sig { params(tag: Dependabot::Docker::Tag).returns(T.nilable(Dependabot::Package::PackageRelease)) }
|
|
470
477
|
def get_tag_publication_details(tag)
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
client.digest(docker_repo_name, tag.name)
|
|
474
|
-
end
|
|
475
|
-
|
|
476
|
-
first_digest = extract_digest_from_response(digest_info, tag)
|
|
477
|
-
return nil unless first_digest
|
|
478
|
-
|
|
479
|
-
# When digest_info is an Array the registry returned a manifest list
|
|
480
|
-
# (OCI image index) and the extracted digest points at a platform-
|
|
481
|
-
# specific *manifest*, not a blob. Use the correct endpoint so the
|
|
482
|
-
# HEAD request succeeds on registries like ghcr.io.
|
|
483
|
-
endpoint = digest_info.is_a?(Array) ? "manifests" : "blobs"
|
|
484
|
-
head_response = with_retries(max_attempts: 3, errors: transient_docker_errors) do
|
|
485
|
-
client = docker_registry_client
|
|
486
|
-
client.dohead "v2/#{docker_repo_name}/#{endpoint}/#{first_digest}"
|
|
487
|
-
end
|
|
488
|
-
|
|
489
|
-
published_date = published_date_from_response_headers(head_response.headers, tag.name)
|
|
478
|
+
published_date = registry_tag_release_date(tag)
|
|
479
|
+
return nil unless published_date
|
|
490
480
|
|
|
491
481
|
Dependabot::Package::PackageRelease.new(
|
|
492
482
|
version: release_version_for(tag),
|
|
@@ -496,58 +486,75 @@ module Dependabot
|
|
|
496
486
|
url: nil,
|
|
497
487
|
package_type: "docker"
|
|
498
488
|
)
|
|
499
|
-
|
|
489
|
+
end
|
|
490
|
+
|
|
491
|
+
sig { params(tag: Dependabot::Docker::Tag).returns(T.nilable(Time)) }
|
|
492
|
+
def registry_tag_release_date(tag)
|
|
493
|
+
return docker_hub_tag_release_date(tag) if using_dockerhub?
|
|
494
|
+
|
|
495
|
+
Dependabot.logger.info(
|
|
496
|
+
"No verified registry publication date source for #{registry_hostname}; " \
|
|
497
|
+
"skipping cooldown for #{docker_repo_name}:#{tag.name}"
|
|
498
|
+
)
|
|
499
|
+
nil
|
|
500
|
+
rescue JSON::ParserError, ArgumentError, TypeError, Excon::Error::Socket, Excon::Error::Timeout,
|
|
501
|
+
RegistryError, PrivateSourceBadResponse, PrivateSourceAuthenticationFailure,
|
|
502
|
+
*transient_docker_errors,
|
|
500
503
|
DockerRegistry2::RegistryAuthenticationException,
|
|
501
504
|
DockerRegistry2::RegistryAuthorizationException,
|
|
502
505
|
RestClient::Forbidden,
|
|
503
506
|
RestClient::TooManyRequests => e
|
|
504
|
-
Dependabot.logger.
|
|
505
|
-
"Failed to fetch
|
|
506
|
-
"skipping cooldown: #{e.class} - #{e.message}"
|
|
507
|
+
Dependabot.logger.info(
|
|
508
|
+
"Failed to fetch registry tag metadata for #{docker_repo_name}:#{tag.name}: #{e.message}"
|
|
507
509
|
)
|
|
508
510
|
nil
|
|
509
511
|
end
|
|
510
512
|
|
|
511
|
-
sig { params(
|
|
512
|
-
def
|
|
513
|
-
|
|
514
|
-
return
|
|
513
|
+
sig { params(tag: Dependabot::Docker::Tag).returns(T.nilable(Time)) }
|
|
514
|
+
def docker_hub_tag_release_date(tag)
|
|
515
|
+
namespace, repository = docker_repo_name.split("/", 2)
|
|
516
|
+
return unless namespace && repository
|
|
515
517
|
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
518
|
+
digest = digest_of(tag.name)
|
|
519
|
+
return unless digest
|
|
520
|
+
|
|
521
|
+
response = Dependabot::RegistryClient.get(
|
|
522
|
+
url: docker_hub_tag_url(namespace, repository, tag.name),
|
|
523
|
+
headers: { "Accept" => "application/json" },
|
|
524
|
+
options: {
|
|
525
|
+
connect_timeout: docker_open_timeout_in_seconds,
|
|
526
|
+
read_timeout: docker_read_timeout_in_seconds,
|
|
527
|
+
write_timeout: docker_read_timeout_in_seconds
|
|
528
|
+
}
|
|
520
529
|
)
|
|
521
|
-
|
|
530
|
+
return unless response.status == 200
|
|
531
|
+
|
|
532
|
+
metadata = JSON.parse(response.body)
|
|
533
|
+
return unless metadata.is_a?(Hash)
|
|
534
|
+
return unless docker_hub_digest_matches_update?(metadata["digest"], digest)
|
|
535
|
+
|
|
536
|
+
timestamp = metadata["tag_last_pushed"]
|
|
537
|
+
Time.iso8601(timestamp) if timestamp.is_a?(String)
|
|
522
538
|
end
|
|
523
539
|
|
|
524
|
-
sig
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
540
|
+
sig { params(metadata_digest: Object, digest: String).returns(T::Boolean) }
|
|
541
|
+
def docker_hub_digest_matches_update?(metadata_digest, digest)
|
|
542
|
+
return digest_requirements.empty? && !pin_digests? if metadata_digest.nil?
|
|
543
|
+
|
|
544
|
+
matching_digest?(metadata_digest, digest)
|
|
529
545
|
end
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
when String
|
|
543
|
-
digest_info
|
|
544
|
-
else
|
|
545
|
-
Dependabot.logger.warn(
|
|
546
|
-
"Unexpected digest_info type for #{docker_repo_name}:#{tag.name}: " \
|
|
547
|
-
"#{digest_info.class} (expected String or Array)"
|
|
548
|
-
)
|
|
549
|
-
nil
|
|
550
|
-
end
|
|
546
|
+
|
|
547
|
+
sig { params(namespace: String, repository: String, tag: String).returns(String) }
|
|
548
|
+
def docker_hub_tag_url(namespace, repository, tag)
|
|
549
|
+
escaped = [namespace, repository, tag].map { |value| URI.encode_www_form_component(value) }
|
|
550
|
+
"https://hub.docker.com/v2/namespaces/#{escaped[0]}/repositories/#{escaped[1]}/tags/#{escaped[2]}"
|
|
551
|
+
end
|
|
552
|
+
|
|
553
|
+
sig { params(first: Object, second: Object).returns(T::Boolean) }
|
|
554
|
+
def matching_digest?(first, second)
|
|
555
|
+
return false unless first.is_a?(String) && second.is_a?(String)
|
|
556
|
+
|
|
557
|
+
first.delete_prefix("sha256:").casecmp?(second.delete_prefix("sha256:")) || false
|
|
551
558
|
end
|
|
552
559
|
|
|
553
560
|
sig do
|
|
@@ -1068,11 +1075,6 @@ module Dependabot
|
|
|
1068
1075
|
)
|
|
1069
1076
|
end
|
|
1070
1077
|
|
|
1071
|
-
sig { void }
|
|
1072
|
-
def mark_cooldown_date_unavailable
|
|
1073
|
-
dependency.metadata[:docker_cooldown_date_unavailable] = true
|
|
1074
|
-
end
|
|
1075
|
-
|
|
1076
1078
|
# Builds the PackageRelease version for a tag. Non-comparable tags (e.g.
|
|
1077
1079
|
# "alpine") have no semver, so Docker::Version.new would raise. The version
|
|
1078
1080
|
# is only consumed by semver-aware version-tag cooldown; the digest cooldown
|
|
@@ -1090,8 +1092,7 @@ module Dependabot
|
|
|
1090
1092
|
# don't change the version string, so the default cooldown window applies
|
|
1091
1093
|
# (semver-specific windows require a version delta, and the tag may be
|
|
1092
1094
|
# non-comparable like "alpine"). Fails open (returns false) when the
|
|
1093
|
-
# publication date can't be determined
|
|
1094
|
-
# never permanently blocks an update.
|
|
1095
|
+
# publication date can't be determined and records an unavailable-date warning.
|
|
1095
1096
|
sig { params(tag_name: String).returns(T::Boolean) }
|
|
1096
1097
|
def digest_within_cooldown?(tag_name)
|
|
1097
1098
|
return false if should_skip_cooldown?
|
|
@@ -1101,7 +1102,10 @@ module Dependabot
|
|
|
1101
1102
|
|
|
1102
1103
|
released_at = publication_detail(Tag.new(tag_name))&.released_at
|
|
1103
1104
|
unless released_at
|
|
1104
|
-
mark_cooldown_date_unavailable
|
|
1105
|
+
Dependabot::UpdateCheckers::CooldownCalculation.mark_cooldown_date_unavailable(
|
|
1106
|
+
dependency,
|
|
1107
|
+
cooldown_days: cooldown.default_days
|
|
1108
|
+
)
|
|
1105
1109
|
return false
|
|
1106
1110
|
end
|
|
1107
1111
|
|
|
@@ -154,11 +154,12 @@ module Dependabot
|
|
|
154
154
|
return if old_tags.empty?
|
|
155
155
|
|
|
156
156
|
modified_content = content
|
|
157
|
+
replacement = new_helm_tag(file)
|
|
157
158
|
|
|
158
159
|
old_tags.each do |old_tag|
|
|
159
|
-
old_tag_regex = /^\s*(?:-\s)?(?:tag|version):\s+["']?#{old_tag}["']?(?=\s|$)/
|
|
160
|
+
old_tag_regex = /^\s*(?:-\s)?(?:tag|version):\s+["']?#{Regexp.escape(old_tag)}["']?(?=\s|$)/
|
|
160
161
|
modified_content = modified_content&.gsub(old_tag_regex) do |old_img_tag|
|
|
161
|
-
old_img_tag.gsub(old_tag.to_s,
|
|
162
|
+
old_img_tag.gsub(old_tag.to_s, replacement.to_s)
|
|
162
163
|
end
|
|
163
164
|
end
|
|
164
165
|
modified_content
|
|
@@ -170,11 +171,12 @@ module Dependabot
|
|
|
170
171
|
return if old_images.empty?
|
|
171
172
|
|
|
172
173
|
modified_content = content
|
|
174
|
+
replacement = new_yaml_image(file)
|
|
173
175
|
|
|
174
176
|
old_images.each do |old_image|
|
|
175
|
-
old_image_regex =
|
|
177
|
+
old_image_regex = %r{^\s*(?:-\s)?image:\s+(?:docker\.io/)?#{Regexp.escape(old_image)}(?=\s|$)}
|
|
176
178
|
modified_content = modified_content&.gsub(old_image_regex) do |old_img|
|
|
177
|
-
old_img.gsub(old_image.to_s,
|
|
179
|
+
old_img.gsub(old_image.to_s, replacement.to_s)
|
|
178
180
|
end
|
|
179
181
|
end
|
|
180
182
|
modified_content
|
|
@@ -182,7 +184,7 @@ module Dependabot
|
|
|
182
184
|
|
|
183
185
|
sig { params(file: Dependabot::DependencyFile).returns(String) }
|
|
184
186
|
def new_yaml_image(file)
|
|
185
|
-
element =
|
|
187
|
+
element = requirement_for_file(file)
|
|
186
188
|
source = image_source(element)
|
|
187
189
|
prefix = source[:registry] ? "#{source[:registry]}/" : ""
|
|
188
190
|
digest = source[:digest] ? "@sha256:#{source[:digest]}" : ""
|
|
@@ -198,7 +200,7 @@ module Dependabot
|
|
|
198
200
|
digest = source[:digest] ? "@sha256:#{source[:digest]}" : ""
|
|
199
201
|
tag = source[:tag] ? ":#{source[:tag]}" : ""
|
|
200
202
|
"#{prefix}#{T.must(dependency).name}#{tag}#{digest}"
|
|
201
|
-
end
|
|
203
|
+
end.uniq
|
|
202
204
|
end
|
|
203
205
|
|
|
204
206
|
sig { params(file: Dependabot::DependencyFile).returns(T::Array[String]) }
|
|
@@ -208,18 +210,23 @@ module Dependabot
|
|
|
208
210
|
tag = source[:tag] || ""
|
|
209
211
|
digest = source[:digest] ? "@sha256:#{source[:digest]}" : ""
|
|
210
212
|
"#{tag}#{digest}"
|
|
211
|
-
end
|
|
213
|
+
end.uniq
|
|
212
214
|
end
|
|
213
215
|
|
|
214
216
|
sig { params(file: Dependabot::DependencyFile).returns(String) }
|
|
215
217
|
def new_helm_tag(file)
|
|
216
|
-
element =
|
|
218
|
+
element = requirement_for_file(file)
|
|
217
219
|
source = image_source(element)
|
|
218
220
|
tag = source[:tag] || ""
|
|
219
221
|
digest = source[:digest] ? "@sha256:#{source[:digest]}" : ""
|
|
220
222
|
"#{tag}#{digest}"
|
|
221
223
|
end
|
|
222
224
|
|
|
225
|
+
sig { params(file: Dependabot::DependencyFile).returns(T.nilable(Dependabot::DependencyRequirement)) }
|
|
226
|
+
def requirement_for_file(file)
|
|
227
|
+
requirements(file).first
|
|
228
|
+
end
|
|
229
|
+
|
|
223
230
|
protected
|
|
224
231
|
|
|
225
232
|
sig { params(file: Dependabot::DependencyFile, dependency: Dependabot::Dependency).returns(T::Boolean) }
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: dependabot-docker
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.397.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.397.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.397.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.
|
|
269
|
+
changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.397.0
|
|
270
270
|
rdoc_options: []
|
|
271
271
|
require_paths:
|
|
272
272
|
- lib
|