Every workflow run stays in your Actions history forever, unless you clean it up yourself. After a year or two of CI, that history turns into thousands of runs nobody will ever open again. Scrolling through them to find anything useful becomes painful.
That is why I built Prune Old GitHub Actions Runs, a GitHub Action that deletes workflow runs older than a number of days you choose, on a schedule.
Get it on GitHub Marketplace · Source on GitHub
What it does
You give it a token and a number of days. Anything older than that gets deleted. You can also tell it to always keep the N most recent runs, regardless of age, so a workflow you rarely trigger does not lose its entire history. A dry-run mode lists what it would delete without deleting anything, which is worth running once before you trust it with the real thing.
Deletion is permanent and cannot be undone, so start with dry-run.
Inputs
| Input | Required | Default | Description |
|---|---|---|---|
token | Yes | - | GitHub token for authentication (use ${{ secrets.GITHUB_TOKEN }}) |
days-ago | Yes | - | number of days to look back when identifying old runs |
dry-run | No | false | when true, lists runs without deleting them |
keep-latest | No | 0 | preserves the most recent N runs; 0 disables this |
Example workflow
Save this as a scheduled workflow, for example .github/workflows/prune-old-actions.yml. Test with dry-run first:
on:
schedule:
- cron: '0 0 * * *'
permissions:
actions: write
jobs:
prune-old-actions:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: yanovian/prune-old-actions@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}
days-ago: 30
dry-run: true
keep-latest: 5
Once you have checked the dry-run output and it deletes what you expect, drop dry-run (or set it to false) and let it run for real on the same schedule.
Permissions and tokens
Deleting workflow runs needs a token with write access to the Actions scope. The default GITHUB_TOKEN works if your workflow grants actions: write; a scoped personal access token or a GitHub App token are the more locked-down alternatives if you would rather not give the default token that reach.
Why it matters
The goal is simple: keep your Actions history relevant and your repository light, without spending time deleting runs by hand every few months. Set the retention window once, run it on a schedule, and forget about it.
