Skip to content

fix: actions rate limit#164

Merged
lizhengfeng101 merged 10 commits into
alibaba:mainfrom
stay-foolish-forever:fix/actions-rate-limit
Jun 22, 2026
Merged

fix: actions rate limit#164
lizhengfeng101 merged 10 commits into
alibaba:mainfrom
stay-foolish-forever:fix/actions-rate-limit

Conversation

@stay-foolish-forever

@stay-foolish-forever stay-foolish-forever commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Description

Add rate-limit handling and version verification to both the GitHub Actions and GitLab CI example workflows. When posting many review comments via API, the original scripts could hit platform rate limits (GitHub's secondary rate limit of ~80 content-creating requests/min, and GitLab's general rate limit on self-hosted instances), causing comment posting failures with no recovery mechanism.

This PR introduces exponential backoff with retry logic, configurable delay constants, and a post-install version check for better observability.

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Refactoring (no functional changes)
  • Documentation update
  • CI / Build / Tooling

How Has This Been Tested?

  • make test passes locally
  • Manual testing (describe below)

Checklist

  • My code follows the project's coding style (go fmt, go vet)
  • I have performed a self-review of my code
  • I have added tests that prove my fix is effective or my feature works
  • New and existing unit tests pass locally with my changes
  • I have updated the documentation accordingly (if applicable)
  • I have signed the CLA

Related Issues

#158

…s workflow

- Add version check after OCR installation to verify successful setup
- Implement exponential backoff retry logic for GitHub API rate limits
- Add delays between individual comment posts to avoid secondary rate limits
- GitHub enforces ~80 content-generating requests per minute; spacing calls
  helps stay under that threshold with 2-second base delay and up to 3 retries
- Add `|| true` to ocr version check for error isolation
- Narrow rate limit detection to 429 and 403 with rate-limit
  message matching, avoiding retries on permission/auth failures
- Extract hardcoded delay constants into env-configurable
  variables (OCR_RETRY_BASE_DELAY, OCR_MAX_RETRIES,
  OCR_SUCCESS_DELAY, OCR_FAILURE_DELAY) with sensible defaults
- Document optional environment variables in workflow header
- Add `ocr version || true` after install for diagnostic logging
- Add `api_request_with_retry` function with exponential backoff
  for 429 and 403 (rate-limit message matching) errors
- Respect GitLab `Retry-After` header when present
- Extract delay constants into CI/CD-configurable variables
  (OCR_RETRY_BASE_DELAY, OCR_MAX_RETRIES,
  OCR_SUCCESS_DELAY, OCR_FAILURE_DELAY) with defaults
- Add pacing delays between successful/failed discussion posts
- Document optional CI/CD variables in pipeline header comments

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔍 OpenCodeReview found 1 issue(s) in this PR.

  • ✅ 1 posted as inline comment(s)
  • 📝 0 posted as summary

Comment on lines +286 to +292
} else {
failedCount++;
failedComments.push({ comment, error: innerE.message });
console.log(`Failed to post comment for ${reviewComment.path}: ${innerE.message}`);
// Still delay after a non-rate-limit failure to pace subsequent requests
await sleep(FAILURE_DELAY);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: When rate-limit retries are exhausted (i.e., isRateLimit === true but attempt === MAX_RETRIES), execution falls into this else branch, which only applies FAILURE_DELAY (default 1000ms). After repeatedly hitting rate limits, a 1-second pause before the next comment's API call is likely insufficient and may perpetuate rate-limit failures.

Additionally, the comment "Still delay after a non-rate-limit failure" is misleading because this branch also handles exhausted rate-limit retries.

Consider distinguishing between the two failure cases: apply a longer delay (e.g., the last computed backoff delay or SUCCESS_DELAY) when rate-limit retries are exhausted, and keep the shorter FAILURE_DELAY only for genuine non-rate-limit errors.

Suggestion:

Suggested change
} else {
failedCount++;
failedComments.push({ comment, error: innerE.message });
console.log(`Failed to post comment for ${reviewComment.path}: ${innerE.message}`);
// Still delay after a non-rate-limit failure to pace subsequent requests
await sleep(FAILURE_DELAY);
}
} else {
failedCount++;
failedComments.push({ comment, error: innerE.message });
console.log(`Failed to post comment for ${reviewComment.path}: ${innerE.message}`);
// After exhausting rate-limit retries, use a longer delay; for other errors, use a shorter pace delay
const postFailDelay = isRateLimit ? RETRY_BASE_DELAY * Math.pow(2, MAX_RETRIES) : FAILURE_DELAY;
await sleep(postFailDelay);
}

- GitHub Actions: distinguish exhausted rate-limit retries from other errors, apply SUCCESS_DELAY (2s) instead of FAILURE_DELAY (1s) when retries exhausted
- GitLab CI: return structured result from api_request_with_retry to differentiate failure types, apply context-aware delays based on rate-limit exhaustion status
- Both: prevent perpetuating rate-limit failures by using longer delays after retry exhaustion
@stay-foolish-forever

Copy link
Copy Markdown
Contributor Author

Will perform some further tests before it can be merged.

@vanducng

Copy link
Copy Markdown
Contributor

Thanks for issuing this, hit the same issue today.

Derive wait durations from response headers (retry-after, x-ratelimit-reset)
instead of fixed exponential backoff, add proactive throttle when remaining
quota is low, honor batch-level rate limits before per-comment retry, and add
support for transient 5xx/408 errors.
…elay, and proactive throttling

- Add ±25% jitter on retry delays to avoid thundering herd problems
- Add OCR_MAX_RETRY_DELAY (default 60s) to cap per-retry wait time
- Add OCR_RATE_LIMIT_THRESHOLD (default 10) for proactive throttling
  based on GitLab RateLimit-Remaining response header
- Parse Retry-After header properly (handle non-numeric values)
- Apply retry logic to all API requests (notes, versions, discussions)
- Parse and log RateLimit-Remaining/Limit headers for observability
- Double pacing delay when remaining quota drops below threshold
- Update README with new configuration variables and behavior docs
…ing variables

- GitHub Actions README: fix OCR_RETRY_BASE_DELAY default from 2000 to 60000
  (matching script code and header comments)
- GitHub Actions README: add missing OCR_RETRY_MAX_DELAY, OCR_LOW_REMAINING_THRESHOLD,
  OCR_LOW_REMAINING_SPACING variables
- GitHub Actions README: add GitHub Rate Limits doc reference link
- GitHub Actions yml header: add OCR_LLM_USE_ANTHROPIC and llm.extra_body notes
- GitLab CI yml header: add llm.extra_body note
- GitLab CI README: add GitLab Rate Limits doc reference link
- GitHub Actions: extract inline header closure into a reusable getHeader
  helper; use it in both computeRetryDelayMs and logRateLimitQuota for
  consistent case-insensitive header access.
- GitHub Actions: use a 2s transientBase for 5xx/408 exponential backoff
  instead of the 60s rate-limit base, since server hiccups are typically
  short-lived and the longer base stalled CI jobs unnecessarily.
- GitLab CI: add a _get_header helper and route all header access
  (Retry-After, RateLimit-*) through it, matching the GitHub Actions
  approach.
- GitLab CI: add transient retry logic for 5xx/408 errors with a 2s
  base delay, so server errors no longer fail immediately.

@lizhengfeng101 lizhengfeng101 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@lizhengfeng101 lizhengfeng101 merged commit 7f22ba8 into alibaba:main Jun 22, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants