From 4d582e62eb2e049f0ca00946afe180ea44aded31 Mon Sep 17 00:00:00 2001 From: opsx Date: Sat, 31 Oct 2026 18:12:46 +0000 Subject: [PATCH] =?UTF-8?q?fix(release):=20digest=20=E6=A0=A1=E9=AA=8C?= =?UTF-8?q?=E6=94=B9=E4=B8=BA=E8=BD=AE=E8=AF=A2=EF=BC=8C=E9=81=BF=E5=85=8D?= =?UTF-8?q?=20Docker=20Hub=20=E4=BC=A0=E6=92=AD=E5=BB=B6=E8=BF=9F=E5=AF=BC?= =?UTF-8?q?=E8=87=B4=E8=AF=AF=E5=88=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 现象:刚 push 完立刻查 tags API,latest 已是新 digest 而 v0.1 还是旧值, 脚本按"三个 tag 不一致 = 并发覆盖"直接 exit 1,把正常发布拦下来了。 根因:Docker Hub 的 /v2/repositories//tags/ 有秒级~十几秒的 传播延迟,单次查询不能作为判据。 修复:轮询最多 12 次、每次间隔 5 秒(共 60 秒),三者一致才继续; 超时仍不一致则 exit 1,并在报错里区分两种可能: - latest 与 v0.1 不同 → 疑似并发构建覆盖(提示检查 flock 是否被绕过) - 仍为 "?" → 推送根本没成功或仓库不可达 本次实测:第 1 次轮询发现未同步,等待 5 秒后三者均为 1ce3d4166506 ✅ 顺带:不可变 tag 之前出现 -dirty 后缀,是因为改完脚本没提交就发版; 本次先提交再发版,tag 恢复干净(2.0.0-20261031-)。 --- scripts/release.sh | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/scripts/release.sh b/scripts/release.sh index 5cdf35b..52c6676 100755 --- a/scripts/release.sh +++ b/scripts/release.sh @@ -130,14 +130,30 @@ digest_of() { | python3 -c 'import sys,json;print(json.load(sys.stdin).get("digest","?"))' 2>/dev/null \ || echo "?" } -D_LATEST=$(digest_of latest) -D_V01=$(digest_of v0.1) -D_IMM=$(digest_of "${IMMUTABLE_TAG}") +# Docker Hub 的 tags API 有传播延迟:刚 push 完立刻查,常常还是旧 digest。 +# 实测遇到过 latest 已是新值、v0.1 还停在旧值,如果只查一次就会误判成 +# "并发覆盖"并拒绝部署。所以轮询到三者一致为止(最多 60 秒)。 +DIGEST_ATTEMPTS=12 +DIGEST_SLEEP=5 +for attempt in $(seq 1 ${DIGEST_ATTEMPTS}); do + D_LATEST=$(digest_of latest) + D_V01=$(digest_of v0.1) + D_IMM=$(digest_of "${IMMUTABLE_TAG}") + if [ "${D_LATEST:0:19}" = "${D_V01:0:19}" ] && [ "${D_LATEST:0:19}" = "${D_IMM:0:19}" ] \ + && [ "${D_LATEST:0:19}" != "?" ]; then + break + fi + if [ "${attempt}" -lt "${DIGEST_ATTEMPTS}" ]; then + echo " ⏳ 远端 digest 尚未同步(第 ${attempt}/${DIGEST_ATTEMPTS} 次),${DIGEST_SLEEP}s 后重试…" + sleep ${DIGEST_SLEEP} + fi +done echo " latest : ${D_LATEST:0:19}" echo " v0.1 : ${D_V01:0:19}" echo " ${IMMUTABLE_TAG}: ${D_IMM:0:19}" if [ "${D_LATEST:0:19}" != "${D_V01:0:19}" ] || [ "${D_LATEST:0:19}" != "${D_IMM:0:19}" ]; then - echo "❌ 三个 tag digest 不一致,先别继续部署(可能是并发构建覆盖了 latest)" + echo "❌ 三个 tag digest 不一致(已等待 $((DIGEST_ATTEMPTS * DIGEST_SLEEP)) 秒)" + echo " 若 latest 与 v0.1 不同:可能是并发构建覆盖了 latest(检查 flock 锁是否被绕过)" exit 1 fi echo " → 一致 ✅"