Purge all completed GitHub Action runs.
✅ Pre-flight quota checking - Verifies API rate limit before making requests
✅ Smart hibernation - Sleeps until rate limit reset when quota is low (<50 remaining)
✅ Parallel deletion - Deletes up to 15 runs concurrently using Rayon
✅ Secondary rate limit detection - Automatically backs off when hitting burst limits
✅ Colorful output - Emoji-rich terminal feedback
✅ Graceful error handling - Retries on network issues or API errors
- Rust (1.70+)
ghCLI installed and authenticated
cd gh-jobs-purge
cargo build --release# Run all tests
cargo test
# Run with verbose output
cargo test -- --nocapture
# See TESTING.md for detailed test documentation# Default: Delete all completed runs
cargo run --release
# Delete specific statuses
cargo run --release -- --status "success,failure"
# Delete queued runs (use with caution!)
cargo run --release -- --status "queued"
# Multiple statuses with dashes or underscores
cargo run --release -- --status "in-progress,timed-out,action-required"
cargo run --release -- --status "in_progress,timed_out,action_required" # Same thing
# Get help
cargo run --release -- --helpOr install it to your PATH:
cargo install --path .
# Then use it directly
gh-jobs-purge
gh-jobs-purge --status "success,failure,cancelled"The --status flag accepts a comma-separated list of statuses:
queuedin-progress(orin_progress)requestedwaitingpending
✅ Safe to delete
successfailurecancelledskippedneutralstaletimed-out(ortimed_out)action-required(oraction_required)
completed- All finished runs (default)
Note: You can use dashes (-) or underscores (_) interchangeably. Both in-progress and in_progress work.
- Parse Arguments: Validates and normalizes status filters from
--statusflag - Rate Limit Check: Queries GitHub API quota before proceeding
- Hibernation: If <50 requests remaining, sleeps until reset time
- Fetch Runs: Gets up to 300 run IDs per status (multiple API calls if needed)
- Parallel Delete: Spawns 15 worker threads to delete runs concurrently
- Backoff: If secondary rate limit hit, waits 60 seconds
- Loop: Continues until no matching runs remain
| Feature | Fish Script | Rust Implementation |
|---|---|---|
| Rate limiting | ✅ | ✅ |
| Parallel deletion | xargs -P 15 |
Rayon thread pool (15 threads) |
| Error handling | Status codes + stderr | Result<T, E> + anyhow |
| JSON parsing | jq |
serde_json |
| Colors | colorme |
colored crate |
| Performance | ~Same | ~Same (both spawn gh processes) |
- serde/serde_json - JSON parsing
- colored - Terminal colors
- rayon - Parallel iteration
- anyhow - Error handling
- chrono - Time calculations
The script handles:
- Network failures (30s retry)
- API errors (5s retry)
- Rate limit exhaustion (sleep until reset + 10s)
- Secondary rate limits (60s backoff)
MIT