kettle-gha-pins 0.3.12 → 0.3.13
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
- checksums.yaml.gz.sig +0 -0
- data/CHANGELOG.md +14 -1
- data/README.md +1 -1
- data/lib/kettle/gha/pins/github_client.rb +67 -16
- data/lib/kettle/gha/pins/version.rb +1 -1
- data.tar.gz.sig +0 -0
- metadata +6 -6
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: dd7079aed4ef058846c17830bf396357d912f70228c310c91ab9c4cdec617f1d
|
|
4
|
+
data.tar.gz: 911ae0a3199007441d6e41f06ededaa3c8150babae9f88e0ed5ca5a616b21336
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 16ea373fc56f23764e4cda2ab6e56695d92fc5296665c95dd5e166879be4136a3a491cb96ec6d96433e1ef90975227ebe11674ecb7479c9ba36fec56adf9c52d
|
|
7
|
+
data.tar.gz: 302ab92e5d76c6046ecfbaba990eb495408f4843ca4dd029033a9dd49455eb1291b93eb8a474ad6a81a4714ed886724a1ae81e1271f14adbae2f4e12bf53d5f1
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
data/CHANGELOG.md
CHANGED
|
@@ -30,6 +30,17 @@ Please file a bug if you notice a violation of semantic versioning.
|
|
|
30
30
|
|
|
31
31
|
### Security
|
|
32
32
|
|
|
33
|
+
## [0.3.13] - 2026-08-15
|
|
34
|
+
|
|
35
|
+
- TAG: [v0.3.13][0.3.13t]
|
|
36
|
+
- COVERAGE: 97.09% -- 1067/1099 lines in 8 files
|
|
37
|
+
- BRANCH COVERAGE: 85.66% -- 430/502 branches in 8 files
|
|
38
|
+
- 26.13% documented
|
|
39
|
+
|
|
40
|
+
### Fixed
|
|
41
|
+
|
|
42
|
+
- Retry transient GitHub Action metadata failures and report API response details during strict pin reviews.
|
|
43
|
+
|
|
33
44
|
## [0.3.12] - 2026-08-12
|
|
34
45
|
|
|
35
46
|
- TAG: [v0.3.12][0.3.12t]
|
|
@@ -323,7 +334,9 @@ Please file a bug if you notice a violation of semantic versioning.
|
|
|
323
334
|
- kettle-jem-template-20260720-005 - Generated README Support & Community rows
|
|
324
335
|
now include a RubyForum help badge.
|
|
325
336
|
|
|
326
|
-
[Unreleased]: https://github.com/kettle-dev/kettle-gha-pins/compare/v0.3.
|
|
337
|
+
[Unreleased]: https://github.com/kettle-dev/kettle-gha-pins/compare/v0.3.13...HEAD
|
|
338
|
+
[0.3.13]: https://github.com/kettle-dev/kettle-gha-pins/compare/v0.3.12...v0.3.13
|
|
339
|
+
[0.3.13t]: https://github.com/kettle-dev/kettle-gha-pins/releases/tag/v0.3.13
|
|
327
340
|
[0.3.12]: https://github.com/kettle-dev/kettle-gha-pins/compare/v0.3.11...v0.3.12
|
|
328
341
|
[0.3.12t]: https://github.com/kettle-dev/kettle-gha-pins/releases/tag/v0.3.12
|
|
329
342
|
[0.3.11]: https://github.com/kettle-dev/kettle-gha-pins/compare/v0.3.10...v0.3.11
|
data/README.md
CHANGED
|
@@ -568,7 +568,7 @@ Thanks for RTFM. ☺️
|
|
|
568
568
|
[📌gitmoji]: https://gitmoji.dev
|
|
569
569
|
[📌gitmoji-img]: https://img.shields.io/badge/gitmoji_commits-%20%F0%9F%98%9C%20%F0%9F%98%8D-34495e.svg?style=flat-square
|
|
570
570
|
[🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
|
|
571
|
-
[🧮kloc-img]: https://img.shields.io/badge/KLOC-1.
|
|
571
|
+
[🧮kloc-img]: https://img.shields.io/badge/KLOC-1.099-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
|
|
572
572
|
[🔐security]: https://github.com/kettle-dev/kettle-gha-pins/blob/main/SECURITY.md
|
|
573
573
|
[🔐security-img]: https://img.shields.io/badge/security-policy-259D6C.svg?style=flat
|
|
574
574
|
[📄copyright-notice-explainer]: https://opensource.stackexchange.com/questions/5778/why-do-licenses-such-as-the-mit-license-specify-a-single-year
|
|
@@ -12,6 +12,8 @@ module Kettle
|
|
|
12
12
|
# Lightweight GitHub API client for commit and release SHA resolution.
|
|
13
13
|
class GitHubClient
|
|
14
14
|
ANNOTATED_TAG_GIT_FALLBACK_THRESHOLD = 4
|
|
15
|
+
HTTP_RETRY_LIMIT = 2
|
|
16
|
+
RETRYABLE_HTTP_STATUS_CODES = [408, 425, 429, 500, 502, 503, 504].freeze
|
|
15
17
|
class CacheMissError < Error; end
|
|
16
18
|
class RefreshError < Error; end
|
|
17
19
|
|
|
@@ -29,9 +31,10 @@ module Kettle
|
|
|
29
31
|
@commit_cache = {}
|
|
30
32
|
@release_cache = {}
|
|
31
33
|
@last_versions_cache_hit = false
|
|
34
|
+
@last_request_error = nil
|
|
32
35
|
end
|
|
33
36
|
|
|
34
|
-
attr_reader :last_versions_cache_hit
|
|
37
|
+
attr_reader :last_request_error, :last_versions_cache_hit
|
|
35
38
|
|
|
36
39
|
def versions_for_repo(repo_ref)
|
|
37
40
|
@last_versions_cache_hit = false
|
|
@@ -64,7 +67,10 @@ module Kettle
|
|
|
64
67
|
releases = nil
|
|
65
68
|
Timeout.timeout(@refresh_timeout) do
|
|
66
69
|
data = request_json("/repos/#{repo_ref}/releases?per_page=100")
|
|
67
|
-
|
|
70
|
+
unless data.is_a?(Array)
|
|
71
|
+
detail = data.nil? ? nil : "expected an array, got #{data.class}"
|
|
72
|
+
return refresh_failed!(repo_ref, stale, "invalid releases response", detail: detail)
|
|
73
|
+
end
|
|
68
74
|
|
|
69
75
|
tag_shas = tag_ref_shas(repo_ref)
|
|
70
76
|
return refresh_failed!(repo_ref, stale, "invalid tag response") unless tag_shas
|
|
@@ -122,10 +128,12 @@ module Kettle
|
|
|
122
128
|
versions
|
|
123
129
|
end
|
|
124
130
|
|
|
125
|
-
def refresh_failed!(repo_ref, stale, message)
|
|
131
|
+
def refresh_failed!(repo_ref, stale, message, detail: nil)
|
|
126
132
|
return cached_versions(repo_ref, stale) unless @fail_on_refresh_error
|
|
127
133
|
|
|
128
|
-
|
|
134
|
+
detail ||= @last_request_error
|
|
135
|
+
suffix = detail.to_s.empty? ? "" : ": #{detail}"
|
|
136
|
+
raise RefreshError, "#{message} for #{repo_ref}#{suffix}"
|
|
129
137
|
end
|
|
130
138
|
|
|
131
139
|
def build_release_versions(data, tag_shas)
|
|
@@ -222,8 +230,10 @@ module Kettle
|
|
|
222
230
|
|
|
223
231
|
def request_json(path, redirects: 3)
|
|
224
232
|
uri = URI.join(@api_base + "/", path)
|
|
233
|
+
@last_request_error = nil
|
|
225
234
|
|
|
226
235
|
response = nil
|
|
236
|
+
retries = 0
|
|
227
237
|
loop do
|
|
228
238
|
request = Net::HTTP::Get.new(uri)
|
|
229
239
|
request["Accept"] = "application/vnd.github+json"
|
|
@@ -231,27 +241,68 @@ module Kettle
|
|
|
231
241
|
request["X-GitHub-Api-Version"] = "2022-11-28"
|
|
232
242
|
request["Authorization"] = "Bearer #{@token}" if @token && !@token.empty?
|
|
233
243
|
|
|
234
|
-
|
|
244
|
+
begin
|
|
245
|
+
response = http_request(uri, request)
|
|
246
|
+
rescue IOError, SystemCallError, Net::OpenTimeout, Net::ReadTimeout => error
|
|
247
|
+
if retries < HTTP_RETRY_LIMIT
|
|
248
|
+
retries += 1
|
|
249
|
+
sleep(retry_delay(nil, retries))
|
|
250
|
+
next
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
@last_request_error = "GitHub request failed for #{path}: #{error.class}: #{error.message}"
|
|
254
|
+
return nil
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
if response.code.to_i.between?(300, 399)
|
|
258
|
+
redirects -= 1
|
|
259
|
+
return nil if redirects.negative?
|
|
260
|
+
|
|
261
|
+
location = response["location"].to_s
|
|
262
|
+
return nil if location.empty?
|
|
263
|
+
|
|
264
|
+
uri = URI.join(uri.to_s, location)
|
|
265
|
+
next
|
|
266
|
+
end
|
|
235
267
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
268
|
+
status = response.code.to_i
|
|
269
|
+
unless status == 200
|
|
270
|
+
if RETRYABLE_HTTP_STATUS_CODES.include?(status) && retries < HTTP_RETRY_LIMIT
|
|
271
|
+
retries += 1
|
|
272
|
+
sleep(retry_delay(response, retries))
|
|
273
|
+
next
|
|
274
|
+
end
|
|
239
275
|
|
|
240
|
-
|
|
241
|
-
|
|
276
|
+
@last_request_error = response_error(response, path)
|
|
277
|
+
return nil
|
|
278
|
+
end
|
|
242
279
|
|
|
243
|
-
|
|
280
|
+
begin
|
|
281
|
+
return JSON.parse(response.body)
|
|
282
|
+
rescue JSON::ParserError
|
|
283
|
+
@last_request_error = "GitHub returned invalid JSON for #{path}"
|
|
284
|
+
return nil
|
|
285
|
+
end
|
|
244
286
|
end
|
|
287
|
+
end
|
|
245
288
|
|
|
246
|
-
|
|
289
|
+
def retry_delay(response, attempt)
|
|
290
|
+
retry_after = response ? response["retry-after"].to_f : 0.0
|
|
291
|
+
return retry_after.clamp(0.0, 2.0) if retry_after.positive?
|
|
247
292
|
|
|
248
|
-
|
|
249
|
-
|
|
293
|
+
0.25 * (2**(attempt - 1))
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
def response_error(response, path)
|
|
297
|
+
status = response.code.to_i
|
|
298
|
+
body = begin
|
|
299
|
+
JSON.parse(response.body.to_s)
|
|
250
300
|
rescue JSON::ParserError
|
|
251
301
|
nil
|
|
252
302
|
end
|
|
253
|
-
|
|
254
|
-
|
|
303
|
+
message = body.is_a?(Hash) ? body["message"].to_s : ""
|
|
304
|
+
detail = message.empty? ? "response body was not a GitHub API error object" : message
|
|
305
|
+
"GitHub API returned HTTP #{status} for #{path}: #{detail}"
|
|
255
306
|
end
|
|
256
307
|
|
|
257
308
|
def http_request(uri, request)
|
|
@@ -6,7 +6,7 @@ module Kettle
|
|
|
6
6
|
# Version namespace for this gem.
|
|
7
7
|
module Version
|
|
8
8
|
# Current gem version.
|
|
9
|
-
VERSION = "0.3.
|
|
9
|
+
VERSION = "0.3.13"
|
|
10
10
|
end
|
|
11
11
|
# Current gem version exposed at the traditional constant location.
|
|
12
12
|
VERSION = Version::VERSION # Traditional Constant Location
|
data.tar.gz.sig
CHANGED
|
Binary file
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: kettle-gha-pins
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.3.
|
|
4
|
+
version: 0.3.13
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Peter H. Boling
|
|
@@ -202,7 +202,7 @@ dependencies:
|
|
|
202
202
|
version: '2.0'
|
|
203
203
|
- - ">="
|
|
204
204
|
- !ruby/object:Gem::Version
|
|
205
|
-
version: 2.0.
|
|
205
|
+
version: 2.0.20
|
|
206
206
|
type: :development
|
|
207
207
|
prerelease: false
|
|
208
208
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -212,7 +212,7 @@ dependencies:
|
|
|
212
212
|
version: '2.0'
|
|
213
213
|
- - ">="
|
|
214
214
|
- !ruby/object:Gem::Version
|
|
215
|
-
version: 2.0.
|
|
215
|
+
version: 2.0.20
|
|
216
216
|
- !ruby/object:Gem::Dependency
|
|
217
217
|
name: turbo_tests2
|
|
218
218
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -301,10 +301,10 @@ licenses:
|
|
|
301
301
|
- MIT
|
|
302
302
|
metadata:
|
|
303
303
|
homepage_uri: https://github.com/kettle-dev/kettle-gha-pins
|
|
304
|
-
source_code_uri: https://github.com/kettle-dev/kettle-gha-pins/tree/v0.3.
|
|
305
|
-
changelog_uri: https://github.com/kettle-dev/kettle-gha-pins/blob/v0.3.
|
|
304
|
+
source_code_uri: https://github.com/kettle-dev/kettle-gha-pins/tree/v0.3.13
|
|
305
|
+
changelog_uri: https://github.com/kettle-dev/kettle-gha-pins/blob/v0.3.13/CHANGELOG.md
|
|
306
306
|
bug_tracker_uri: https://github.com/kettle-dev/kettle-gha-pins/issues
|
|
307
|
-
documentation_uri: https://www.rubydoc.info/gems/kettle-gha-pins/0.3.
|
|
307
|
+
documentation_uri: https://www.rubydoc.info/gems/kettle-gha-pins/0.3.13
|
|
308
308
|
funding_uri: https://github.com/sponsors/pboling
|
|
309
309
|
wiki_uri: https://github.com/kettle-dev/kettle-gha-pins/wiki
|
|
310
310
|
news_uri: https://www.railsbling.com/tags/kettle-gha-pins
|
metadata.gz.sig
CHANGED
|
Binary file
|