-
Notifications
You must be signed in to change notification settings - Fork 433
153 lines (129 loc) · 5.37 KB
/
cleanup-caches.yml
File metadata and controls
153 lines (129 loc) · 5.37 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
name: Cleanup github runner caches
on:
# pull_request_target is required so fork PRs can delete their own caches on close.
# pull_request from a fork ships a read-only GITHUB_TOKEN regardless of the
# permissions: block, causing gh cache delete to fail with HTTP 403.
# Safe here: no PR code is checked out, the workflow only calls gh cache list/delete.
pull_request_target:
types:
- closed
# Daily cleanup of stale julia caches on long-lived branches. julia-actions/cache@v3
# does not run delete-old-caches on the default branch (by design, to avoid races
# between concurrent runs), so caches accumulate. This job keeps only the newest
# cache per (workflow, os) tuple.
schedule:
- cron: "0 4 * * *"
workflow_dispatch:
jobs:
cleanup-pr:
if: github.event_name == 'pull_request_target'
runs-on: ubuntu-latest
permissions:
actions: write
steps:
- name: Cleanup
run: |
echo "::group::Fetching cache list for PR #${{ github.event.pull_request.number }}"
echo "Branch ref: $BRANCH"
# Get full cache list with details for logging
cacheList=$(gh cache list --ref $BRANCH --limit 100 --json id,key,sizeInBytes)
cacheCount=$(echo "$cacheList" | jq '. | length')
echo "Found $cacheCount cache(s) for this PR"
if [ "$cacheCount" -gt 0 ]; then
echo "Cache details:"
echo "$cacheList" | jq -r '.[] | " - ID: \(.id) | Key: \(.key) | Size: \(.sizeInBytes | tonumber / 1024 / 1024 | floor)MB"'
fi
echo "::endgroup::"
if [ "$cacheCount" -eq 0 ]; then
echo "No caches to delete"
exit 0
fi
# Extract just the IDs for deletion
cacheKeysForPR=$(echo "$cacheList" | jq -r '.[].id')
## Setting this to not fail the workflow while deleting cache keys.
set +e
echo "::group::Deleting caches"
deleted=0
failed=0
for cacheKey in $cacheKeysForPR
do
echo "Deleting cache ID: $cacheKey"
if gh cache delete $cacheKey; then
echo " ✓ Successfully deleted cache $cacheKey"
((deleted++))
else
echo " ✗ Failed to delete cache $cacheKey"
((failed++))
fi
done
echo "::endgroup::"
echo "::notice::Cache cleanup complete: $deleted deleted, $failed failed out of $cacheCount total"
env:
GH_TOKEN: ${{ github.token }}
GH_REPO: ${{ github.repository }}
BRANCH: refs/pull/${{ github.event.pull_request.number }}/merge
cleanup-branches:
if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'
runs-on: ubuntu-latest
permissions:
actions: write
strategy:
fail-fast: false
matrix:
ref:
- refs/heads/main
- refs/heads/v1.9
steps:
- name: Cleanup stale julia caches on ${{ matrix.ref }}
run: |
echo "::group::Julia cache list for $REF"
# Filter at source with --key (prefix match) so non-julia caches
# don't push stale julia entries past the --limit window.
caches=$(gh cache list --ref "$REF" --key julia-cache --limit 100 --json id,key,createdAt,sizeInBytes)
total=$(echo "$caches" | jq 'length')
echo "Found $total julia cache(s) on $REF"
if [ "$total" -eq 0 ]; then
echo "::endgroup::"
echo "::notice::No julia caches on $REF"
exit 0
fi
# Group key is the cache key with run_id=... onwards stripped.
# Sort by createdAt descending so the newest cache per group comes first;
# awk keeps the first occurrence of each group (newest) and prints the rest.
toDelete=$(echo "$caches" \
| jq -r '.[] | "\(.createdAt)|\(.id)|\(.sizeInBytes)|\(.key | split(";run_id=") | .[0])"' \
| sort -r \
| awk -F'|' 'seen[$4]++ { print $2 "|" $3 "|" $4 }')
deleteCount=$(echo "$toDelete" | grep -c '|' || true)
keepCount=$((total - deleteCount))
echo "Will delete $deleteCount stale cache(s), keep $keepCount newest per (workflow, os)"
echo "::endgroup::"
if [ "$deleteCount" -eq 0 ]; then
echo "::notice::Nothing to delete on $REF - all caches are already the newest per (workflow, os)"
exit 0
fi
## Do not fail the workflow on a single delete error.
set +e
echo "::group::Deleting stale caches"
deleted=0
failed=0
freedMb=0
while IFS='|' read -r id size group; do
[ -z "$id" ] && continue
mb=$((size / 1024 / 1024))
echo "Deleting cache $id (${mb}MB) - group: $group"
if gh cache delete "$id"; then
echo " ✓ deleted"
deleted=$((deleted + 1))
freedMb=$((freedMb + mb))
else
echo " ✗ failed"
failed=$((failed + 1))
fi
done <<< "$toDelete"
echo "::endgroup::"
echo "::notice::Cleanup complete on $REF: $deleted deleted (${freedMb}MB freed), $failed failed"
env:
GH_TOKEN: ${{ github.token }}
GH_REPO: ${{ github.repository }}
REF: ${{ matrix.ref }}