跳转至

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 的 bsdiff4patch_settings.ini engine=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 }

决策

  1. 热修主 exe 走全量 zip 投递,不做 bsdiff——沿用 force_add_list.txtStreamFab64.exe 的既定结论。ADR-0001/0007 中"体积代价已由差分消解"的说法作废:热修包体积 ≈ 主 exe 压缩后大小(实际值待测),第一版接受。若后续体积成为瓶颈,需先解决"加壳签名二进制差分触发杀软"这一根因,属独立课题。
  2. CI 改造点create_ini.pymake_initype=hotfix section 类型(复用其 MySQL 真源、版本对枚举、防回滚);CreateUpdate_new.pyHotfixPatchWork(PatchWork) 子类,只覆写 create_patch()(单文件全量),复用 zip_patch/create_md5_txt/_verify_patch_integrity;Jenkinsfile 增 HOTFIX 与灰度参数、增 Ed25519 签名 stage(Authenticode 照抄上游 sign_downloader.bat 的 signtool 调用)。
  3. 热修流水线必须补 post { failure } 通知——热修是紧急通道,构建失败必须响。
  4. 复用 TEST_MODE 隔离模式(test cfg 目录 / 不写库 / 不通知)作为热修灰度前验证通道。
  5. .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 触发。