entitlements-github-plugin 1.2.0 → 1.2.1

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: 4907f4cd71ba69a500d3d7da6bd1e27407d55777e1e83ec1bc9ab7278fdaa744
4
- data.tar.gz: 8cd6c1023daa722e97c0d54ccba07568ff9e86749be83089da54077c0a94ba70
3
+ metadata.gz: 63c03f0243b0e1b51bcf58b214a4cf70bc856522209b07f721d4e6b5c219dbe1
4
+ data.tar.gz: 1fc7c61f4ca66cc75a4c212f4f0a40a21b6e5c7e4011dabef46bc6293d4220e0
5
5
  SHA512:
6
- metadata.gz: fab3df5745d25dfc4d89b4c9ee78fb9a0a320b23b3ae6d009ed0efa13b7298118b5ee588c11133396487a477dc94cbe5ddd495fa03e94678e9080c18d3f64990
7
- data.tar.gz: c2e481dbb6807564dc7fc7619ecf31b5adf9fd245e54ed7613d8418b90ca83f98080a6be1a4d7d4060ea3af6c1696575cadd2f08237ab7c4a6ada4880e695268
6
+ metadata.gz: b4344c74a359dc828711ceaea05cf083fc699218a43af046a8fddcd98fc8fe7651dc71e108c2d6f9abc9b5f1aa9f9b7a7b2f70d525927f1b3a179fca2f4e5d5c
7
+ data.tar.gz: ca57d0790b548d6039b48163d38753cacbfd80d86fef7888835f0c70426273188d7533c2e04ce9ecd370ec5553996beb7613aba5fa2788d9ce6ffbde623b5285
@@ -162,7 +162,7 @@ module Entitlements
162
162
  metadata = entitlement_group.metadata
163
163
  metadata["team_id"] = -999
164
164
  rescue Entitlements::Models::Group::NoMetadata
165
- metadata = {"team_id" => -999}
165
+ metadata = { "team_id" => -999 }
166
166
  end
167
167
  Entitlements::Backend::GitHubTeam::Models::Team.new(
168
168
  team_id: -999,
@@ -338,18 +338,30 @@ module Entitlements
338
338
  def graphql_http_post(query)
339
339
  1.upto(MAX_GRAPHQL_RETRIES) do |try_number|
340
340
  result = graphql_http_post_real(query)
341
- if result[:code] < 500
341
+ if !graphql_result_retryable?(result)
342
342
  return result
343
343
  elsif try_number >= MAX_GRAPHQL_RETRIES
344
- Entitlements.logger.error "Query still failing after #{MAX_GRAPHQL_RETRIES} tries. Giving up."
344
+ Entitlements.logger.error "Query still failing after #{MAX_GRAPHQL_RETRIES} tries (last code: #{result[:code]}). Giving up."
345
345
  return result
346
346
  else
347
347
  Entitlements.logger.warn "GraphQL failed on try #{try_number} of #{MAX_GRAPHQL_RETRIES}. Will retry."
348
- sleep WAIT_BETWEEN_GRAPHQL_RETRIES * (2 ** (try_number - 1))
348
+ sleep WAIT_BETWEEN_GRAPHQL_RETRIES * (2**(try_number - 1))
349
349
  end
350
350
  end
351
351
  end
352
352
 
353
+ # Helper: determine whether a result hash from `graphql_http_post_real` represents
354
+ # a transient failure that the retry wrapper will retry. Used by the wrapper itself
355
+ # and to decide log severity inside `graphql_http_post_real`.
356
+ #
357
+ # result - Hash returned by `graphql_http_post_real`.
358
+ #
359
+ # Returns true if the result is retryable (HTTP 5xx or synthetic 5xx), false otherwise.
360
+ Contract ({ code: Integer, data: C::Or[nil, Hash] }) => C::Bool
361
+ def graphql_result_retryable?(result)
362
+ result[:code] >= 500
363
+ end
364
+
353
365
  # Helper method: Do the HTTP POST to the GitHub API for GraphQL.
354
366
  #
355
367
  # query - String with the data to be posted.
@@ -370,23 +382,35 @@ module Entitlements
370
382
  response = http.request(request)
371
383
 
372
384
  if response.code != "200"
373
- Entitlements.logger.error "Got HTTP #{response.code} POSTing to #{uri}"
374
- Entitlements.logger.error response.body
385
+ # The retry wrapper retries on 5xx, so log those at WARN to avoid misleading
386
+ # the operator with an ERROR for a transient failure that we recover from.
387
+ # Terminal non-2xx responses (4xx) stay at ERROR.
388
+ msg = "POST to #{uri} returned HTTP Code #{response.code} and Body: #{response.body}"
389
+ response.code.start_with?("5") ? Entitlements.logger.warn(msg) : Entitlements.logger.error(msg)
375
390
  return { code: response.code.to_i, data: { "body" => response.body } }
376
391
  end
377
392
 
378
393
  begin
379
394
  data = JSON.parse(response.body)
380
395
  if data.key?("errors")
381
- Entitlements.logger.error "Errors reported: #{data['errors'].inspect}"
396
+ # Synthesized 500 below triggers a retry, so log at WARN. Note: some GraphQL
397
+ # `errors` are permanent (bad query, auth, schema). The retry wrapper's final
398
+ # "Giving up" ERROR will surface persistent cases.
399
+ Entitlements.logger.warn "Errors reported: #{data['errors'].inspect}"
382
400
  return { code: 500, data: }
383
401
  end
384
402
  { code: response.code.to_i, data: }
385
403
  rescue JSON::ParserError => e
404
+ # JSON parse errors mean the API returned something we can't interpret. The
405
+ # synthesized 500 below triggers a retry, but the cause is more likely a real
406
+ # protocol/server problem than a transient network blip, so log at ERROR.
386
407
  Entitlements.logger.error "#{e.class} #{e.message}: #{response.body.inspect}"
387
408
  { code: 500, data: { "body" => response.body } }
388
409
  end
389
410
  rescue => e
411
+ # Catch-all for any unexpected exception (network blip OR local code bug).
412
+ # We retry below via the synthesized 500, but log at ERROR because this
413
+ # branch can mask programming errors that operators must see.
390
414
  Entitlements.logger.error "Caught #{e.class} POSTing to #{uri}: #{e.message}"
391
415
  { code: 500, data: nil }
392
416
  end
data/lib/version.rb CHANGED
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Entitlements
4
4
  module Version
5
- VERSION = "1.2.0"
5
+ VERSION = "1.2.1"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: entitlements-github-plugin
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - GitHub, Inc. Security Ops
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-04-16 00:00:00.000000000 Z
11
+ date: 2026-05-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: contracts
@@ -126,14 +126,14 @@ dependencies:
126
126
  requirements:
127
127
  - - '='
128
128
  - !ruby/object:Gem::Version
129
- version: 3.13.0
129
+ version: 3.13.2
130
130
  type: :development
131
131
  prerelease: false
132
132
  version_requirements: !ruby/object:Gem::Requirement
133
133
  requirements:
134
134
  - - '='
135
135
  - !ruby/object:Gem::Version
136
- version: 3.13.0
136
+ version: 3.13.2
137
137
  - !ruby/object:Gem::Dependency
138
138
  name: rubocop
139
139
  requirement: !ruby/object:Gem::Requirement
@@ -182,14 +182,14 @@ dependencies:
182
182
  requirements:
183
183
  - - "~>"
184
184
  - !ruby/object:Gem::Version
185
- version: 0.19.1
185
+ version: 0.26.1
186
186
  type: :development
187
187
  prerelease: false
188
188
  version_requirements: !ruby/object:Gem::Requirement
189
189
  requirements:
190
190
  - - "~>"
191
191
  - !ruby/object:Gem::Version
192
- version: 0.19.1
192
+ version: 0.26.1
193
193
  - !ruby/object:Gem::Dependency
194
194
  name: rugged
195
195
  requirement: !ruby/object:Gem::Requirement