1+ name : Cache Cleanup
2+
3+ on :
4+ schedule :
5+ # Run every Sunday at 2 AM UTC
6+ - cron : ' 0 2 * * 0'
7+ workflow_dispatch :
8+ inputs :
9+ max_age_days :
10+ description : ' Maximum age of caches to keep (in days)'
11+ required : false
12+ default : ' 30'
13+ type : string
14+
15+ jobs :
16+ cleanup :
17+ name : Clean up old caches
18+ runs-on : ubuntu-latest
19+ permissions :
20+ actions : write
21+ contents : read
22+
23+ steps :
24+ - name : Checkout code
25+ uses : actions/checkout@v4
26+
27+ - name : Get cache cleanup parameters
28+ id : params
29+ run : |
30+ MAX_AGE_DAYS="${{ github.event.inputs.max_age_days || '30' }}"
31+ echo "max_age_days=${MAX_AGE_DAYS}" >> $GITHUB_OUTPUT
32+ echo "cleanup_date=$(date -d "${MAX_AGE_DAYS} days ago" '+%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_OUTPUT
33+
34+ - name : List current caches
35+ run : |
36+ echo "Current caches in repository:"
37+ gh api \
38+ -H "Accept: application/vnd.github+json" \
39+ -H "X-GitHub-Api-Version: 2022-11-28" \
40+ "/repos/${{ github.repository }}/actions/caches" \
41+ --jq '.actions_caches[] | "\(.key) - \(.size_in_bytes) bytes - \(.created_at)"'
42+ env :
43+ GH_TOKEN : ${{ github.token }}
44+
45+ - name : Clean up old caches
46+ run : |
47+ echo "Cleaning up caches older than ${{ steps.params.outputs.cleanup_date }}"
48+
49+ # Get list of cache IDs older than specified date
50+ CACHE_IDS=$(gh api \
51+ -H "Accept: application/vnd.github+json" \
52+ -H "X-GitHub-Api-Version: 2022-11-28" \
53+ "/repos/${{ github.repository }}/actions/caches" \
54+ --jq --arg cleanup_date "${{ steps.params.outputs.cleanup_date }}" \
55+ '.actions_caches[] | select(.created_at < $cleanup_date) | .id')
56+
57+ if [ -z "$CACHE_IDS" ]; then
58+ echo "No old caches found to clean up"
59+ exit 0
60+ fi
61+
62+ echo "Found caches to delete:"
63+ echo "$CACHE_IDS"
64+
65+ # Delete each cache
66+ for cache_id in $CACHE_IDS; do
67+ echo "Deleting cache ID: $cache_id"
68+ gh api \
69+ -X DELETE \
70+ -H "Accept: application/vnd.github+json" \
71+ -H "X-GitHub-Api-Version: 2022-11-28" \
72+ "/repos/${{ github.repository }}/actions/caches/$cache_id" || true
73+ done
74+ env :
75+ GH_TOKEN : ${{ github.token }}
76+
77+ - name : Clean up caches from deleted branches
78+ run : |
79+ echo "Cleaning up caches from non-existent branches"
80+
81+ # Get all remote branches
82+ git fetch --all
83+ EXISTING_BRANCHES=$(git branch -r | sed 's/origin\///' | grep -v HEAD | tr -d ' ')
84+
85+ # Get all cache keys
86+ CACHE_KEYS=$(gh api \
87+ -H "Accept: application/vnd.github+json" \
88+ -H "X-GitHub-Api-Version: 2022-11-28" \
89+ "/repos/${{ github.repository }}/actions/caches" \
90+ --jq '.actions_caches[] | .key')
91+
92+ # Find caches that might be from deleted branches
93+ for cache_key in $CACHE_KEYS; do
94+ # Extract potential branch name from cache key (this is heuristic)
95+ # Cache keys often contain branch names or refs
96+ if [[ "$cache_key" == *"refs/heads/"* ]]; then
97+ BRANCH_IN_KEY=$(echo "$cache_key" | sed -n 's/.*refs\/heads\/\([^-]*\).*/\1/p')
98+ if [ -n "$BRANCH_IN_KEY" ] && ! echo "$EXISTING_BRANCHES" | grep -q "^$BRANCH_IN_KEY$"; then
99+ echo "Found cache from potentially deleted branch: $cache_key (branch: $BRANCH_IN_KEY)"
100+
101+ # Get cache ID and delete
102+ CACHE_ID=$(gh api \
103+ -H "Accept: application/vnd.github+json" \
104+ -H "X-GitHub-Api-Version: 2022-11-28" \
105+ "/repos/${{ github.repository }}/actions/caches" \
106+ --jq --arg key "$cache_key" \
107+ '.actions_caches[] | select(.key == $key) | .id')
108+
109+ if [ -n "$CACHE_ID" ]; then
110+ echo "Deleting cache ID: $CACHE_ID"
111+ gh api \
112+ -X DELETE \
113+ -H "Accept: application/vnd.github+json" \
114+ -H "X-GitHub-Api-Version: 2022-11-28" \
115+ "/repos/${{ github.repository }}/actions/caches/$CACHE_ID" || true
116+ fi
117+ fi
118+ fi
119+ done
120+ env :
121+ GH_TOKEN : ${{ github.token }}
122+
123+ - name : Show cache statistics after cleanup
124+ run : |
125+ echo "Cache statistics after cleanup:"
126+ CACHE_INFO=$(gh api \
127+ -H "Accept: application/vnd.github+json" \
128+ -H "X-GitHub-Api-Version: 2022-11-28" \
129+ "/repos/${{ github.repository }}/actions/caches")
130+
131+ CACHE_COUNT=$(echo "$CACHE_INFO" | jq '.actions_caches | length')
132+ TOTAL_SIZE=$(echo "$CACHE_INFO" | jq '.actions_caches | map(.size_in_bytes) | add // 0')
133+ TOTAL_SIZE_MB=$((TOTAL_SIZE / 1024 / 1024))
134+
135+ echo "Total caches: $CACHE_COUNT"
136+ echo "Total size: ${TOTAL_SIZE_MB} MB"
137+ echo "Remaining caches:"
138+ echo "$CACHE_INFO" | jq '.actions_caches[] | "\(.key) - \(.size_in_bytes) bytes - \(.created_at)"'
139+ env :
140+ GH_TOKEN : ${{ github.token }}
0 commit comments