@@ -4,8 +4,8 @@ set -euo pipefail
44# Self-service S3 cache cleanup script.
55#
66# Two modes of operation:
7- # LIST MODE (no branch): Lists all cache entries for the repo, optionally filtered by key .
8- # DELETE MODE (branch provided): Deletes cache entries matching branch and optional key .
7+ # LIST MODE (no branch or key ): Lists all cache entries for the repo.
8+ # DELETE MODE (branch and/or key provided): Deletes matching cache entries .
99#
1010# The branch name in S3 varies by GitHub event type:
1111# - PR events use GITHUB_HEAD_REF (bare name, e.g., "feat/my-branch")
@@ -17,8 +17,9 @@ set -euo pipefail
1717# - GITHUB_REPOSITORY: Repository in org/repo format
1818#
1919# Optional environment variables:
20- # - CLEANUP_BRANCH: Branch name. If empty, runs in list mode .
20+ # - CLEANUP_BRANCH: Branch name to filter by .
2121# - CLEANUP_KEY: Cache key prefix to filter (e.g., "sccache-Linux-").
22+ # If both are empty, runs in list mode.
2223# - DRY_RUN: Set to "true" to preview deletions without executing them (delete mode only).
2324
2425# Escape a string for use in grep regex
@@ -43,16 +44,52 @@ format_size() {
4344 return 0
4445}
4546
46- # Print a formatted table of S3 objects (size, date, key)
47+ # Extract object rows as TSV: size_bytes \t date \t key (shared by print_table and write_summary)
48+ extract_rows () {
49+ local objects=" $1 "
50+ echo " $objects " | jq -r --arg prefix " $S3_PREFIX " \
51+ ' [.Size, (.LastModified | split("T") | .[0]), (.Key | ltrimstr($prefix))] | @tsv'
52+ return $?
53+ }
54+
55+ # Print a formatted table of S3 objects (size, date, key) to stdout
4756print_table () {
4857 local objects=" $1 "
4958 printf " %-8s %-20s %s\n" " SIZE" " LAST MODIFIED" " KEY"
5059 printf " %-8s %-20s %s\n" " --------" " --------------------" " ---"
51- echo " $objects " | jq -r --arg prefix " $S3_PREFIX " \
52- ' [.Size, (.LastModified | split("T") | .[0]), (.Key | ltrimstr($prefix))] | @tsv' | \
53- while IFS=$' \t ' read -r size date key; do
54- printf " %-8s %-20s %s\n" " $( format_size " $size " ) " " $date " " $key "
60+ extract_rows " $objects " | while IFS=$' \t ' read -r size date key; do
61+ printf " %-8s %-20s %s\n" " $( format_size " $size " ) " " $date " " $key "
62+ done
63+ return 0
64+ }
65+
66+ # Write GitHub Actions job summary (markdown with collapsible object list)
67+ write_summary () {
68+ local title=" $1 "
69+ local objects=" $2 "
70+ local count=" $3 "
71+ local total_size=" $4 "
72+
73+ if [[ -z " ${GITHUB_STEP_SUMMARY:- } " ]]; then
74+ return 0
75+ fi
76+
77+ {
78+ echo " ### $title "
79+ echo " "
80+ echo " **${count} object(s)**, $( format_size " $total_size " ) total"
81+ echo " "
82+ echo " <details>"
83+ echo " <summary>Show objects</summary>"
84+ echo " "
85+ echo " | Size | Last Modified | Key |"
86+ echo " |------|--------------|-----|"
87+ extract_rows " $objects " | while IFS=$' \t ' read -r size date key; do
88+ echo " | $( format_size " $size " ) | $date | $key |"
5589 done
90+ echo " "
91+ echo " </details>"
92+ } >> " $GITHUB_STEP_SUMMARY "
5693 return 0
5794}
5895
@@ -135,25 +172,28 @@ MATCH_COUNT=$(echo "$MATCHED_OBJECTS" | wc -l | tr -d ' ')
135172TOTAL_SIZE=$( echo " $MATCHED_OBJECTS " | jq -s ' [.[].Size] | add // 0' )
136173MATCHED_KEYS=$( echo " $MATCHED_OBJECTS " | jq -r ' .Key' )
137174
138- # --- List mode: display with details and exit ---
175+ # --- List mode: display with details and exit (only when no branch AND no key) ---
139176
140- if [[ -z " $INPUT_BRANCH " ]]; then
177+ if [[ -z " $INPUT_BRANCH " && -z " $KEY_PATTERN " ]]; then
141178 echo " "
142179 echo " === Cache entries for ${GITHUB_REPOSITORY} ==="
143180 echo " "
144181 print_table " $MATCHED_OBJECTS "
145182 echo " "
146183 echo " Total: ${MATCH_COUNT} object(s), $( format_size " $TOTAL_SIZE " ) "
184+ write_summary " Cache entries for ${GITHUB_REPOSITORY} " " $MATCHED_OBJECTS " " $MATCH_COUNT " " $TOTAL_SIZE "
147185 exit 0
148186fi
149187
150188# --- Phase 2: Delete matched objects ---
151189
152190echo " "
153- if [[ -n " $KEY_PATTERN " ]]; then
191+ if [[ -n " $INPUT_BRANCH " && -n " $ KEY_PATTERN" ]]; then
154192 echo " Matched ${MATCH_COUNT} object(s) for branch='${BARE_BRANCH:- $INPUT_BRANCH } ' key='${KEY_PATTERN} ' ($( format_size " $TOTAL_SIZE " ) )"
155- else
193+ elif [[ -n " $INPUT_BRANCH " ]] ; then
156194 echo " Matched ${MATCH_COUNT} object(s) for branch='${BARE_BRANCH:- $INPUT_BRANCH } ' ($( format_size " $TOTAL_SIZE " ) )"
195+ else
196+ echo " Matched ${MATCH_COUNT} object(s) for key='${KEY_PATTERN} ' across all branches ($( format_size " $TOTAL_SIZE " ) )"
157197fi
158198
159199if [[ " ${DRY_RUN:- false} " == " true" ]]; then
@@ -163,6 +203,7 @@ if [[ "${DRY_RUN:-false}" == "true" ]]; then
163203 print_table " $MATCHED_OBJECTS "
164204 echo " "
165205 echo " Total: ${MATCH_COUNT} object(s) would be deleted ($( format_size " $TOTAL_SIZE " ) )"
206+ write_summary " DRY RUN - objects that would be deleted" " $MATCHED_OBJECTS " " $MATCH_COUNT " " $TOTAL_SIZE "
166207 exit 0
167208fi
168209
206247
207248echo " "
208249echo " Cache cleanup completed. ${DELETED} object(s) deleted ($( format_size " $TOTAL_SIZE " ) )."
250+ write_summary " Deleted cache entries" " $MATCHED_OBJECTS " " $DELETED " " $TOTAL_SIZE "
0 commit comments