forked from SynoCommunity/spksrc
-
Notifications
You must be signed in to change notification settings - Fork 13
236 lines (207 loc) · 8.9 KB
/
distrib-cache-maintenance.yml
File metadata and controls
236 lines (207 loc) · 8.9 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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
name: Distrib Cache Maintenance
on:
# Regular refresh to prevent GitHub's 7-day eviction policy
schedule:
- cron: '0 4 * * 1,4' # Monday and Thursday at 4 AM
workflow_dispatch:
inputs:
max_age_days:
description: 'Maximum age of files to keep (days)'
required: false
default: '180'
type: string
dry_run:
description: 'Dry run mode (no deletions)'
required: false
default: false
type: boolean
jobs:
maintain-distrib-cache:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Restore distrib cache
id: cache-restore
uses: actions/cache/restore@v5
with:
path: distrib
# Use a placeholder key that will never match for the exact key,
# forcing GitHub to use restore-keys to find the best available cache
key: distrib-placeholder-${{ github.run_id }}
restore-keys: |
distrib-
- name: Display cache status
run: |
if [ "${{ steps.cache-restore.outputs.cache-hit }}" = "true" ]; then
echo "Cache restored successfully"
else
echo "No cache found or partial restore"
fi
echo ""
echo "Current distrib cache status:"
if [ -d "distrib" ]; then
FILE_COUNT=$(find distrib -type f | wc -l)
TOTAL_SIZE=$(du -sh distrib 2>/dev/null | cut -f1 || echo "0")
echo " Files: $FILE_COUNT"
echo " Size: $TOTAL_SIZE"
else
echo " (empty)"
mkdir -p distrib
fi
- name: Clean old files from distrib
env:
MAX_AGE_DAYS: ${{ github.event.inputs.max_age_days || '180' }}
DRY_RUN: ${{ github.event.inputs.dry_run || 'false' }}
run: |
echo "Cleaning files older than $MAX_AGE_DAYS days"
echo ""
if [ ! -d "distrib" ] || [ -z "$(ls -A distrib 2>/dev/null)" ]; then
echo "Distrib cache is empty, nothing to clean"
exit 0
fi
# Remove corrupted/invalid files marked as .wrong by checksum verification
WRONG_FILES=$(find distrib -type f -name "*.wrong" 2>/dev/null || true)
if [ -n "$WRONG_FILES" ]; then
WRONG_COUNT=$(echo "$WRONG_FILES" | wc -l)
echo "Found $WRONG_COUNT corrupted file(s) marked as .wrong"
if [ "$DRY_RUN" = "true" ]; then
echo "[DRY RUN] Would delete $WRONG_COUNT .wrong file(s)"
echo "Sample files (first 5):"
echo "$WRONG_FILES" | head -5
else
echo "$WRONG_FILES" | xargs rm -f
echo "Deleted $WRONG_COUNT .wrong file(s)"
fi
echo ""
fi
# Find files not modified for more than MAX_AGE_DAYS
OLD_FILES=$(find distrib -type f -mtime +${MAX_AGE_DAYS} 2>/dev/null || true)
if [ -z "$OLD_FILES" ]; then
echo "No obsolete files found"
exit 0
fi
OLD_COUNT=$(echo "$OLD_FILES" | wc -l)
OLD_SIZE=$(echo "$OLD_FILES" | xargs du -ch 2>/dev/null | tail -1 | cut -f1 || echo "0")
echo "Obsolete files found: $OLD_COUNT ($OLD_SIZE)"
echo ""
if [ "$DRY_RUN" = "true" ]; then
echo "[DRY RUN] Files that would be deleted:"
echo "Sample files (first 10):"
echo "$OLD_FILES" | head -10
if [ "$OLD_COUNT" -gt 10 ]; then
echo " ... and $((OLD_COUNT - 10)) more"
fi
else
echo "Deleting files..."
echo "$OLD_FILES" | xargs rm -f
# Clean empty directories
find distrib -type d -empty -delete 2>/dev/null || true
echo "$OLD_COUNT files deleted ($OLD_SIZE freed)"
fi
- name: Report final status
run: |
echo ""
echo "Final distrib cache status:"
if [ -d "distrib" ]; then
FILE_COUNT=$(find distrib -type f | wc -l)
TOTAL_SIZE=$(du -sh distrib 2>/dev/null | cut -f1 || echo "0")
TOTAL_BYTES=$(du -sb distrib 2>/dev/null | cut -f1 || echo "0")
echo " Files: $FILE_COUNT"
echo " Size: $TOTAL_SIZE"
echo ""
echo "Distribution by file type:"
find distrib -type f -name "*.tar.gz" | wc -l | xargs -I{} echo " .tar.gz: {}"
find distrib -type f -name "*.tar.xz" | wc -l | xargs -I{} echo " .tar.xz: {}"
find distrib -type f -name "*.tar.bz2" | wc -l | xargs -I{} echo " .tar.bz2: {}"
find distrib -type f -name "*.zip" | wc -l | xargs -I{} echo " .zip: {}"
find distrib -type f -name "*.whl" | wc -l | xargs -I{} echo " .whl: {}"
echo ""
echo "File age distribution:"
find distrib -type f -mtime -7 | wc -l | xargs -I{} echo " < 7 days: {}"
find distrib -type f -mtime +7 -mtime -30 | wc -l | xargs -I{} echo " 7-30 days: {}"
find distrib -type f -mtime +30 -mtime -90 | wc -l | xargs -I{} echo " 30-90 days: {}"
find distrib -type f -mtime +90 -mtime -180 | wc -l | xargs -I{} echo " 90-180 days: {}"
find distrib -type f -mtime +180 | wc -l | xargs -I{} echo " > 180 days: {}"
# Alert if cache size exceeds 2GB (considering other active caches in the repository)
echo ""
LIMIT_BYTES=2147483648
if [ "$TOTAL_BYTES" -gt "$LIMIT_BYTES" ]; then
echo "WARNING: Distrib cache size exceeds 2GB. Consider reducing max_age_days parameter."
else
echo "Cache size is within acceptable limits."
fi
else
echo " (empty)"
fi
- name: Compute distrib hash
id: distrib-hash
run: |
# Compute a hash based on file paths and sizes (not content) for performance.
# This is fast even with thousands of files since we don't read file contents.
# Format: "path size" per line, sorted for reproducibility, then hashed.
if [ -d "distrib" ] && [ -n "$(ls -A distrib 2>/dev/null)" ]; then
HASH=$(find distrib -type f -printf '%p %s\n' | sort | sha256sum | cut -d' ' -f1)
else
HASH="empty"
fi
echo "hash=$HASH" >> $GITHUB_OUTPUT
echo "Distrib cache hash: $HASH"
- name: Check if cache already exists
id: cache-check
run: |
# Check if a cache with this exact hash already exists to avoid duplication
CACHE_KEY="distrib-${{ steps.distrib-hash.outputs.hash }}"
if gh cache list --json key | jq -e --arg key "$CACHE_KEY" '.[] | select(.key == $key)' > /dev/null 2>&1; then
echo "Cache with key $CACHE_KEY already exists, skipping save"
echo "save_cache=false" >> $GITHUB_OUTPUT
else
echo "New cache content detected, will save with key: $CACHE_KEY"
echo "save_cache=true" >> $GITHUB_OUTPUT
fi
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Save refreshed cache
if: steps.cache-check.outputs.save_cache == 'true'
uses: actions/cache/save@v5
with:
path: distrib
key: distrib-${{ steps.distrib-hash.outputs.hash }}
cleanup-stale-caches:
runs-on: ubuntu-latest
needs: maintain-distrib-cache
permissions:
actions: write
steps:
- name: Cleanup old GitHub cache entries
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
echo "Cleaning up old GitHub cache entries"
# List all distrib caches with available fields
# Note: Only targets caches with keys starting with "distrib-"
# Other caches (e.g., toolchain-*) are not affected
ALL_CACHES=$(gh cache list --key "distrib-" --limit 100 --json key 2>/dev/null || true)
if [ -z "$ALL_CACHES" ] || [ "$ALL_CACHES" = "[]" ]; then
echo "No caches found"
exit 0
fi
# Count total caches
CACHE_COUNT=$(echo "$ALL_CACHES" | jq 'length')
echo "Found $CACHE_COUNT distrib caches"
# Keep 10 most recent, delete the remaining
# Keeping more during transition period to accommodate both old and new cache formats.
if [ "$CACHE_COUNT" -le 10 ]; then
echo "10 or fewer caches exist, nothing to delete based on count"
else
CACHES_TO_DELETE=$(echo "$ALL_CACHES" | jq -r '.[10:] | .[].key' 2>/dev/null || true)
if [ -n "$CACHES_TO_DELETE" ]; then
echo "Deleting old caches (keeping 10 most recent):"
for key in $CACHES_TO_DELETE; do
echo " Deleting: $key"
gh cache delete "$key" --confirm 2>/dev/null || true
done
fi
fi
echo ""
echo "Cleanup completed"