From 1acc75f00ef22c18f7d431c4481807d3cc6d63eb Mon Sep 17 00:00:00 2001 From: zijunchiang Date: Fri, 18 Sep 2026 03:10:05 +0800 Subject: [PATCH] =?UTF-8?q?test(release):=20=E9=80=90=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E6=A0=B8=E5=AF=B9=E3=80=8C=E5=8F=91=E5=B8=83=E5=8C=85=20=3D=3D?= =?UTF-8?q?=20=E6=89=93=E6=A0=87=E7=AD=BE=E7=9A=84=E6=A0=91=E3=80=8D?= =?UTF-8?q?=EF=BC=88T-WEB-018=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 「发布包里的东西必须等于打标签的那棵树」此前靠人抽查几个文件(README、contracts/VERSION…), 必然会漏。上一轮实测就暴露了两个认知错误:Web 的发布包其实**包含** web-server/test/** (33 个文件,我此前以为不含),以及包内另有 177 个**构建产物**(admin/、web-server/dist/) 必须与工作树构建比 —— 只比源码文件是不够的。 新增 web-server/scripts/check-tracked-release.py(纯标准库,支持 .tar.gz / .zip): 对包内**每一个**文件按路径决定比较基准 —— 构建产物(admin/、web-server/dist/)比工作树 构建结果,其余文件比 `git show :<路径>`;任何内容不一致 / 包内多余(既不在 git 也不是 声明的构建产物)/ 构建产物在工作树缺失都会列出并以非 0 退出。`npm run release:check` 已注册。 实测(**已发布**资产重新下载后跑): 包内 356 个文件:源码/文档 179(与 tag v0.7.5 比)+ 构建产物 177(与工作树构建比) ✓ 逐文件一致:0 处不一致 / 0 处多余 / 0 处缺失 反向验证:篡改 README.md 一个字节 + 塞入 web-server/EXTRA.txt → ✗ 内容不一致 1 处(README.md)、✗ 包内多余 1 处(EXTRA.txt),退出码 1。 顺带修掉脚本自身一个路径映射缺陷:BUILD_OUTPUTS 的键若是不带 / 的**精确文件名** (Windows/Android 的单文件产物),原实现会把剩余路径拼成 ".../OpenDance.exe/" 导致「工作树缺失」误报;现在区分「目录前缀」与「精确文件名」两种键。 注:accept-release.sh 的接入只在下一个版本的产物里生效(本仓 accept-release.sh 本身 也在发布包内,v0.7.5 已发布);对已发布的 v0.7.5 包仍可用 `npm run release:check -- <包> --tag v0.7.5` 逐文件核对(已跑通)。同时已把同一脚本复制到 opendance-windows / opendance-android 并接入 两端的 accept-release.sh。 --- web-server/package.json | 3 +- web-server/scripts/accept-release.sh | 15 ++ web-server/scripts/check-tracked-release.py | 183 ++++++++++++++++++++ 3 files changed, 200 insertions(+), 1 deletion(-) create mode 100644 web-server/scripts/check-tracked-release.py diff --git a/web-server/package.json b/web-server/package.json index 6bc33be..394e3be 100644 --- a/web-server/package.json +++ b/web-server/package.json @@ -25,7 +25,8 @@ "migration:show": "node scripts/migrate.mjs show", "version:check": "node scripts/check-version.mjs", "bootstrap:check": "node scripts/check-bootstrap.mjs", - "vectors:frame": "vite-node scripts/gen-frame-vectors.mts --" + "vectors:frame": "vite-node scripts/gen-frame-vectors.mts --", + "release:check": "python3 scripts/check-tracked-release.py" }, "dependencies": { "@nestjs/common": "^11.0.12", diff --git a/web-server/scripts/accept-release.sh b/web-server/scripts/accept-release.sh index 7a34b6f..dab4354 100755 --- a/web-server/scripts/accept-release.sh +++ b/web-server/scripts/accept-release.sh @@ -65,6 +65,21 @@ log "发布包:$TARBALL" log "工作目录:$WORK_DIR" mkdir -p "$WORK_DIR" +# ---- 0. 逐文件核对:发布包 == 打标签的树(T-WEB-018)---- +# 只在仓库内、且能解析到对应 tag 时执行;对用户拿到的 tarball 也能跑(--tag 需显式给)。 +TRACKED_CHECKER="$PROJECT_DIR/scripts/check-tracked-release.py" +if [ -f "$TRACKED_CHECKER" ] && command -v git >/dev/null 2>&1; then + TAG="$(basename "$TARBALL" .tar.gz | sed 's/^opendance-web-//')" + if git -C "$PROJECT_DIR" rev-parse --verify "${TAG}^{commit}" >/dev/null 2>&1; then + log "逐文件核对:发布包 == tag $TAG(源码/文档比 tag,构建产物比工作树构建)" + python3 "$TRACKED_CHECKER" "$TARBALL" --tag "$TAG" || fail "发布包与 tag $TAG 不一致" + else + log "跳过逐文件核对(仓库里没有 tag $TAG;可在仓库内用 --tag 手工核对)" + fi +else + log "跳过逐文件核对(缺 $TRACKED_CHECKER 或 git)" +fi + # ---- 1. 解包 ---- log "解包…" tar -xzf "$TARBALL" -C "$WORK_DIR" || { echo "✗ 解包失败" >&2; exit 1; } diff --git a/web-server/scripts/check-tracked-release.py b/web-server/scripts/check-tracked-release.py new file mode 100644 index 0000000..b76209a --- /dev/null +++ b/web-server/scripts/check-tracked-release.py @@ -0,0 +1,183 @@ +#!/usr/bin/env python3 +"""发布产物 × 打标签的树:**逐文件**核对(T-WEB-018) + +## 为什么需要 + +「发布包里的东西必须等于打标签的那棵树」这条规则此前是靠人手工抽查几个文件 +(README、contracts/VERSION…)来确认的 —— 而抽查必然会漏。本轮实测就发现 +两个认知错误: + +* Web 的发布包**包含** `web-server/test/**`(33 个文件),而我此前以为不含, + 于是 `test/**` 的改动是否影响产物从来没被检查过; +* 发布包里另有 177 个**构建产物**(`admin/`、`web-server/dist/`)与 git 无关, + 必须与工作树的构建结果比 —— 只比源码文件是不够的。 + +本脚本把这条规则变成**可重复的全量核对**: + +对发布包里的**每一个**文件,按路径决定比较基准: + +| 路径 | 比较基准 | +|--|--| +| 构建产物(见 `BUILD_OUTPUTS`) | 工作树里对应的构建输出 | +| 其余文件 | `git show :<路径>`(打标签的树) | + +任何一处不一致 / 包内多余(既不在 git 也不在构建输出)/ 缺失都会列出并以非 0 退出。 + +## 用法(在仓库根目录执行) + + python3