ADR-0008:热修包构建复用现有增量流水线,但主 exe 走全量投递¶
日期:2026-07-20 状态:已接受
背景(源码核实结论)¶
CI 侧现状(jekins/dvdfab_update_build_scripts + jekins/fabupdate_creator):
- Jenkins 流水线纯手动触发,参数含 APP(含架构)/VERSION/UPDATE_PKG_NUMS(1~4)/SERVER/TEST_MODE;
create_ini.py连 MySQL(10.10.2.17/update) 查历史版本、防版本回滚、生成 section({PID}_{from}_{to})配置。 CreateUpdate_new.py从两个已发布的安装包 exe 解包做目录树差分,现役引擎为 Python 的bsdiff4(patch_settings.iniengine=python),产出 zip(内含update.xml+ 一堆{uuid}.patch,扁平结构)+.zip.txt(MD5) +.zip.cfg(多 CDN 镜像域名下载配置),落 NAS,无 CDN 上传动作。force_add_list.txt已把StreamFab64.exe列为强制全量 ADD,明确绕开 bsdiff——原因是签名/加壳二进制的 bspatch 会触发杀软或签名问题、大文件差分压缩率不如全量 zip、且有客户端 bspatch 回归。- CI 侧无任何大小阈值判定(全仓无命中),所有 section 无条件生成。
- 增量流水线无代码签名步骤(签名在上游打包流水线:VMProtect 加壳 → signtool + GlobalSign 时间戳 → 生成安装包);产物校验只有 MD5,无 SHA-256、无非对称签名。
- 通知:邮件 + 两个飞书 webhook,均在成功后;无
post { failure }。
决策¶
- 热修主 exe 走全量 zip 投递,不做 bsdiff——沿用
force_add_list.txt对StreamFab64.exe的既定结论。ADR-0001/0007 中"体积代价已由差分消解"的说法作废:热修包体积 ≈ 主 exe 压缩后大小(实际值待测),第一版接受。若后续体积成为瓶颈,需先解决"加壳签名二进制差分触发杀软"这一根因,属独立课题。 - CI 改造点:
create_ini.py的make_ini增type=hotfixsection 类型(复用其 MySQL 真源、版本对枚举、防回滚);CreateUpdate_new.py增HotfixPatchWork(PatchWork)子类,只覆写create_patch()(单文件全量),复用zip_patch/create_md5_txt/_verify_patch_integrity;Jenkinsfile 增 HOTFIX 与灰度参数、增 Ed25519 签名 stage(Authenticode 照抄上游sign_downloader.bat的 signtool 调用)。 - 热修流水线必须补
post { failure }通知——热修是紧急通道,构建失败必须响。 - 复用 TEST_MODE 隔离模式(test cfg 目录 / 不写库 / 不通知)作为热修灰度前验证通道。
.zip.cfg的多镜像 CDN 下发机制直接复用。
已知风险与遗留¶
- 下发服务是最大未知区:灰度分流、cfg 选择逻辑在 10.10.2.17 的 update DB + 未见源码的下发服务里,不在已探索的两个仓库中。热修的灰度参数最终要落到那一侧——spec 阶段必须拿到这部分代码或负责人确认。
update.xml目录节点 MD5 为空的已知缺陷(xmlwriter.py)——若 Ed25519 清单要覆盖 update.xml 语义完整性,宜先修。_zip_files扁平化写入:签名/清单文件命名不得与 patch 文件冲突。- 触发方式为纯手动,热修若需更快响应可考虑 upstream 或 API token 触发。