fix(release): digest 校验改为轮询,避免 Docker Hub 传播延迟导致误判
CI / Backend (go vet + test) (push) Waiting to run
CI / Frontend (lint + build + test) (push) Waiting to run

现象:刚 push 完立刻查 tags API,latest 已是新 digest 而 v0.1 还是旧值,
脚本按"三个 tag 不一致 = 并发覆盖"直接 exit 1,把正常发布拦下来了。

根因:Docker Hub 的 /v2/repositories/<repo>/tags/<tag> 有秒级~十几秒的
传播延迟,单次查询不能作为判据。

修复:轮询最多 12 次、每次间隔 5 秒(共 60 秒),三者一致才继续;
超时仍不一致则 exit 1,并在报错里区分两种可能:
  - latest 与 v0.1 不同 → 疑似并发构建覆盖(提示检查 flock 是否被绕过)
  - 仍为 "?"            → 推送根本没成功或仓库不可达
本次实测:第 1 次轮询发现未同步,等待 5 秒后三者均为 1ce3d4166506 ✅

顺带:不可变 tag 之前出现 -dirty 后缀,是因为改完脚本没提交就发版;
本次先提交再发版,tag 恢复干净(2.0.0-20261031-<sha>)。
This commit is contained in:
opsx committed 2026-10-31 18:12:46 +00:00
1 parent 0644dccf2a
commit 4d582e62eb
1 file changed
+20 -4
+20 -4
View File
@@ -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 " → 一致 ✅"