背景
现有两阶段发布避免了未完成 release 提前暴露,但 latest.json 的最终写入仍是无条件覆盖。旧 tag 的 Actions rerun,或两个稳定版本发布并发交错时,较旧版本仍可在较新版本之后覆盖 R2/IHEP 的 latest 指针,导致首选自更新端点回退。
同时 promote 前的健康检查只读取公开 candidate 并对平台 URL 做 HEAD;IHEP 存储没有独立下载核验,两个后端也没有在写入前校验当前远端版本与候选版本的单调关系。
当前证据
.github/workflows/release.yml:25-29:tag 发布没有 release concurrency/serialization。
scripts/sync-mirror.sh:110-121:upload_latest 对目标 latest.json 无条件覆盖。
scripts/sync-mirror.sh:124-155:candidate 健康检查只验证版本相等与 URL HEAD 可达。
scripts/sync-mirror.sh:191-213,224-241:IHEP 与 R2 promote 均无远端版本比较;只在 R2 configured 时走一次公开 candidate 检查。
验收标准
占位说明
对应 Draft PR 只保留实施入口,不改变当前发布流程,不应合并。
背景
现有两阶段发布避免了未完成 release 提前暴露,但
latest.json的最终写入仍是无条件覆盖。旧 tag 的 Actions rerun,或两个稳定版本发布并发交错时,较旧版本仍可在较新版本之后覆盖 R2/IHEP 的 latest 指针,导致首选自更新端点回退。同时 promote 前的健康检查只读取公开 candidate 并对平台 URL 做 HEAD;IHEP 存储没有独立下载核验,两个后端也没有在写入前校验当前远端版本与候选版本的单调关系。
当前证据
.github/workflows/release.yml:25-29:tag 发布没有 release concurrency/serialization。scripts/sync-mirror.sh:110-121:upload_latest对目标latest.json无条件覆盖。scripts/sync-mirror.sh:124-155:candidate 健康检查只验证版本相等与 URL HEAD 可达。scripts/sync-mirror.sh:191-213,224-241:IHEP 与 R2 promote 均无远端版本比较;只在 R2 configured 时走一次公开 candidate 检查。验收标准
latest.json,按语义版本执行单调检查;旧版本不得覆盖新版本。占位说明
对应 Draft PR 只保留实施入口,不改变当前发布流程,不应合并。