kettle-gha-pins 0.3.12 → 0.3.14

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: bbd722b090d367d80e40c34de0df0f3abc00fff51e411a8c0676e45d556eb7ef
4
- data.tar.gz: 80aa6f0f24d4c5473a6e78d5b487ce34ae3e200a032503b652b9ca37aacfc0ae
3
+ metadata.gz: 9a6c9dee6aafe12efeb7572d62b3bee72660c3e9b05d2d556b51e23ca35fc1ce
4
+ data.tar.gz: f77439677811a504d5258374721142c6d94beb01cfc3687b9c510f6d23de57e1
5
5
  SHA512:
6
- metadata.gz: 9ad84fb8c23112d1dd16bdf9226f101daf0d685e1e8d59378118c941a4129b6b274552ca9397bbb6b6c0c3c3a96a85ad1394490421fccb1ff76920f484688266
7
- data.tar.gz: 49b0370d149323a8a4735afbec6e49f29b34ce939b84b71c9d55980e94918961cf66f6b8edd591572b395bf5def8a3ddea27b1e04a803870cd6619d51c4d6094
6
+ metadata.gz: 8588d4a919344972832a510333f3f7777ea9feb3c4de203e3ac5843e931ed27a7212238eaa6fc801effafe25e4f233c05afd56d2b5f1b506596e170e13548d8e
7
+ data.tar.gz: ced0bc3b684ee34a1db85dae10fb158d4a4828b1c8113783f000884598b664fff3136eacc1e6e097d74c19d4c26af69e74557c591bde15d6b54ad788a171893f
checksums.yaml.gz.sig CHANGED
Binary file
data/CHANGELOG.md CHANGED
@@ -30,6 +30,35 @@ Please file a bug if you notice a violation of semantic versioning.
30
30
 
31
31
  ### Security
32
32
 
33
+ ## [0.3.14] - 2026-08-28
34
+
35
+ - TAG: [v0.3.14][0.3.14t]
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
+ ### Changed
41
+
42
+ - [kc] kettle-jem/prepare: updated 8 project files:
43
+ - configuration (1)
44
+ - dependencies (7)
45
+
46
+ - [kc] kettle-jem/template: updated 4 project files:
47
+ - dependencies (1)
48
+ - documentation (2)
49
+ - other (1)
50
+
51
+ ## [0.3.13] - 2026-08-15
52
+
53
+ - TAG: [v0.3.13][0.3.13t]
54
+ - COVERAGE: 97.09% -- 1067/1099 lines in 8 files
55
+ - BRANCH COVERAGE: 85.66% -- 430/502 branches in 8 files
56
+ - 26.13% documented
57
+
58
+ ### Fixed
59
+
60
+ - Retry transient GitHub Action metadata failures and report API response details during strict pin reviews.
61
+
33
62
  ## [0.3.12] - 2026-08-12
34
63
 
35
64
  - TAG: [v0.3.12][0.3.12t]
@@ -323,7 +352,11 @@ Please file a bug if you notice a violation of semantic versioning.
323
352
  - kettle-jem-template-20260720-005 - Generated README Support & Community rows
324
353
  now include a RubyForum help badge.
325
354
 
326
- [Unreleased]: https://github.com/kettle-dev/kettle-gha-pins/compare/v0.3.12...HEAD
355
+ [Unreleased]: https://github.com/kettle-dev/kettle-gha-pins/compare/v0.3.14...HEAD
356
+ [0.3.14]: https://github.com/kettle-dev/kettle-gha-pins/compare/v0.3.13...v0.3.14
357
+ [0.3.14t]: https://github.com/kettle-dev/kettle-gha-pins/releases/tag/v0.3.14
358
+ [0.3.13]: https://github.com/kettle-dev/kettle-gha-pins/compare/v0.3.12...v0.3.13
359
+ [0.3.13t]: https://github.com/kettle-dev/kettle-gha-pins/releases/tag/v0.3.13
327
360
  [0.3.12]: https://github.com/kettle-dev/kettle-gha-pins/compare/v0.3.11...v0.3.12
328
361
  [0.3.12t]: https://github.com/kettle-dev/kettle-gha-pins/releases/tag/v0.3.12
329
362
  [0.3.11]: https://github.com/kettle-dev/kettle-gha-pins/compare/v0.3.10...v0.3.11
data/README.md CHANGED
@@ -96,7 +96,9 @@ The _amazing_ test matrix is powered by the kettle-dev stack.
96
96
 
97
97
  </details>
98
98
 
99
- ### Enterprise Support [![Tidelift](https://tidelift.com/badges/package/rubygems/kettle-gha-pins)](https://tidelift.com/subscription/pkg/rubygems-kettle-gha-pins?utm_source=rubygems-kettle-gha-pins&utm_medium=referral&utm_campaign=readme)
99
+ ### Enterprise Support
100
+
101
+ [![Tidelift](https://tidelift.com/badges/package/rubygems/kettle-gha-pins)](https://tidelift.com/subscription/pkg/rubygems-kettle-gha-pins?utm_source=rubygems-kettle-gha-pins&utm_medium=referral&utm_campaign=readme)
100
102
 
101
103
  Available as part of the Tidelift Subscription.
102
104
 
@@ -568,7 +570,7 @@ Thanks for RTFM. ☺️
568
570
  [📌gitmoji]: https://gitmoji.dev
569
571
  [📌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
572
  [🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
571
- [🧮kloc-img]: https://img.shields.io/badge/KLOC-1.065-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
573
+ [🧮kloc-img]: https://img.shields.io/badge/KLOC-1.099-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
572
574
  [🔐security]: https://github.com/kettle-dev/kettle-gha-pins/blob/main/SECURITY.md
573
575
  [🔐security-img]: https://img.shields.io/badge/security-policy-259D6C.svg?style=flat
574
576
  [📄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
- return refresh_failed!(repo_ref, stale, "invalid releases response") unless data.is_a?(Array)
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
- raise RefreshError, "#{message} for #{repo_ref}"
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
- response = http_request(uri, request)
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
- break unless response.code.to_i.between?(300, 399)
237
- redirects -= 1
238
- return nil if redirects.negative?
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
- location = response["location"].to_s
241
- return nil if location.empty?
276
+ @last_request_error = response_error(response, path)
277
+ return nil
278
+ end
242
279
 
243
- uri = URI.join(uri.to_s, location)
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
- return nil unless response.code.to_i == 200
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
- begin
249
- JSON.parse(response.body)
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
- rescue IOError, SystemCallError, Net::OpenTimeout, Net::ReadTimeout
254
- nil
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.12"
9
+ VERSION = "0.3.14"
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.12
4
+ version: 0.3.14
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter H. Boling
@@ -94,7 +94,7 @@ dependencies:
94
94
  version: '3.0'
95
95
  - - ">="
96
96
  - !ruby/object:Gem::Version
97
- version: 3.0.6
97
+ version: 3.0.13
98
98
  type: :development
99
99
  prerelease: false
100
100
  version_requirements: !ruby/object:Gem::Requirement
@@ -104,7 +104,7 @@ dependencies:
104
104
  version: '3.0'
105
105
  - - ">="
106
106
  - !ruby/object:Gem::Version
107
- version: 3.0.6
107
+ version: 3.0.13
108
108
  - !ruby/object:Gem::Dependency
109
109
  name: bundler-audit
110
110
  requirement: !ruby/object:Gem::Requirement
@@ -202,7 +202,7 @@ dependencies:
202
202
  version: '2.0'
203
203
  - - ">="
204
204
  - !ruby/object:Gem::Version
205
- version: 2.0.19
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.19
215
+ version: 2.0.20
216
216
  - !ruby/object:Gem::Dependency
217
217
  name: turbo_tests2
218
218
  requirement: !ruby/object:Gem::Requirement
@@ -222,7 +222,7 @@ dependencies:
222
222
  version: '3.2'
223
223
  - - ">="
224
224
  - !ruby/object:Gem::Version
225
- version: 3.2.5
225
+ version: 3.2.6
226
226
  type: :development
227
227
  prerelease: false
228
228
  version_requirements: !ruby/object:Gem::Requirement
@@ -232,7 +232,7 @@ dependencies:
232
232
  version: '3.2'
233
233
  - - ">="
234
234
  - !ruby/object:Gem::Version
235
- version: 3.2.5
235
+ version: 3.2.6
236
236
  - !ruby/object:Gem::Dependency
237
237
  name: stone_checksums
238
238
  requirement: !ruby/object:Gem::Requirement
@@ -262,7 +262,7 @@ dependencies:
262
262
  version: '2.0'
263
263
  - - ">="
264
264
  - !ruby/object:Gem::Version
265
- version: 2.0.11
265
+ version: 2.0.12
266
266
  type: :development
267
267
  prerelease: false
268
268
  version_requirements: !ruby/object:Gem::Requirement
@@ -272,7 +272,7 @@ dependencies:
272
272
  version: '2.0'
273
273
  - - ">="
274
274
  - !ruby/object:Gem::Version
275
- version: 2.0.11
275
+ version: 2.0.12
276
276
  description: "\U0001F4CC GitHub Actions workflow SHA pin maintenance, including deterministic
277
277
  release-tag parsing, canonicalization, cache-backed GitHub ref resolution, and upgrade
278
278
  planning."
@@ -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.12
305
- changelog_uri: https://github.com/kettle-dev/kettle-gha-pins/blob/v0.3.12/CHANGELOG.md
304
+ source_code_uri: https://github.com/kettle-dev/kettle-gha-pins/tree/v0.3.14
305
+ changelog_uri: https://github.com/kettle-dev/kettle-gha-pins/blob/v0.3.14/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.12
307
+ documentation_uri: https://www.rubydoc.info/gems/kettle-gha-pins/0.3.14
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