Skip to content

Commit c2a62d3

Browse files
torykitclaude
andcommitted
ci(r2): 清理 workflow 加 artifact 报告与删除后自校验
CI 日志在本地代理环境读不到真实内容,改为把分类报告/totals/待删前缀写成 artifact 上传,并写 job summary。delete 后统计残留 -beta key,>0 即 exit 1, 用 job 成败作为可靠信号。delete 列表里出现非 beta 前缀直接 ABORT。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent c472c2f commit c2a62d3

1 file changed

Lines changed: 74 additions & 54 deletions

File tree

Lines changed: 74 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
11
name: R2 cleanup (purge beta builds)
22

33
# 一次性运维:清掉 Cloudflare R2 (bucket: openspeech) 里所有 beta 版本的二进制归档
4-
#顶层前缀 v*-beta*/),保留全部正式版归档与顶层滚动 manifest(latest*.json /
5-
# download*.json)。复用 release.yml 同一套 R2_* secrets。
4+
#首段前缀含 -beta,如 v0.2.49-beta.6/),保留全部正式版归档与顶层滚动 manifest
5+
# (latest*.json / download*.json)。复用 release.yml 同一套 R2_* secrets。
66
#
7-
# 用法:Actions → 本 workflow → Run workflow
8-
# 1. 先用 mode=dry-run 跑一次,看 step 日志里的「将删除」清单与体积;
9-
# 2. 确认无误后再用 mode=delete 跑一次真删。
10-
#
11-
# 安全:delete step 对每个待删前缀二次校验必须含 `-beta` 才执行 rm,正式版与
12-
# 顶层 manifest 永不进入删除列表。
7+
# 分组不依赖 S3 delimiter/CommonPrefixes(R2 上为空),而是 aws s3 ls --recursive 拉全部
8+
# key 后按首段路径聚合。报告写成 artifact(report.txt / beta_prefixes.txt / totals.txt)。
9+
# delete step 对每个待删前缀二次校验必须含 -beta;删完自校验,若仍有 -beta key 残留则 exit 1。
1310

1411
on:
1512
workflow_dispatch:
@@ -37,81 +34,104 @@ jobs:
3734
R2_BUCKET: ${{ secrets.R2_BUCKET }}
3835
MODE: ${{ inputs.mode }}
3936
steps:
40-
- name: List & classify top-level prefixes
37+
- name: List & classify objects
4138
run: |
4239
set -euo pipefail
4340
echo "Mode: $MODE | Bucket: $R2_BUCKET"
44-
echo
4541
46-
echo "=== 顶层对象(manifest 等,保留)==="
47-
aws s3api list-objects-v2 --bucket "$R2_BUCKET" --delimiter / \
48-
--query 'Contents[].Key' --output text 2>/dev/null \
49-
| tr '\t' '\n' | grep -v -e '^$' -e '^None$' || true
50-
echo
42+
aws s3 ls "s3://$R2_BUCKET" --recursive > all_objects.txt
43+
total_all=$(wc -l < all_objects.txt)
5144
52-
echo "=== 顶层前缀分类 ==="
53-
prefixes=$(aws s3api list-objects-v2 --bucket "$R2_BUCKET" --delimiter / \
54-
--query 'CommonPrefixes[].Prefix' --output text 2>/dev/null \
55-
| tr '\t' '\n' | grep -v -e '^$' -e '^None$' || true)
45+
# 按 key 首段路径聚合;不含 / 的顶层文件归到 (root)
46+
awk '{
47+
key=$4; size=$3;
48+
n=index(key,"/");
49+
grp=(n>0)?substr(key,1,n-1):"(root)";
50+
objs[grp]++; bytes[grp]+=size;
51+
} END { for (g in objs) printf "%s\t%d\t%d\n", g, objs[g], bytes[g] }' \
52+
all_objects.txt | sort > groups.txt
5653
5754
: > beta_prefixes.txt
58-
total_del_objs=0
59-
total_del_bytes=0
60-
beta_count=0
61-
for p in $prefixes; do
62-
summ=$(aws s3 ls "s3://$R2_BUCKET/$p" --recursive --summarize 2>/dev/null | tail -2 || true)
63-
objs=$(printf '%s\n' "$summ" | awk '/Total Objects/{print $NF}')
64-
bytes=$(printf '%s\n' "$summ" | awk '/Total Size/{print $NF}')
65-
objs=${objs:-0}; bytes=${bytes:-0}
66-
if [[ "$p" == *-beta* ]]; then
67-
printf '%-32s objs=%-4s bytes=%-13s [BETA → 将删]\n' "$p" "$objs" "$bytes"
68-
echo "$p" >> beta_prefixes.txt
69-
total_del_objs=$((total_del_objs + objs))
70-
total_del_bytes=$((total_del_bytes + bytes))
71-
beta_count=$((beta_count + 1))
55+
: > report.txt
56+
del_objs=0; del_bytes=0; beta_count=0; keep_objs=0; keep_bytes=0
57+
while IFS=$'\t' read -r g o b; do
58+
if [[ "$g" == *-beta* ]]; then
59+
printf '%-34s objs=%-4s bytes=%s [BETA -> DELETE]\n' "$g" "$o" "$b" >> report.txt
60+
echo "$g/" >> beta_prefixes.txt
61+
del_objs=$((del_objs+o)); del_bytes=$((del_bytes+b)); beta_count=$((beta_count+1))
7262
else
73-
printf '%-32s objs=%-4s bytes=%-13s [STABLE → 保留]\n' "$p" "$objs" "$bytes"
63+
printf '%-34s objs=%-4s bytes=%s [KEEP]\n' "$g" "$o" "$b" >> report.txt
64+
keep_objs=$((keep_objs+o)); keep_bytes=$((keep_bytes+b))
7465
fi
75-
done
66+
done < groups.txt
7667
77-
echo
78-
human=$(awk -v b="$total_del_bytes" 'BEGIN{printf "%.2f GiB", b/1073741824}')
79-
echo "=== 将删除 ${total_del_objs} 个对象 / ${total_del_bytes} 字节 (${human}),覆盖 ${beta_count} 个 beta 前缀 ==="
80-
echo
81-
if [[ "$MODE" == "dry-run" ]]; then
82-
echo "★ 当前 dry-run,未删除任何对象。确认清单后用 mode=delete 重新触发。"
83-
fi
68+
{
69+
echo "total_all_objects=$total_all"
70+
echo "beta_prefix_count=$beta_count"
71+
echo "delete_objects=$del_objs"
72+
echo "delete_bytes=$del_bytes"
73+
echo "keep_objects=$keep_objs"
74+
echo "keep_bytes=$keep_bytes"
75+
} > totals.txt
76+
77+
# job summary(Actions 页可视)
78+
{
79+
echo "## R2 cleanup ($MODE)"
80+
echo '```'
81+
cat totals.txt
82+
echo '```'
83+
echo "### prefixes"
84+
echo '```'
85+
cat report.txt
86+
echo '```'
87+
} >> "$GITHUB_STEP_SUMMARY"
88+
89+
cat totals.txt
90+
91+
- name: Upload report artifact
92+
uses: actions/upload-artifact@v4
93+
with:
94+
name: r2-cleanup-report
95+
path: |
96+
report.txt
97+
beta_prefixes.txt
98+
totals.txt
99+
retention-days: 7
84100

85101
- name: Delete beta prefixes
86102
if: ${{ inputs.mode == 'delete' }}
87103
run: |
88104
set -euo pipefail
89105
if [[ ! -s beta_prefixes.txt ]]; then
90-
echo "没有 beta 前缀可删,结束。"
106+
echo "No beta prefixes to delete."
91107
exit 0
92108
fi
93109
while IFS= read -r p; do
94110
[[ -z "$p" ]] && continue
95111
case "$p" in
96112
*-beta*) ;;
97-
*) echo "跳过非 beta 前缀(不应出现): $p"; continue ;;
113+
*) echo "ABORT: non-beta prefix in delete list: $p"; exit 1 ;;
98114
esac
99-
echo ">>> 删除 s3://$R2_BUCKET/$p"
115+
echo ">>> deleting s3://$R2_BUCKET/$p"
100116
aws s3 rm "s3://$R2_BUCKET/$p" --recursive --only-show-errors
101117
done < beta_prefixes.txt
102-
echo "删除完成。"
118+
echo "Delete done."
103119
104120
- name: Verify after delete
105121
if: ${{ inputs.mode == 'delete' }}
106122
run: |
107123
set -euo pipefail
108-
echo "=== 删除后剩余顶层前缀 ==="
109-
aws s3api list-objects-v2 --bucket "$R2_BUCKET" --delimiter / \
110-
--query 'CommonPrefixes[].Prefix' --output text 2>/dev/null \
111-
| tr '\t' '\n' | grep -v -e '^$' -e '^None$' || true
112-
echo
113-
echo "=== 桶总用量 ==="
124+
remaining=$(aws s3 ls "s3://$R2_BUCKET" --recursive | awk '{print $4}' | grep -c -- '-beta' || true)
114125
summ=$(aws s3 ls "s3://$R2_BUCKET" --recursive --summarize | tail -2)
115-
echo "$summ"
116126
bytes=$(printf '%s\n' "$summ" | awk '/Total Size/{print $NF}')
117-
awk -v b="${bytes:-0}" 'BEGIN{printf "总计 %.2f GiB\n", b/1073741824}'
127+
{
128+
echo "## R2 cleanup verify"
129+
echo "remaining_beta_keys=$remaining"
130+
echo "bucket_total_bytes=${bytes:-0}"
131+
} >> "$GITHUB_STEP_SUMMARY"
132+
echo "remaining_beta_keys=$remaining"
133+
echo "bucket_total_bytes=${bytes:-0}"
134+
if [[ "$remaining" -ne 0 ]]; then
135+
echo "ERROR: still $remaining beta keys left"; exit 1
136+
fi
137+
echo "OK: no beta keys remain."

0 commit comments

Comments
 (0)