The test workflow was failing with 429 Too Many Requests errors from GitHub. The root cause: composer install --prefer-dist downloads 95 packages from api.github.com/repos/.../zipball/..., and GitHub's unauthenticated API rate limit is only 60 requests/hour per IP — so the CI run blows through the limit before even finishing.
Solution
Two complementary fixes applied to .gitea/workflows/tests.yaml:
Added a step that configures Composer with a GitHub OAuth token using the existing SYNC_GITHUB_TOKEN secret (already used by publish.yaml). This raises the rate limit to 5,000 requests/hour, which is more than enough for our 95 packages.
Added actions/cache@v4 for ~/.composer/cache, keyed on the composer.lock hash. On repeated CI runs where composer.lock hasn't changed, packages are served from cache — zero GitHub API requests. The cache automatically busts when dependencies change.
## Problem
The test workflow was failing with `429 Too Many Requests` errors from GitHub. The root cause: `composer install --prefer-dist` downloads 95 packages from `api.github.com/repos/.../zipball/...`, and GitHub's **unauthenticated** API rate limit is only **60 requests/hour per IP** — so the CI run blows through the limit before even finishing.
## Solution
Two complementary fixes applied to `.gitea/workflows/tests.yaml`:
### 1. GitHub OAuth authentication (rate limit: 60 → 5,000 req/hour)
Added a step that configures Composer with a GitHub OAuth token using the existing `SYNC_GITHUB_TOKEN` secret (already used by `publish.yaml`). This raises the rate limit to 5,000 requests/hour, which is more than enough for our 95 packages.
```yaml
- name: Configure GitHub OAuth token
env:
GITHUB_TOKEN: ${{ secrets.SYNC_GITHUB_TOKEN }}
run: composer config --global github-oauth.github.com "$GITHUB_TOKEN"
```
### 2. Composer download cache (avoid re-downloading entirely)
Added `actions/cache@v4` for `~/.composer/cache`, keyed on the `composer.lock` hash. On repeated CI runs where `composer.lock` hasn't changed, packages are served from cache — **zero GitHub API requests**. The cache automatically busts when dependencies change.
```yaml
- name: Cache Composer dependencies
uses: actions/cache@v4
with:
path: ~/.composer/cache
key: composer-${{ runner.os }}-${{ hashFiles('composer.lock') }}
restore-keys: |
composer-${{ runner.os }}-
```
## Together
| Scenario | Before | After |
|---|---|---|
| First run (cold cache) | 95 unauthenticated req → 429 | 95 authenticated req → ✅ |
| Repeat run (warm cache) | 95 unauthenticated req → 429 | 0 GitHub req → ✅ |
| After `composer.lock` change | 95 unauthenticated req → 429 | 95 authenticated req → ✅ |
The test workflow was hitting GitHub's unauthenticated API rate
limit (60 req/hour) when downloading 95 packages via composer
install --prefer-dist, causing 429 Too Many Requests errors.
Two fixes applied:
1. Cache Composer's download cache (~/.composer/cache) keyed on
composer.lock hash, so repeated CI runs don't re-download
packages at all.
2. Configure GitHub OAuth token via SYNC_GITHUB_TOKEN secret to
raise the rate limit to 5,000 req/hour for cache misses.
andrew
approved these changes 2026-08-17 18:58:59 -04:00
andrew
merged commit 472abfdf89 into develop2026-08-17 18:59:06 -04:00
andrew
deleted branch fix/ci-github-rate-limit2026-08-17 18:59:06 -04:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Problem
The test workflow was failing with
429 Too Many Requestserrors from GitHub. The root cause:composer install --prefer-distdownloads 95 packages fromapi.github.com/repos/.../zipball/..., and GitHub's unauthenticated API rate limit is only 60 requests/hour per IP — so the CI run blows through the limit before even finishing.Solution
Two complementary fixes applied to
.gitea/workflows/tests.yaml:1. GitHub OAuth authentication (rate limit: 60 → 5,000 req/hour)
Added a step that configures Composer with a GitHub OAuth token using the existing
SYNC_GITHUB_TOKENsecret (already used bypublish.yaml). This raises the rate limit to 5,000 requests/hour, which is more than enough for our 95 packages.2. Composer download cache (avoid re-downloading entirely)
Added
actions/cache@v4for~/.composer/cache, keyed on thecomposer.lockhash. On repeated CI runs wherecomposer.lockhasn't changed, packages are served from cache — zero GitHub API requests. The cache automatically busts when dependencies change.Together
composer.lockchange