Skip to content

Commit 6ea5205

Browse files
authored
Add workflow to clean up old action runs and artifacts
This workflow automates the cleanup of old GitHub Actions runs, artifacts, and caches, keeping only the specified number of each type.
1 parent 9ccd087 commit 6ea5205

1 file changed

Lines changed: 74 additions & 0 deletions

File tree

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
name: Cleanup Actions runs and artifacts
2+
3+
on:
4+
workflow_dispatch:
5+
6+
permissions:
7+
actions: write
8+
contents: read
9+
10+
jobs:
11+
cleanup:
12+
runs-on: ubuntu-latest
13+
steps:
14+
- uses: actions/github-script@v7
15+
with:
16+
script: |
17+
const KEEP_RUNS = 10
18+
const KEEP_ARTIFACTS = 10
19+
const KEEP_CACHES = 10
20+
21+
core.info('Fetching workflow runs...')
22+
const runs = await github.paginate(
23+
github.rest.actions.listWorkflowRunsForRepo,
24+
{ owner: context.repo.owner, repo: context.repo.repo, per_page: 100 }
25+
)
26+
27+
core.info(`Total runs: ${runs.length}`)
28+
core.info(`Keeping newest ${KEEP_RUNS}, deleting ${Math.max(runs.length - KEEP_RUNS, 0)}`)
29+
30+
for (const [i, run] of runs.slice(KEEP_RUNS).entries()) {
31+
core.info(`Deleting run ${i + 1}/${runs.length - KEEP_RUNS} (id=${run.id})`)
32+
await github.rest.actions.deleteWorkflowRun({
33+
owner: context.repo.owner,
34+
repo: context.repo.repo,
35+
run_id: run.id,
36+
})
37+
}
38+
39+
core.info('Fetching artifacts...')
40+
const artifacts = await github.paginate(
41+
github.rest.actions.listArtifactsForRepo,
42+
{ owner: context.repo.owner, repo: context.repo.repo, per_page: 100 }
43+
)
44+
45+
core.info(`Total artifacts: ${artifacts.length}`)
46+
core.info(`Keeping newest ${KEEP_ARTIFACTS}, deleting ${Math.max(artifacts.length - KEEP_ARTIFACTS, 0)}`)
47+
48+
for (const [i, artifact] of artifacts.slice(KEEP_ARTIFACTS).entries()) {
49+
core.info(`Deleting artifact ${i + 1}/${artifacts.length - KEEP_ARTIFACTS} (id=${artifact.id})`)
50+
await github.rest.actions.deleteArtifact({
51+
owner: context.repo.owner,
52+
repo: context.repo.repo,
53+
artifact_id: artifact.id,
54+
})
55+
}
56+
57+
core.info('Fetching caches...')
58+
const caches = await github.paginate(
59+
github.rest.actions.getActionsCacheList,
60+
{ owner: context.repo.owner, repo: context.repo.repo, per_page: 100 }
61+
)
62+
63+
core.info(`Total caches: ${caches.length}`)
64+
core.info(`Keeping newest ${KEEP_CACHES}, deleting ${Math.max(caches.length - KEEP_CACHES, 0)}`)
65+
66+
for (const [i, cache] of caches.slice(KEEP_CACHES).entries()) {
67+
core.info(`Deleting cache ${i + 1}/${caches.length - KEEP_CACHES} (id=${cache.id})`)
68+
await github.rest.actions.deleteActionsCacheById({
69+
owner: context.repo.owner,
70+
repo: context.repo.repo,
71+
cache_id: cache.id,
72+
})
73+
}
74+
core.info('Cleanup complete')

0 commit comments

Comments
 (0)