Files
opendance-windows/build/sync-export-version.sh
T
zijunchiang ba988f6ca6 fix(packaging): 发布包 exe 的 PE 版本资源必须等于发布版本(v0.2.2)
缺陷(v0.2.1 实测):把 opendance-windows-v0.2.1.zip 解开、在 Windows 上
「右键 → 属性 → 详细信息」,显示的是

    文件版本    0.1.0
    产品版本    0.1.0

而产物名、Git tag、README 全是 v0.2.1 —— 正是文档 §11.2 要禁止的
「不可核对的发布」。

根因:export_presets.cfg 的 application/file_version /
application/product_version 被硬编码在 0.1.0,而它们**不会**跟随
project.godot 的 application/config/version 自动更新;check-version.sh 当时
只比 project.godot ↔ project.yaml(两处一致),所以静态校验全绿、产物却是错的。
漂移发生在没人看的第三个位置 —— 校验位置少一个,等于没校验。

证据:
  strings -a -el OpenDance.exe  ->  FileVersion 0.1.0 / ProductVersion 0.1.0
  VS_FIXEDFILEINFO @0x67b976c   ->  FileVersion 0.1.0.0 / ProductVersion 0.0.0.0
对照组:官方模板 windows_release_x86_64.exe 的 FileVersion = 4.7.2,
说明本机 rcedit 改写是生效的,问题纯粹在预设的值本身。

修复:
  * build/sync-export-version.sh(新增):导出前把版本号写进导出预设,
    幂等、拒绝非 X.Y.Z;
  * build/check-pe-version.sh(新增):直接读 exe 的 PE 版本资源 ——
    VS_FIXEDFILEINFO(签名 0xFEEF04BD 后 16 字节,grep -abo 取偏移约 40 ms)
    与 StringFileInfo(strings -el,资源管理器属性页显示的就是它)。
    两处都查:实测固定信息里的 ProductVersion 恒为 0.0.0.0;
  * build/check-version.sh:新增导出预设两个键的校验;
  * build/export-windows.sh:导出前同步、导出后直接复核产物;
  * build/package-release.sh:打包前校验源 exe、解包后再校验包内 exe;
  * build/verify.sh:新增步骤 1/5「产物 PE 版本资源」(未导出则跳过);
  * tests/test_about.gd:新增 test_export_preset_version_matches_project_version。

反向验证:把预设 file_version 改回 0.1.0 →
  check-version.sh 退出码 1(报出两处不一致);
  无头测试 753 通过 / 1 失败,失败项正是
  「导出预设的 file_version 与版本号唯一来源一致」。

实测 v0.2.2 产物:PE FileVersion 0.2.2.0 / StringFileInfo 0.2.2,
版本号在 project.godot / project.yaml / export_presets.cfg / exe 元数据 /
产物名 / tag 六处一致。verify.sh 全绿(754 通过 / 0 失败 / 5 跳过)。

同时把 LZMA 压缩的取舍写清楚:deflate 包 38,248,818 B 仍超 IIS
30,000,000 B 上限,故 Release 资产仍是 LZMA 整包(26,628,529 B,不拆分卷);
若上限放开或改由 Web /static 分发,用 ZIP_METHOD=deflate 重打包即可得到
资源管理器可直接双击解压的包。
2026-09-17 04:22:57 +08:00

59 lines
2.2 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
# ============================================================
# OpenDance Studio —— 把当前版本号同步进 Godot 导出预设
#
# 为什么需要它:`export_presets.cfg` 的
# application/file_version / application/product_version
# 决定导出后 `OpenDance.exe` 的 PE `VERSIONINFO` 资源,也就是 Windows 上
# 「右键 → 属性 → 详细信息」里显示的文件版本/产品版本。这两个键**不会**
# 跟着 `project.godot` 的 `application/config/version` 自动走:
# 它们当初被硬编码成 0.1.0 后一直没人改,导致 **v0.2.1 的包显示 0.1.0**。
#
# 因此发布前必须显式同步,并由 `build/check-pe-version.sh` 在产物上复核。
#
# 用法:
# bash build/sync-export-version.sh [版本号] # 缺省取 project.yaml 的 version
# ============================================================
set -euo pipefail
PROJECT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
cd "$PROJECT_DIR"
PRESET="$PROJECT_DIR/export_presets.cfg"
[ -f "$PRESET" ] || { echo "错误:缺少 $PRESET" >&2; exit 1; }
VERSION="${1:-$(sed -n 's/^version:[[:space:]]*//p' project.yaml | head -1)}"
VERSION="${VERSION:-}"
if ! printf '%s' "$VERSION" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+$'; then
echo "错误:版本号必须形如 X.Y.Z(实际 '$VERSION')" >&2
exit 1
fi
CHANGED=0
for KEY in file_version product_version; do
LINE="application/${KEY}=\"${VERSION}\""
if grep -qE "^application/${KEY}=" "$PRESET"; then
OLD=$(grep -E "^application/${KEY}=" "$PRESET" | head -1)
if [ "$OLD" != "$LINE" ]; then
# 用 sed 就地替换;值里只有数字和点,无需转义
sed -i "s|^application/${KEY}=.*$|${LINE}|" "$PRESET"
echo " application/${KEY}: ${OLD#*=} → \"${VERSION}\""
CHANGED=1
else
echo " application/${KEY}: 已是 \"${VERSION}\""
fi
else
# 预设里没有这一行就追加到 [preset.0.options] 段的末尾(application/ 键都在该段)
printf '%s\n' "$LINE" >>"$PRESET"
echo " application/${KEY}: 新增 \"${VERSION}\""
CHANGED=1
fi
done
if [ "$CHANGED" -eq 1 ]; then
echo "✓ 导出预设已同步到 v${VERSION}(重新导出后 PE 资源才会更新)"
else
echo "✓ 导出预设已是 v${VERSION},无需改动"
fi