Install
Be productive in under a minute
Install the extension once, then use dry runs to preview cleanup safely before deleting anything.
gh extension install Nick2bad4u/gh-runs-cleanup
GitHub CLI extension
gh-runs-cleanup helps you safely
bulk-delete GitHub Actions workflow runs with
dry-run previews, explicit confirmation, filtering
by workflow, branch, age, and status, plus retry
handling and machine-readable JSON summaries.
--dry-run and
--confirm--jsonInstall
Install the extension once, then use dry runs to preview cleanup safely before deleting anything.
gh extension install Nick2bad4u/gh-runs-cleanup
Requirements
gh installed and authenticated>= 22.18.0Features
No destructive action happens unless you opt in
with
--confirm or --yes.
Filter by workflow, branch, event, actor, commit, created date, age threshold, and run status.
Retries with backoff, fail-fast, max-failures, ordering, and exclusion filters help avoid noisy cleanup runs.
Use --json for machine-readable
summaries in scheduled workflows, scripts, or
local tooling.
Process runs in oldest,
newest, or none mode
to match your retention strategy.
Works with existing gh
authentication and repository context instead of
requiring a separate service or config file.
Usage
gh runs-cleanup --repo owner/repo --dry-run
gh runs-cleanup --repo owner/repo --status failure,cancelled --confirm
gh runs-cleanup --repo owner/repo --status failure --before-days 30 --confirm
gh runs-cleanup --repo owner/repo --all-statuses --exclude-workflow CI,Release --dry-run
Filters & controls
| Category | Options |
|---|---|
| Repository | --repo |
| Workflow selection | --workflow,
--exclude-workflow |
| Branch selection | --branch,
--exclude-branch |
| Status & age | --status,
--all-statuses,
--before-days,
--created |
| Execution controls | --max-delete,
--order,
--max-retries,
--retry-delay-ms,
--fail-fast,
--max-failures |
| Output | --verbose,
--quiet,
--json |
JSON mode
gh runs-cleanup \
--repo owner/repo \
--status failure \
--before-days 14 \
--dry-run \
--json
{
"attempted": 0,
"deleted": 0,
"dryRun": true,
"durationMs": 112,
"failed": 0,
"failedIds": [],
"matched": 42,
"repo": "owner/repo",
"skippedByExclusion": 3,
"statuses": ["failure"],
"skippedByAge": 19
}
Start with a dry run, confirm only what you want to remove, and automate the rest with JSON output and scheduled jobs.