A GitHub Action to delete all caches associated with a specific branch reference in your repository.
- Deletes all GitHub Actions caches for a given branch (
ref) - Supports dry-run mode to preview cache deletions without deleting them
- Supports filtering caches by key glob pattern (e.g. only delete caches with key prefix
npm-) - Supports age-based pruning of stale caches (e.g. only delete caches older than 7 days)
Add the following step to your workflow:
- name: Delete branch caches
uses: Friedinger/DeleteBranchCaches@v3
with:
github-token: ${{ github.token }}
ref: ${{ github.ref }}Note: Your workflow or job must include the following permissions:
permissions:
actions: writeThis is required to allow the action to delete caches.
| Name | Description | Required | Default |
|---|---|---|---|
| github-token | GitHub token to use for authentication | true | ${{ github.token }} |
| ref | The branches ref to delete caches for (e.g. refs/heads/main), can be a single string or a yaml list |
true | ${{ github.ref }} |
| fail-on-warning | Fail the action if a warning occurs during cache deletion | false | false |
| dry-run | List the caches that would be deleted without deleting them | false | false |
| key-filter | Only delete caches whose key matches the glob pattern (e.g. npm-*), combined with ref |
false | "" |
| max-age | Only delete caches older than the given duration (e.g. 7d, 24h, 30m), combined with ref |
false | "" |
- You can leave out both inputs to use the default values, which will delete caches for the current branch of the workflow.
- But it is recommended to always specify the
github-tokeninput for clarity and to avoid issues with permissions.
You can provide the ref input in several ways, depending on your use case and YAML syntax. All of the following variants are supported:
ref: refs/heads/mainref: |
refs/heads/branch-1
refs/heads/branch-2ref: "['refs/heads/branch-1', 'refs/heads/branch-2']"- The action automatically detects the format and processes all variants correctly.
- For lists, the YAML list or array syntax is recommended for best readability.
- Sadly, directly passing an array like
ref: [refs/heads/branch-1, refs/heads/branch-2]does not work due to GitHub only supporting strings for inputs.
The key-filter input is optional. When set, only caches whose key matches the given glob pattern are deleted (or listed with dry-run), combined with ref using AND semantics.
Matching rules:
*matches any sequence of characters (e.g.npm-*matchesnpm-1,npm-lock)- A pattern without
*matches the cache key exactly (e.g.npm-1matches onlynpm-1) - Matching is case-sensitive
key-filter: "npm-*"The max-age input is optional. When set, only caches whose age exceeds the given duration are deleted (or listed with dry-run). The age is determined by last_accessed_at, falling back to created_at. Caches below the age threshold are kept and reported separately.
Duration format: a number followed by m (minutes), h (hours) or d (days). Invalid values fail the action with an error.
max-age: "7d"name: Clean up caches
on:
push:
branches:
- main
jobs:
cleanup:
runs-on: ubuntu-latest
permissions:
actions: write
steps:
- uses: actions/checkout@v4
- name: Delete branch caches
uses: Friedinger/DeleteBranchCaches@v3
with:
github-token: ${{ github.token }}
ref: ${{ github.ref }}
fail-on-warning: trueThe action writes a step summary (visible in the GitHub Actions UI) with one row per ref:
| Ref | Found | Deleted | Freed |
|---|---|---|---|
| feature/xyz | 12 | 12 | 2.3 MB |
| Total | 12 | 12 | 2.3 MB |
Repo cache usage: 4.1 GB / 10 GB
Notice: The repository cache limit may be higher, and usage data may be delayed.
In dry-run mode the table shows what would be deleted.
Build the action:
npm install
npm run buildThe dist/ output is committed by CI on main and must not be committed locally. A pre-commit hook blocks local dist commits; it is enabled automatically by npm install.
To enable the hook manually or after a fresh clone without install:
git config core.hooksPath .githooksSet ALLOW_DIST_COMMIT=true to force a manual dist commit.
MIT License © 2026 Friedinger