dependabot-docker 0.382.0 → 0.383.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 +4 -4
- data/lib/dependabot/docker/update_checker.rb +117 -2
- metadata +4 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: '0200408166a023ea4720b018f90dda3232304f7b5f1abec28dd8dbb9bf2b3f0e'
|
|
4
|
+
data.tar.gz: 99f2b3c7a81588a396ca4fc38b1cb9ce9d5907f455122f7b3285fc84c92afe51
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b4eb568dd7249d487a42415564920512f63d953049334e64ec09171435385b48365e0934c8d392b8d7033d743f33b887fb4de1548e1c25db65e355cd2e9cf798
|
|
7
|
+
data.tar.gz: 517a96c97e6b74ed9873be9d49cbdf0913204f2111f4191c18a22a9c6c9e37c9665760a70662f84e4c87b65607b710414d871109fd72dc68d64f58f0f56795ea
|
|
@@ -263,6 +263,7 @@ module Dependabot
|
|
|
263
263
|
# (which requires a call to the registry for each tag, so can be slow)
|
|
264
264
|
candidate_tags = comparable_tags_from_registry(version_tag)
|
|
265
265
|
candidate_tags = remove_version_downgrades(candidate_tags, version_tag)
|
|
266
|
+
candidate_tags = remove_more_precise_tags(candidate_tags, version_tag)
|
|
266
267
|
candidate_tags = remove_prereleases(candidate_tags, version_tag)
|
|
267
268
|
candidate_tags = filter_ignored(candidate_tags)
|
|
268
269
|
candidate_tags = sort_tags(candidate_tags, version_tag)
|
|
@@ -285,14 +286,26 @@ module Dependabot
|
|
|
285
286
|
candidate_tags.reverse_each do |candidate|
|
|
286
287
|
selected = select_tag_with_precision(candidate, same_precision_tags, version_tag)
|
|
287
288
|
|
|
289
|
+
# Content check (runs regardless of experiments): if the candidate tag
|
|
290
|
+
# resolves to the exact same image contents as the current tag, there
|
|
291
|
+
# is no real update to make. This catches rolling tags (e.g. "9.0")
|
|
292
|
+
# that point to the same image as a pinned tag (e.g. "9.0.11").
|
|
293
|
+
if selected.name != version_tag.name && same_image_contents?(selected, version_tag)
|
|
294
|
+
Dependabot.logger.info(
|
|
295
|
+
"Digest check: #{selected.name} has the same image contents as #{version_tag.name} " \
|
|
296
|
+
"— no update needed, staying on #{version_tag.name}"
|
|
297
|
+
)
|
|
298
|
+
next
|
|
299
|
+
end
|
|
300
|
+
|
|
288
301
|
if Dependabot::Experiments.enabled?(:docker_created_timestamp_validation) &&
|
|
289
302
|
selected.name != version_tag.name
|
|
290
303
|
if validation_attempts >= MAX_PLATFORM_VALIDATION_ATTEMPTS
|
|
291
304
|
Dependabot.logger.info(
|
|
292
305
|
"Platform validation: reached max attempts (#{MAX_PLATFORM_VALIDATION_ATTEMPTS}), " \
|
|
293
|
-
"
|
|
306
|
+
"skipping #{selected.name} — continuing to find a validated candidate"
|
|
294
307
|
)
|
|
295
|
-
|
|
308
|
+
next
|
|
296
309
|
end
|
|
297
310
|
validation_attempts += 1
|
|
298
311
|
end
|
|
@@ -562,6 +575,26 @@ module Dependabot
|
|
|
562
575
|
end
|
|
563
576
|
end
|
|
564
577
|
|
|
578
|
+
# When the current tag pins only the major or major.minor version (e.g.
|
|
579
|
+
# "9.0"), a candidate that additionally specifies a patch version (e.g.
|
|
580
|
+
# "9.0.17") is not a wanted upgrade: pinning the less precise tag opts into
|
|
581
|
+
# a rolling tag, so the patch should not be specified for them. Only true
|
|
582
|
+
# semver tags (":normal" format) are filtered here — build-number and date
|
|
583
|
+
# based formats have their own comparability rules and are left untouched.
|
|
584
|
+
sig do
|
|
585
|
+
params(
|
|
586
|
+
candidate_tags: T::Array[Dependabot::Docker::Tag],
|
|
587
|
+
version_tag: Dependabot::Docker::Tag
|
|
588
|
+
)
|
|
589
|
+
.returns(T::Array[Dependabot::Docker::Tag])
|
|
590
|
+
end
|
|
591
|
+
def remove_more_precise_tags(candidate_tags, version_tag)
|
|
592
|
+
return candidate_tags unless version_tag.format == :normal
|
|
593
|
+
return candidate_tags if version_tag.precision > 2
|
|
594
|
+
|
|
595
|
+
candidate_tags.select { |tag| tag.precision <= version_tag.precision }
|
|
596
|
+
end
|
|
597
|
+
|
|
565
598
|
sig do
|
|
566
599
|
params(
|
|
567
600
|
candidate_tags: T::Array[Dependabot::Docker::Tag],
|
|
@@ -1083,6 +1116,80 @@ module Dependabot
|
|
|
1083
1116
|
candidate_created > current_created
|
|
1084
1117
|
end
|
|
1085
1118
|
|
|
1119
|
+
# Returns true when the candidate tag and current tag reference the exact
|
|
1120
|
+
# same image contents. Only multi-arch (manifest list) images are compared
|
|
1121
|
+
# here, by checking that both tags expose the identical set of platforms
|
|
1122
|
+
# with matching per-platform manifest digests. For single-platform images this
|
|
1123
|
+
# returns false (empty digest map), so this check is effectively a no-op and
|
|
1124
|
+
# we fall back to the existing semver/precision selection logic.
|
|
1125
|
+
sig do
|
|
1126
|
+
params(
|
|
1127
|
+
candidate_tag: Dependabot::Docker::Tag,
|
|
1128
|
+
current_tag: Dependabot::Docker::Tag
|
|
1129
|
+
).returns(T::Boolean)
|
|
1130
|
+
end
|
|
1131
|
+
def same_image_contents?(candidate_tag, current_tag)
|
|
1132
|
+
current_digests = fetch_platform_digests(current_tag.name)
|
|
1133
|
+
return false if current_digests.empty?
|
|
1134
|
+
|
|
1135
|
+
candidate_digests = fetch_platform_digests(candidate_tag.name)
|
|
1136
|
+
return false if candidate_digests.empty?
|
|
1137
|
+
|
|
1138
|
+
# The contents are unchanged only when both tags expose the exact same set
|
|
1139
|
+
# of platforms with identical per-platform manifest digests. A candidate
|
|
1140
|
+
# with extra platforms is a different image and must not match.
|
|
1141
|
+
current_digests == candidate_digests
|
|
1142
|
+
end
|
|
1143
|
+
|
|
1144
|
+
# Fetches a map of platform key (e.g. "linux/amd64") to platform manifest
|
|
1145
|
+
# digest for a tag's manifest list. Returns an empty hash for single-platform
|
|
1146
|
+
# images or when the manifest can't be fetched.
|
|
1147
|
+
sig { params(tag_name: String).returns(T::Hash[String, String]) }
|
|
1148
|
+
def fetch_platform_digests(tag_name)
|
|
1149
|
+
return T.must(platform_digests_cache[tag_name]) if platform_digests_cache.key?(tag_name)
|
|
1150
|
+
|
|
1151
|
+
digests = fetch_platform_digests_from_registry(tag_name)
|
|
1152
|
+
platform_digests_cache[tag_name] = digests
|
|
1153
|
+
digests
|
|
1154
|
+
rescue *transient_docker_errors, DockerRegistry2::RegistryAuthenticationException,
|
|
1155
|
+
RestClient::Forbidden, RestClient::TooManyRequests, JSON::ParserError => e
|
|
1156
|
+
Dependabot.logger.info(
|
|
1157
|
+
"Failed to fetch platform digests for #{docker_repo_name}:#{tag_name}: #{e.message}"
|
|
1158
|
+
)
|
|
1159
|
+
platform_digests_cache[tag_name] = {}
|
|
1160
|
+
{}
|
|
1161
|
+
end
|
|
1162
|
+
|
|
1163
|
+
sig { params(tag_name: String).returns(T::Hash[String, String]) }
|
|
1164
|
+
def fetch_platform_digests_from_registry(tag_name)
|
|
1165
|
+
manifest = with_retries(max_attempts: 3, errors: transient_docker_errors) do
|
|
1166
|
+
docker_registry_client.manifest(docker_repo_name, tag_name)
|
|
1167
|
+
end
|
|
1168
|
+
|
|
1169
|
+
media_type = manifest["mediaType"] || manifest[:mediaType]
|
|
1170
|
+
return {} unless MANIFEST_LIST_TYPES.include?(media_type)
|
|
1171
|
+
|
|
1172
|
+
manifests = manifest["manifests"] || manifest[:manifests] || []
|
|
1173
|
+
collect_platform_digests(manifests)
|
|
1174
|
+
end
|
|
1175
|
+
|
|
1176
|
+
sig { params(manifests: T.untyped).returns(T::Hash[String, String]) }
|
|
1177
|
+
def collect_platform_digests(manifests)
|
|
1178
|
+
digests = {}
|
|
1179
|
+
|
|
1180
|
+
manifests.each do |m|
|
|
1181
|
+
platform = extract_platform(m)
|
|
1182
|
+
next unless platform
|
|
1183
|
+
|
|
1184
|
+
digest = m["digest"] || m[:digest]
|
|
1185
|
+
next unless digest
|
|
1186
|
+
|
|
1187
|
+
digests[platform_key(platform)] = digest
|
|
1188
|
+
end
|
|
1189
|
+
|
|
1190
|
+
digests
|
|
1191
|
+
end
|
|
1192
|
+
|
|
1086
1193
|
# Fetches the platform entries from a manifest list for a given tag.
|
|
1087
1194
|
# Returns nil if the tag is a single-platform image (not a manifest list).
|
|
1088
1195
|
sig { params(tag_name: String).returns(T.nilable(T::Array[T::Hash[String, T.untyped]])) }
|
|
@@ -1218,6 +1325,14 @@ module Dependabot
|
|
|
1218
1325
|
)
|
|
1219
1326
|
end
|
|
1220
1327
|
|
|
1328
|
+
sig { returns(T::Hash[String, T::Hash[String, String]]) }
|
|
1329
|
+
def platform_digests_cache
|
|
1330
|
+
@platform_digests_cache ||= T.let(
|
|
1331
|
+
{},
|
|
1332
|
+
T.nilable(T::Hash[String, T::Hash[String, String]])
|
|
1333
|
+
)
|
|
1334
|
+
end
|
|
1335
|
+
|
|
1221
1336
|
sig { returns(T::Hash[String, T.nilable(Time)]) }
|
|
1222
1337
|
def config_created_timestamps
|
|
1223
1338
|
@config_created_timestamps ||= T.let(
|
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.383.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.383.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.383.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.383.0
|
|
270
270
|
rdoc_options: []
|
|
271
271
|
require_paths:
|
|
272
272
|
- lib
|