dependabot-helm 0.322.2 → 0.324.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: fa837c0ba9d1b227e77e6de8b3b738babcc089edb234eae5473366277332e005
4
- data.tar.gz: 06d2472204b07e77dac65d3991092b24c6d61bd6f36e7e3e71ca5a53624aa8cc
3
+ metadata.gz: 11b62eb89bfbc88ac56c0d84035e9c9902d5a66cb1a08a3b977acb3f020e58e2
4
+ data.tar.gz: 16e970e8fd14f1563898e9ade684a155820287ffe37e3e069ee95c768205f26b
5
5
  SHA512:
6
- metadata.gz: 666de487845c099b49e2440bb6fdc8638624284c66456ece1e171a1dae91fb8a7961b816e3763874ae2c91418066e234fc8f8419b863af64ab1feb3a9c6de360
7
- data.tar.gz: 8ffadf8d3dc7c2d33f7047cc9afd43b50dbe5f33507fd33364223ca393f2675546d37ba2f0c5a5a111e539c74600639f7625ea03dfc6f5f9632f2b101ebbfc93
6
+ metadata.gz: 3c3ae34930911f438748c4a0b687246978fd5409e5d35dcc2d3238c2062395b3efdd23dbc7d0cd91f46f391654f7c7f75998f089925578f4c0ee453f0d93b226
7
+ data.tar.gz: 1e41b94ab1cc9272fbe025601dddc66fbc35e575bfe6dc6775cacab1bac737c834d1a39d1e9462d8267308339a82153faecf7cae4880f8ad76d0975213ae6ffd
@@ -52,36 +52,6 @@ module Dependabot
52
52
  )
53
53
  end
54
54
 
55
- sig { params(username: String, password: String, repository_url: String).returns(String) }
56
- def self.registry_login(username, password, repository_url)
57
- Dependabot.logger.info("Logging into Helm registry \"#{repository_url}\"")
58
-
59
- Dependabot::SharedHelpers.run_shell_command(
60
- "helm registry login --username #{username} --password #{password} #{repository_url}",
61
- fingerprint: "helm registry login --username <username> --password <password> <repository_url>"
62
- )
63
- rescue StandardError => e
64
- Dependabot.logger.error(
65
- "Failed to authenticate for #{repository_url}: #{e.message}"
66
- )
67
- raise
68
- end
69
-
70
- sig { params(username: String, password: String, repository_url: String).returns(String) }
71
- def self.oci_registry_login(username, password, repository_url)
72
- Dependabot.logger.info("Logging into OCI registry \"#{repository_url}\"")
73
-
74
- Dependabot::SharedHelpers.run_shell_command(
75
- "oras login --username #{username} --password #{password} #{repository_url}",
76
- fingerprint: "oras login --username <username> --password <password> <repository_url>"
77
- )
78
- rescue StandardError => e
79
- Dependabot.logger.error(
80
- "Failed to authenticate for #{repository_url}: #{e.message}"
81
- )
82
- raise
83
- end
84
-
85
55
  sig { params(name: String).returns(String) }
86
56
  def self.fetch_oci_tags(name)
87
57
  Dependabot.logger.info("Searching OCI tags for: #{name}")
@@ -91,6 +61,14 @@ module Dependabot
91
61
  fingerprint: "oras repo tags <name>"
92
62
  ).strip
93
63
  end
64
+
65
+ sig { params(repo_url: String, tag: String).returns(String) }
66
+ def self.fetch_tags_with_release_date_using_oci(repo_url, tag)
67
+ Dependabot::SharedHelpers.run_shell_command(
68
+ "oras manifest fetch #{repo_url}:#{tag}",
69
+ fingerprint: "oras manifest fetch <repo_url>:<tag>"
70
+ ).strip
71
+ end
94
72
  end
95
73
  end
96
74
  end
@@ -0,0 +1,109 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ require "json"
5
+ require "time"
6
+ require "cgi"
7
+ require "excon"
8
+ require "sorbet-runtime"
9
+ require "dependabot/helm"
10
+ require "dependabot/helm/helpers"
11
+
12
+ module Dependabot
13
+ module Helm
14
+ module Package
15
+ class PackageDetailsFetcher
16
+ extend T::Sig
17
+ # https://api.github.com/repos/prometheus-community/helm-charts/releases
18
+ RELEASES_URL_GIT = "https://api.github.com/repos/"
19
+ HELM_CHART_RELEASE = "/helm-charts/releases"
20
+ HELM_CHART_INDEX_URL = "https://repo.broadcom.com/bitnami-files/index.yaml"
21
+
22
+ sig do
23
+ params(
24
+ dependency: Dependency,
25
+ credentials: T::Array[Dependabot::Credential]
26
+ ).void
27
+ end
28
+ def initialize(dependency:, credentials:)
29
+ @dependency = dependency
30
+ @credentials = credentials
31
+ end
32
+
33
+ sig { returns(T::Array[Dependabot::Credential]) }
34
+ attr_reader :credentials
35
+
36
+ sig { returns(Dependabot::Dependency) }
37
+ attr_reader :dependency
38
+
39
+ sig { params(repo_name: String).returns(T::Array[GitTagWithDetail]) }
40
+ def fetch_tag_and_release_date_from_chart(repo_name)
41
+ return [] if repo_name.empty?
42
+
43
+ url = RELEASES_URL_GIT + repo_name + HELM_CHART_RELEASE
44
+ Dependabot.logger.info("Fetching graph release details from URL: #{url}")
45
+
46
+ begin
47
+ response = Excon.get(url, headers: { "Accept" => "application/vnd.github.v3+json" })
48
+ rescue Excon::Error => e
49
+ Dependabot.logger.error("Failed to fetch releases from #{url}: #{e.message} ")
50
+ return []
51
+ end
52
+
53
+ Dependabot.logger.error("Failed call details: #{response.body}") unless response.status == 200
54
+ return [] if response.status != 200
55
+
56
+ parse_github_response(response)
57
+ end
58
+
59
+ sig { params(response: Excon::Response).returns(T::Array[GitTagWithDetail]) }
60
+ def parse_github_response(response)
61
+ releases = JSON.parse(response.body)
62
+ result_lines = releases.map do |release|
63
+ GitTagWithDetail.new(
64
+ tag: release["tag_name"],
65
+ release_date: release["published_at"]
66
+ )
67
+ end
68
+ result_lines.sort_by(&:tag).reverse
69
+ rescue JSON::ParserError => e
70
+ Dependabot.logger.error("Failed to parse JSON response: #{e.message} response body #{response.body}")
71
+ []
72
+ end
73
+
74
+ sig { params(index_url: T.nilable(String), chart_name: String).returns(T::Array[GitTagWithDetail]) }
75
+ def fetch_tag_and_release_date_helm_chart_index(index_url, chart_name)
76
+ Dependabot.logger.info("Fetching fetch_tag_and_release_date_helm_chart_index:: #{index_url}")
77
+ index_url = HELM_CHART_INDEX_URL if index_url.nil? || index_url.empty?
78
+ result_lines = T.let([], T::Array[GitTagWithDetail])
79
+ begin
80
+ response = Excon.get(
81
+ index_url,
82
+ idempotent: true,
83
+ middlewares: Excon.defaults[:middlewares] + [Excon::Middleware::RedirectFollower]
84
+ )
85
+ rescue Excon::Error => e
86
+ Dependabot.logger.error("Error fetching Helm index from #{index_url}: #{e.message}")
87
+ return result_lines
88
+ end
89
+ Dependabot.logger.info("Received response from #{index_url} with status #{response.status}")
90
+ begin
91
+ parsed_result = YAML.safe_load(response.body)
92
+ rescue Psych::SyntaxError => e
93
+ Dependabot.logger.error("Error parsing Helm index: #{e.message}")
94
+ return result_lines
95
+ end
96
+ return result_lines unless parsed_result && parsed_result["entries"] && parsed_result["entries"][chart_name]
97
+
98
+ parsed_result["entries"][chart_name].map do |release|
99
+ result_lines << GitTagWithDetail.new(
100
+ tag: release["version"], # Extract the version field
101
+ release_date: release["created"] # Extract the created field
102
+ )
103
+ end
104
+ result_lines
105
+ end
106
+ end
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,188 @@
1
+ # typed: strong
2
+ # frozen_string_literal: true
3
+
4
+ require "dependabot/helm/package/package_details_fetcher"
5
+ require "sorbet-runtime"
6
+ require "dependabot/git_commit_checker"
7
+ require "dependabot/helm/version"
8
+
9
+ module Dependabot
10
+ module Helm
11
+ class LatestVersionResolver
12
+ extend T::Sig
13
+
14
+ DAY_IN_SECONDS = T.let(24 * 60 * 60, Integer)
15
+
16
+ sig do
17
+ params(
18
+ dependency: Dependabot::Dependency,
19
+ credentials: T::Array[Dependabot::Credential],
20
+ cooldown_options: T.nilable(Dependabot::Package::ReleaseCooldownOptions)
21
+ ).void
22
+ end
23
+ def initialize(dependency:, credentials:, cooldown_options:)
24
+ @dependency = dependency
25
+ @credentials = credentials
26
+ @cooldown_options = cooldown_options
27
+ end
28
+
29
+ sig { returns(Dependabot::Dependency) }
30
+ attr_reader :dependency
31
+
32
+ # To filter versions in cooldown period based on version tags from registry call
33
+ sig do
34
+ params(tags: T::Array[String], tags_with_release_date: T::Array[GitTagWithDetail])
35
+ .returns(T::Array[String])
36
+ end
37
+ def filter_versions_in_cooldown_period_using_oci(tags, tags_with_release_date)
38
+ select_tags_which_in_cooldown_using_oci(tags_with_release_date)&.each do |tag_name|
39
+ # Iterate through versions and filter out those matching the tag_name
40
+ tags.reject! do |version|
41
+ version == tag_name
42
+ end
43
+ end
44
+ tags
45
+ rescue StandardError => e
46
+ Dependabot.logger.error("Error filter_versions_in_cooldown_period_for_oci:: #{e.message}")
47
+ tags
48
+ end
49
+
50
+ sig do
51
+ params(
52
+ versions: T::Array[T::Hash[String, T.untyped]],
53
+ repo_name: T.nilable(String),
54
+ chart_name: T.nilable(String)
55
+ )
56
+ .returns(T::Array[T::Hash[String, T.untyped]])
57
+ end
58
+ def fetch_tag_and_release_date_helm_chart(versions, repo_name, chart_name)
59
+ Dependabot.logger.info("Filtering versions in cooldown period from chart: #{repo_name}")
60
+ # Using index URL to fetch tags in cooldown period"
61
+ tags = select_tags_which_in_cooldown_from_chart_index("", T.must(chart_name))
62
+ # If no tags in result then check from github api.
63
+ tags = select_tags_which_in_cooldown_from_chart(T.must(repo_name)) if tags.nil? || tags.empty?
64
+
65
+ return versions if tags.nil? || tags.empty?
66
+
67
+ versions.reject! do |release|
68
+ tags.any?(release["version"])
69
+ end
70
+ versions
71
+ rescue StandardError => e
72
+ Dependabot.logger.error("Error fetch_tag_and_release_date_helm_chart(versions): #{e.message}")
73
+ versions
74
+ end
75
+
76
+ sig { params(repo_name: String).returns(T.nilable(T::Array[String])) }
77
+ def select_tags_which_in_cooldown_from_chart(repo_name)
78
+ version_tags_in_cooldown_from_chart = T.let([], T::Array[String])
79
+
80
+ begin
81
+ package_details_fetcher.fetch_tag_and_release_date_from_chart(repo_name).each do |git_tag_with_detail|
82
+ if check_if_version_in_cooldown_period?(T.must(git_tag_with_detail.release_date))
83
+ version_tags_in_cooldown_from_chart << git_tag_with_detail.tag
84
+ end
85
+ end
86
+ version_tags_in_cooldown_from_chart
87
+ rescue StandardError => e
88
+ Dependabot.logger.error("Error checking if version is in cooldown: #{e.message}")
89
+ version_tags_in_cooldown_from_chart
90
+ end
91
+ end
92
+
93
+ sig { params(index_url: String, versions: T::Array[String], chart_name: String).returns(T::Array[String]) }
94
+ def fetch_tag_and_release_date_helm_chart_index(index_url, versions, chart_name)
95
+ Dependabot.logger.info("Filtering versions in cooldown period from chart: #{index_url}")
96
+ return versions if select_tags_which_in_cooldown_from_chart_index(index_url, chart_name).nil?
97
+
98
+ select_tags_which_in_cooldown_from_chart_index(index_url, chart_name)&.each do |tag_name|
99
+ # Iterate through versions and filter out those matching the tag_name
100
+ versions.reject! do |version|
101
+ version == tag_name
102
+ end
103
+ end
104
+ Dependabot.logger.info("Allowed version tags after filtering versions in cooldown:
105
+ #{versions.map(&:to_s).join(', ')}")
106
+ versions
107
+ rescue StandardError => e
108
+ Dependabot.logger.error("Error fetch_tag_and_release_date_helm_chart_index : #{e.message}")
109
+ versions
110
+ end
111
+
112
+ sig { params(index_url: String, chart_name: String).returns(T.nilable(T::Array[String])) }
113
+ def select_tags_which_in_cooldown_from_chart_index(index_url, chart_name)
114
+ fetch_tag_and_release_date_helm_chart_index = T.let([], T::Array[String])
115
+
116
+ begin
117
+ package_details_fetcher.fetch_tag_and_release_date_helm_chart_index(index_url, chart_name).each do |git_tag|
118
+ if check_if_version_in_cooldown_period?(T.must(git_tag.release_date))
119
+ fetch_tag_and_release_date_helm_chart_index << git_tag.tag
120
+ end
121
+ end
122
+ fetch_tag_and_release_date_helm_chart_index
123
+ rescue StandardError => e
124
+ Dependabot.logger.error("Error checking if version is in cooldown: #{e.message}")
125
+ fetch_tag_and_release_date_helm_chart_index
126
+ end
127
+ end
128
+
129
+ sig { params(release_date: String).returns(T::Boolean) }
130
+ def check_if_version_in_cooldown_period?(release_date)
131
+ return false unless release_date.length.positive?
132
+
133
+ cooldown = @cooldown_options
134
+ return false unless cooldown
135
+
136
+ return false if cooldown.nil?
137
+
138
+ # Calculate the number of seconds passed since the release
139
+ passed_seconds = Time.now.to_i - release_date_to_seconds(release_date)
140
+ # Check if the release is within the cooldown period
141
+ passed_seconds < cooldown.default_days * DAY_IN_SECONDS
142
+ end
143
+
144
+ sig { params(release_date: String).returns(Integer) }
145
+ def release_date_to_seconds(release_date)
146
+ Time.parse(release_date).to_i
147
+ rescue ArgumentError => e
148
+ Dependabot.logger.error("Invalid release date format: #{release_date} and error: #{e.message}")
149
+ 0 # Default to 360 days in seconds if parsing fails, so that it will not be in cooldown
150
+ end
151
+
152
+ sig { params(tags_with_release_date: T::Array[GitTagWithDetail]).returns(T.nilable(T::Array[String])) }
153
+ def select_tags_which_in_cooldown_using_oci(tags_with_release_date)
154
+ fetch_tag_and_release_date_helm_using_oci = T.let([], T::Array[String])
155
+
156
+ begin
157
+ tags_with_release_date.each do |git_tag_with_detail|
158
+ if check_if_version_in_cooldown_period?(T.must(git_tag_with_detail.release_date))
159
+ fetch_tag_and_release_date_helm_using_oci << git_tag_with_detail.tag
160
+ end
161
+ end
162
+ fetch_tag_and_release_date_helm_using_oci
163
+ rescue StandardError => e
164
+ Dependabot.logger.error("Error checking if version is in cooldown: #{e.message}")
165
+ fetch_tag_and_release_date_helm_using_oci
166
+ end
167
+ end
168
+
169
+ sig { returns(Package::PackageDetailsFetcher) }
170
+ def package_details_fetcher
171
+ @package_details_fetcher ||= T.let(
172
+ Package::PackageDetailsFetcher.new(
173
+ dependency: dependency,
174
+ credentials: credentials
175
+ ), T.nilable(Package::PackageDetailsFetcher)
176
+ )
177
+ end
178
+
179
+ sig { returns(T::Boolean) }
180
+ def cooldown_enabled?
181
+ Dependabot::Experiments.enabled?(:enable_cooldown_for_helm)
182
+ end
183
+
184
+ sig { returns(T::Array[Dependabot::Credential]) }
185
+ attr_reader :credentials
186
+ end
187
+ end
188
+ end
@@ -19,6 +19,8 @@ module Dependabot
19
19
  class UpdateChecker < Dependabot::UpdateCheckers::Base
20
20
  extend T::Sig
21
21
 
22
+ require_relative "update_checker/latest_version_resolver"
23
+
22
24
  sig { override.returns(T.nilable(T.any(String, Gem::Version))) }
23
25
  def latest_version
24
26
  @latest_version ||= T.let(fetch_latest_version, T.nilable(T.any(String, Gem::Version)))
@@ -67,6 +69,10 @@ module Dependabot
67
69
  valid_releases = filter_valid_releases(releases)
68
70
  return nil if valid_releases.empty?
69
71
 
72
+ if cooldown_enabled?
73
+ valid_releases = latest_version_resolver
74
+ .fetch_tag_and_release_date_helm_chart(valid_releases, repo_name, chart_name)
75
+ end
70
76
  highest_release = valid_releases.max_by { |release| version_class.new(release["version"]) }
71
77
  Dependabot.logger.info(
72
78
  "Found latest version #{T.must(highest_release)['version']} for #{chart_name} using helm search"
@@ -87,6 +93,14 @@ module Dependabot
87
93
  Dependabot.logger.info("Found #{all_versions.length} versions for #{chart_name} in index.yaml")
88
94
 
89
95
  valid_versions = filter_valid_versions(all_versions)
96
+ if cooldown_enabled?
97
+ # Filter out versions that are in cooldown period
98
+ valid_versions = latest_version_resolver.fetch_tag_and_release_date_helm_chart_index(
99
+ index_url,
100
+ valid_versions,
101
+ chart_name
102
+ )
103
+ end
90
104
  Dependabot.logger.info("After filtering, found #{valid_versions.length} valid versions for #{chart_name}")
91
105
 
92
106
  return nil if valid_versions.empty?
@@ -153,7 +167,6 @@ module Dependabot
153
167
  Dependabot.logger.info("Fetching releases for Helm chart: #{chart_name}")
154
168
 
155
169
  if repo_name && repo_url
156
- authenticate_registry_source(repo_url)
157
170
  begin
158
171
  Helpers.add_repo(repo_name, repo_url)
159
172
  Helpers.update_repo
@@ -178,39 +191,12 @@ module Dependabot
178
191
  end
179
192
  end
180
193
 
181
- sig { params(repo_url: T.nilable(String)).returns(T.nilable(String)) }
182
- def authenticate_registry_source(repo_url)
183
- return unless repo_url
184
-
185
- repo_creds = Shared::Utils::CredentialsFinder.new(@credentials, private_repository_type: "helm_registry")
186
- .credentials_for_registry(repo_url)
187
- return unless repo_creds
188
-
189
- Helpers.registry_login(T.must(repo_creds["username"]), T.must(repo_creds["password"]), repo_url)
190
- rescue StandardError
191
- raise PrivateSourceAuthenticationFailure, repo_url
192
- end
193
-
194
- sig { params(repo_url: T.nilable(String)).returns(T.nilable(String)) }
195
- def authenticate_oci_registry_source(repo_url)
196
- return unless repo_url
197
-
198
- repo_creds = Shared::Utils::CredentialsFinder.new(@credentials, private_repository_type: "helm_registry")
199
- .credentials_for_registry(repo_url)
200
- return unless repo_creds
201
-
202
- Helpers.oci_registry_login(T.must(repo_creds["username"]), T.must(repo_creds["password"]), repo_url)
203
- rescue StandardError
204
- raise PrivateSourceAuthenticationFailure, repo_url
205
- end
206
-
207
194
  sig { returns(T.nilable(Gem::Version)) }
208
195
  def fetch_latest_chart_version
209
196
  chart_name = dependency.name
210
197
  source = dependency.requirements.first&.dig(:source)
211
198
  repo_url = source&.dig(:registry)
212
199
  repo_name = extract_repo_name(repo_url)
213
-
214
200
  releases = fetch_releases_with_helm_cli(chart_name, repo_name, repo_url)
215
201
  return releases if releases
216
202
 
@@ -226,6 +212,16 @@ module Dependabot
226
212
  return nil unless tags && !tags.empty?
227
213
 
228
214
  valid_tags = filter_valid_versions(tags)
215
+ if cooldown_enabled?
216
+ # Filter out versions that are in cooldown period
217
+ repo_url = repo_url.gsub("oci://", "")
218
+ repo_url = repo_url + "/" + chart_name
219
+ tags_with_release_date = fetch_tags_with_release_date_using_oci(valid_tags, repo_url)
220
+ valid_tags = latest_version_resolver.filter_versions_in_cooldown_period_using_oci(
221
+ valid_tags,
222
+ tags_with_release_date
223
+ )
224
+ end
229
225
  return nil if valid_tags.empty?
230
226
 
231
227
  highest_tag = valid_tags.map { |v| version_class.new(v) }.max
@@ -237,7 +233,6 @@ module Dependabot
237
233
  def fetch_oci_tags(chart_name, repo_url)
238
234
  Dependabot.logger.info("Fetching OCI tags for #{repo_url}")
239
235
  oci_registry = repo_url.gsub("oci://", "")
240
- authenticate_oci_registry_source(repo_url)
241
236
 
242
237
  release_tags = Helpers.fetch_oci_tags("#{oci_registry}/#{chart_name}").split("\n")
243
238
  release_tags.map { |tag| tag.tr("_", "+") }
@@ -295,14 +290,26 @@ module Dependabot
295
290
 
296
291
  Dependabot.logger.info("Delegating to Docker UpdateChecker for image: #{docker_dependency.name}")
297
292
 
298
- docker_checker = Dependabot::UpdateCheckers.for_package_manager("docker").new(
299
- dependency: docker_dependency,
300
- dependency_files: dependency_files,
301
- credentials: credentials,
302
- ignored_versions: ignored_versions,
303
- security_advisories: security_advisories,
304
- raise_on_ignored: raise_on_ignored
305
- )
293
+ docker_checker = if cooldown_enabled?
294
+ Dependabot::UpdateCheckers.for_package_manager("docker").new(
295
+ dependency: docker_dependency,
296
+ dependency_files: dependency_files,
297
+ credentials: credentials,
298
+ ignored_versions: ignored_versions,
299
+ security_advisories: security_advisories,
300
+ raise_on_ignored: raise_on_ignored,
301
+ update_cooldown: update_cooldown
302
+ )
303
+ else
304
+ Dependabot::UpdateCheckers.for_package_manager("docker").new(
305
+ dependency: docker_dependency,
306
+ dependency_files: dependency_files,
307
+ credentials: credentials,
308
+ ignored_versions: ignored_versions,
309
+ security_advisories: security_advisories,
310
+ raise_on_ignored: raise_on_ignored
311
+ )
312
+ end
306
313
 
307
314
  latest_version = docker_checker.latest_version
308
315
 
@@ -313,6 +320,36 @@ module Dependabot
313
320
  version_class.new(latest_version)
314
321
  end
315
322
 
323
+ sig { params(tags: T::Array[String], repo_url: String).returns(T::Array[GitTagWithDetail]) }
324
+ def fetch_tags_with_release_date_using_oci(tags, repo_url)
325
+ git_tag_with_release_date = T.let([], T::Array[GitTagWithDetail])
326
+ return git_tag_with_release_date if tags.empty?
327
+
328
+ tags = tags.sort.reverse.take(150) # Limit to 150 tags for performance
329
+ tags.each do |tag|
330
+ # Since the oras registry uses "_" instead of "+", this is a workaround
331
+ # to ensure the tag is correctly formatted for the OCI registry.
332
+ # This is necessary because some tags may contain "+" which is not valid in OCI tags.
333
+
334
+ temp_tag = tag.tr("+", "_")
335
+ response = Helpers.fetch_tags_with_release_date_using_oci(repo_url, temp_tag)
336
+
337
+ begin
338
+ parsed_response = JSON.parse(response)
339
+ rescue JSON::ParserError => e
340
+ Dependabot.logger.error("Failed to parse JSON response for tag #{tag}: #{e.message}")
341
+ next
342
+ end
343
+ git_tag_with_release_date << GitTagWithDetail.new(
344
+ tag: tag,
345
+ release_date: parsed_response.dig("annotations", "org.opencontainers.image.created")
346
+ )
347
+ rescue StandardError => e
348
+ Dependabot.logger.error("Error in fetching details for tag #{tag}: #{e.message}")
349
+ end
350
+ git_tag_with_release_date
351
+ end
352
+
316
353
  sig { returns(Dependabot::Dependency) }
317
354
  def build_docker_dependency
318
355
  source = T.must(dependency.requirements.first)[:source]
@@ -344,8 +381,27 @@ module Dependabot
344
381
  package_manager: "helm"
345
382
  )
346
383
  end
384
+
385
+ sig { returns(T::Boolean) }
386
+ def cooldown_enabled?
387
+ # This is a simple check to see if user has put cooldown days.
388
+ # If not set, then we aassume user does not want cooldown.
389
+ # Since Helm does not support Semver versioning, So option left
390
+ # for the user is to set cooldown default days.
391
+ return false if update_cooldown.nil?
392
+
393
+ T.must(update_cooldown&.default_days).positive?
394
+ end
395
+
396
+ sig { returns(LatestVersionResolver) }
397
+ def latest_version_resolver
398
+ LatestVersionResolver.new(
399
+ dependency: dependency,
400
+ credentials: credentials,
401
+ cooldown_options: update_cooldown
402
+ )
403
+ end
347
404
  end
348
405
  end
349
406
  end
350
-
351
407
  Dependabot::UpdateCheckers.register("helm", Dependabot::Helm::UpdateChecker)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dependabot-helm
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.322.2
4
+ version: 0.324.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dependabot
@@ -15,28 +15,28 @@ dependencies:
15
15
  requirements:
16
16
  - - '='
17
17
  - !ruby/object:Gem::Version
18
- version: 0.322.2
18
+ version: 0.324.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.322.2
25
+ version: 0.324.0
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: dependabot-docker
28
28
  requirement: !ruby/object:Gem::Requirement
29
29
  requirements:
30
30
  - - '='
31
31
  - !ruby/object:Gem::Version
32
- version: 0.322.2
32
+ version: 0.324.0
33
33
  type: :runtime
34
34
  prerelease: false
35
35
  version_requirements: !ruby/object:Gem::Requirement
36
36
  requirements:
37
37
  - - '='
38
38
  - !ruby/object:Gem::Version
39
- version: 0.322.2
39
+ version: 0.324.0
40
40
  - !ruby/object:Gem::Dependency
41
41
  name: debug
42
42
  requirement: !ruby/object:Gem::Requirement
@@ -263,15 +263,17 @@ files:
263
263
  - lib/dependabot/helm/file_updater/image_updater.rb
264
264
  - lib/dependabot/helm/file_updater/lock_file_generator.rb
265
265
  - lib/dependabot/helm/helpers.rb
266
+ - lib/dependabot/helm/package/package_details_fetcher.rb
266
267
  - lib/dependabot/helm/package_manager.rb
267
268
  - lib/dependabot/helm/update_checker.rb
269
+ - lib/dependabot/helm/update_checker/latest_version_resolver.rb
268
270
  - lib/dependabot/helm/version.rb
269
271
  homepage: https://github.com/dependabot/dependabot-core
270
272
  licenses:
271
273
  - MIT
272
274
  metadata:
273
275
  bug_tracker_uri: https://github.com/dependabot/dependabot-core/issues
274
- changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.322.2
276
+ changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.324.0
275
277
  rdoc_options: []
276
278
  require_paths:
277
279
  - lib