Repository navigation
Harden PR labeler against transient GitHub API failures - #22
martinlocklear merged 1 commit into
Conversation
|
[authored by Cursor] Conversation summaryThis PR came from investigating a PR-labeler run that failed on a transient GitHub Plan doc: labeler transient failure hardening Key decisions
Alternatives considered
|
I really like this whole block comment. Useful info. |
|
|
||
| # Case-insensitive substrings that mark a gh failure as a momentary | ||
| # server/network hiccup rather than a real error. | ||
| _RETRYABLE_GH_SIGNATURES = ( |
There was a problem hiding this comment.
Non-blocking: these are matched as bare substrings anywhere in stderr, so codes like 502/504 and especially eof can false-positive on unrelated text (e.g. a numeric ID or SHA that happens to contain 504). Anchoring to HTTP 50x would prevent the numeric one. For eof, I'm a little more shaky. Maybe "unexpected eof", ": eof".
| "connection reset", | ||
| "connection refused", | ||
| "eof", | ||
| "rate limit", |
There was a problem hiding this comment.
Non-blocking: "rate limit" also matches primary rate limits, which reset minutes out. 3 quick retries with a 1-2s backoff won't recover, they'll just delay the inevitable failure. Restricting to "secondary rate limit" (plus the existing "abuse detection") would avoid retrying an unrecoverable condition.
0dc724c to
b5444c7
Compare
|
Should fix the lint failure: #23 |
Wrap gh() in a bounded, classified retry loop so momentary GitHub API errors (5xx, request timeouts, dropped connections, secondary rate limits) retry with exponential backoff instead of failing the run. Real errors (404, auth, bad input) carry none of the transient signatures and still fail fast, honoring the caller's check flag. Floor the backfill failure-rate gate with a two-failure minimum so a single failure never fails the run: event mode (one target) tolerates one transient error even when retries are exhausted, while backfill still fails when 2+ PRs fail and the rate exceeds the threshold. Promote the bare 10% literal to a named constant. Cover both with unit tests: transient classification, retry-then-success, non-retryable fast-fail, exhausted retries, and the failure-rate floor. [authored by Cursor] Co-authored-by: Cursor <cursoragent@cursor.com>
b5444c7 to
2ac60e1
Compare
[authored by Cursor]
Summary
gh()so transient GitHub API errors (502/503/504, timeouts, connection resets) retry instead of failing the run.MIN_FAILURES_TO_FAIL = 2so a single blip never fails event-mode labeling, while backfill still catches systemic breakage.Motivation
A
pull_requestlabeler run failed on a one-offHTTP 504.gh()ran each API call once, and the 10% failure gate has zero tolerance with a single target (1/1 = 100%), so a momentary hiccup failed an otherwise-healthy PR check. Retry is the real fix; the floor is the backstop. Merging tomainpropagates to every repo that calls the reusable labeler workflow at@main.Tracked in INT-802.
Background: labeler transient failure hardening plan
Test plan
python -m pytest .github/scripts -v(134 passed)ruff check .github/scriptsandruff format --check .github/scripts