4.2 KiB
4.2 KiB
id, title, phase, deps, status, created
| id | title | phase | deps | status | created | |
|---|---|---|---|---|---|---|
| T-619 | 自动升级启动健康确认熔断与发布验收 | 8 |
|
TODO | 2026-07-13 |
问题 / 背景
完成文件替换并创建新进程不等于升级成功。新版可能因缺失依赖、打包错误或早期异常无法显示主窗口;直接删除备份会让用户失去可运行版本,直接恢复旧版又可能被同一强制版本反复触发,形成无限更新循环。
本任务完成自动升级的健康确认、失败版本熔断、备份清理、引导版本发布和Windows实机验收。
方案
- 新版通过更新器启动时携带事务ID/目标版本,在
.cmshopee-update/transactions/<id>/health.json写分阶段标记:process_started、main_window_ready或environment_blocked。标记使用原子写入,不包含用户密钥或业务数据。 process_started在新程序完成基础导入、Qt可用和自身版本核对后写入;main_window_ready在prepare_data_dir()、必要DB初始化和MainWindow.show()成功后由事件循环回调写入。数据迁移冲突、数据目录不可写、配置/Chrome等已知用户环境错误写environment_blocked,避免把环境问题误判为坏发布包。- 更新器等待健康标记有明确上限。新进程无法创建、基础导入崩溃、版本不符或未出现任何已知标记即退出时,恢复旧程序;出现
environment_blocked时保留新版并显示原有中文环境提示,不自动回滚。 - 回滚时记录
failed_version、包hash、时间和简短原因。同一失败版本不得自动再次下载/安装;旧版启动门禁看到该记录时仍保持强制阻断,显示“该版本自动升级失败,请重试管理员修复后的新版或手动安装”,避免无限循环和偷偷绕过强制升级。 main_window_ready后更新器才清理pending、下载包和临时目录;备份至少保留到健康确认完成。默认仅保留最近一次失败备份或设置合理容量上限,不扫描、不清理data/。- 完成端到端集成矩阵:正常升级、断网、hash错误、磁盘满、zip非法、安装目录只读、文件锁、替换中断、新版缺依赖、已知环境阻断、回滚和失败版本熔断。
- 完成引导版本策略:当前只支持浏览器下载的旧版必须先人工覆盖一个包含自动升级代码和更新器的引导版本;此后协议兼容版本才可自动升级。服务端发布前先灰度非强制检查,再启用强制标记。
- 更新
docs/update-check.md、docs/packaging.md、docs/04-architecture.md和用户排障说明,记录真实Windows 10/11无Python环境证据。
验收要点
- 正常升级后自动显示新版主窗口,窗口版本与服务端目标一致,旧版备份在健康确认后按策略清理。
- 缺失依赖或早期崩溃时自动恢复旧程序,并留下中文更新日志;
data/前后hash和目录结构不变。 - 已知数据目录、配置或Chrome环境错误不触发程序版本回滚。
- 同一失败版本不会无限自动重试,也不会绕过服务端强制升级进入旧版业务界面。
- 五个正式Tab、账号Chrome资料、SQLite、图片、提示词、cmhub Key和日志在升级前后保持一致。
- 发布zip、更新器、manifest和诊断日志均不包含真实账号、Cookie、API Key、运营Excel或业务图片。
- 无Python的Windows 10与Windows 11完成“旧引导版→新版”真实升级验收。
测试要求
- 新增健康标记、回滚判定、失败版本熔断和备份清理单元/集成测试。
- 在临时安装树做故障注入;打包后在Windows 10/11虚拟机人工验证,记录版本、结果和日志位置,不提交真实data。
- 运行ruff、compileall、完整unittest、build脚本、release内容检查和
git diff --check。
边界(不改什么)
- 不把自动升级失败当作允许进入被淘汰旧版的理由。
- 不自动上传诊断日志,不读取用户业务数据内容,不删除
data/。 - 不引入增量补丁、多发布渠道或静默后台升级;第一版仍是用户在强制窗口点击「立即升级」。
执行记录
(完成后记录实现、验证命令与结果。)