prdigest 0.4.0 → 0.4.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: 85eefac373cdb54b93c372913fcb97cdcd4f1c003aa7cae487355ffd4da2e5e6
4
- data.tar.gz: cb91e2f60e8ae566485dbdb7f56053a93b01df8fe357a9b0b6442c616c1498ec
3
+ metadata.gz: 5e5500df17f1ce6e92cc690540701fdf131a0bf656452dff02611bcb427ff2da
4
+ data.tar.gz: 33d94acd820aa5b1c58789c7d378caf019ec57555cceb50bcee0eda128e57b5b
5
5
  SHA512:
6
- metadata.gz: 2c5009123d2b0df8c39612e47c89ea794a98383808cc709ddbdd1b415d32b71881733007a26f5c3dff69b13027a6c0c9e1ab59e79ee63832c363584b3ef32dc6
7
- data.tar.gz: ab5fd25f659459f3dbd9a787747756bfd9f73c7cc7a56d237529eea18792a15515ac27c9f8a59e954db557338e967c3f639f7c77e318d697255e89be51307d18
6
+ metadata.gz: e065c08331d9f65b8c967af78635e0818568dcc3a987dfaa7618ee605cbf39fe3b484ac539c07b55981c838d2c09bbbe0520f827f6cdd0c5ddc0abb83b6a0358
7
+ data.tar.gz: 757e09a77ec6c7f15f4cb384910f97db756dc0491fb483ef8c3d294c307a32e1fe15d8802f9c35529ca0b9a9c84bc5d085c51852eb4320beb105f02d0ebd0311
data/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.4.1 - 2026-11-07
4
+
5
+ - Retry GitHub rate limits past their reset: waits derived from
6
+ `X-RateLimit-Reset` add a 2-second buffer, no retry waits less than one
7
+ second, and rate-limited requests get 5 attempts (server and transport
8
+ failures keep 3). Previously a search-API limit retried exactly at the reset
9
+ second, saw `remaining=0` again, and exhausted its attempts within that second.
10
+
3
11
  ## 0.4.0 - 2026-09-16
4
12
 
5
13
  - Add bounded PR descriptions and relevant patches to facts, plus the reusable
data/README.md CHANGED
@@ -131,7 +131,7 @@ To build and install the current checkout as a gem without publishing it:
131
131
 
132
132
  ```sh
133
133
  gem build prdigest.gemspec
134
- gem install prdigest-0.4.0.gem
134
+ gem install prdigest-0.4.1.gem
135
135
  prdigest version
136
136
  ```
137
137
 
@@ -336,7 +336,7 @@ chat IDs are normally positive; groups and channels normally use negative IDs.
336
336
  Install the released gem:
337
337
 
338
338
  ```sh
339
- gem install prdigest -v 0.4.0
339
+ gem install prdigest -v 0.4.1
340
340
  prdigest version
341
341
  ```
342
342
 
@@ -416,8 +416,8 @@ current skill. To let OpenClaw install both, copy and paste this prompt into an
416
416
  OpenClaw chat:
417
417
 
418
418
  ```text
419
- Install PRDigest 0.4.0 in the same user/runtime context as OpenClaw with
420
- `gem install prdigest -v 0.4.0`, then install the ClawHub skill with
419
+ Install PRDigest 0.4.1 in the same user/runtime context as OpenClaw with
420
+ `gem install prdigest -v 0.4.1`, then install the ClawHub skill with
421
421
  `openclaw skills install @ivankuznetsov/prdigest`. This message
422
422
  explicitly authorizes those two installs and only the PATH adjustment needed to
423
423
  make the installed `prdigest` executable visible to the OpenClaw runtime. Do
@@ -429,7 +429,7 @@ discover the installed PRDigest skill, and report the installed paths and
429
429
  versions without exposing environment variables or tokens.
430
430
  ```
431
431
 
432
- For a manual install, run `gem install prdigest -v 0.4.0` and
432
+ For a manual install, run `gem install prdigest -v 0.4.1` and
433
433
  `openclaw skills install @ivankuznetsov/prdigest`. The skill gives an agent
434
434
  facts-to-prose behavior only; use the
435
435
  [standalone Telegram bot](#standalone-telegram-bot) when PRDigest itself should
@@ -448,8 +448,8 @@ gem contains the example configuration and tested service units, so a source
448
448
  checkout is not required:
449
449
 
450
450
  ```sh
451
- sudo gem install prdigest -v 0.4.0 --no-document --bindir /usr/local/bin
452
- gem_root=$(ruby -e 'print Gem::Specification.find_by_name("prdigest", "0.4.0").full_gem_path')
451
+ sudo gem install prdigest -v 0.4.1 --no-document --bindir /usr/local/bin
452
+ gem_root=$(ruby -e 'print Gem::Specification.find_by_name("prdigest", "0.4.1").full_gem_path')
453
453
 
454
454
  sudo useradd --system --home /nonexistent --shell "$(command -v nologin)" prdigest
455
455
  sudo install -d -o root -g prdigest -m 0750 /etc/prdigest
@@ -8,6 +8,14 @@ module Prdigest
8
8
  class GitHub
9
9
  SEARCH_CAP = 1_000
10
10
  MAX_ATTEMPTS = 3
11
+ # GitHub's search API allows 30 requests per minute; a multi-repository
12
+ # day or a backfill can exhaust it. Rate limits name their own wait, so
13
+ # they get more attempts than server/transport failures.
14
+ MAX_RATE_LIMIT_ATTEMPTS = 5
15
+ # x-ratelimit-reset is a whole-second boundary. Retrying exactly at it can
16
+ # still see remaining=0 and a computed wait of zero, burning the remaining
17
+ # attempts within the same second.
18
+ RATE_LIMIT_RESET_BUFFER = 2
11
19
  MAX_DESCRIPTION_CHARS = 4_000
12
20
  MAX_PATCH_FILES = 20
13
21
  MAX_PATCH_CHARS = 6_000
@@ -207,10 +215,11 @@ module Prdigest
207
215
  attempts += 1
208
216
  yield
209
217
  rescue StandardError => e
210
- unless transient?(e) && attempts < MAX_ATTEMPTS
218
+ limit = rate_limited?(e) ? MAX_RATE_LIMIT_ATTEMPTS : MAX_ATTEMPTS
219
+ unless transient?(e) && attempts < limit
211
220
  fail_fetch!(repository, date, error_kind(e))
212
221
  end
213
- delay = retry_delay(e) || attempts
222
+ delay = [retry_delay(e) || attempts, 1].max
214
223
  fail_fetch!(repository, date, "retry delay exceeds 60 seconds") if delay > 60
215
224
  @sleeper.call(delay)
216
225
  retry
@@ -225,8 +234,16 @@ module Prdigest
225
234
  end
226
235
 
227
236
  def rate_limited?(error)
228
- error.is_a?(Octokit::TooManyRequests) ||
229
- (error.respond_to?(:response_status) && Integer(error.response_status, exception: false) == 429)
237
+ error.is_a?(Octokit::TooManyRequests) || response_status(error) == 429
238
+ end
239
+
240
+ # Octokit errors built without a response raise from #response_status.
241
+ def response_status(error)
242
+ return unless error.respond_to?(:response_status)
243
+
244
+ Integer(error.response_status, exception: false)
245
+ rescue StandardError
246
+ nil
230
247
  end
231
248
 
232
249
  def retry_delay(error)
@@ -235,7 +252,7 @@ module Prdigest
235
252
  return retry_after if retry_after
236
253
 
237
254
  reset_at = Integer(response_header(headers, "x-ratelimit-reset"), exception: false)
238
- [reset_at - Integer(@now.call), 0].max if reset_at
255
+ [reset_at - Integer(@now.call), 0].max + RATE_LIMIT_RESET_BUFFER if reset_at
239
256
  rescue StandardError
240
257
  nil
241
258
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Prdigest
4
- VERSION = "0.4.0"
4
+ VERSION = "0.4.1"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: prdigest
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ivan Kuznetsov