Files

4.0 KiB
Raw Permalink Blame History

id, title, phase, deps, status, created
id title phase deps status created
T-618 强制升级进度窗口与自动下载重启编排 8
T-616
T-617
DONE 2026-07-13

问题 / 背景

T-544当前“下载新版”只打开浏览器并退出。完成安全下载暂存和独立更新器后,需要把它们接回启动门禁:用户点击「立即升级」后在软件内看到持续进度,下载和准备完成后旧程序退出,由更新器替换并自动启动新版。

方案

  1. 扩展 UpdateInfo/UpdateCheckResult,解析并校验 size_bytes、package_format、updater_protocol、可选签名字段;旧接口仍可用于手动下载提示,但只有完整自动安装元数据才能启用「立即升级」。
  2. 用专用模态 QDialog 替代当前一次性 QMessageBox。状态包括:发现必须升级、下载、校验、暂存、准备重启、失败;显示中文阶段、进度百分比、已下载/总大小和发布说明,不显示URL、内部路径、堆栈或英文异常。
  3. 下载、hash、解压和manifest校验全部由 QObject + QThread worker执行;主线程只更新UI。线程引用保留到 thread.finished,退出/取消使用协作式停止并等待安全清理,禁止出现 QThread: Destroyed while thread is still running。
  4. 强制响应元数据完整时按钮为「立即升级」「退出程序」;运行中允许退出并协作式取消;失败后为「重试」「退出程序」。没有成功启动更新器前,用户不能进入主窗口。
  5. 区分失败边界:版本接口完全不可达/非法时保持T-544失败放行;一旦服务端已明确返回强制升级,后续元数据缺失、下载、校验、暂存或启动更新器失败都保持阻断,只允许重试或退出。
  6. 启动时先检查本地已验证 pending.json;有效则直接进入“准备重启”,不重复下载。无效pending清理后再请求/下载。
  7. 暂存成功后生成plan,把更新器复制到临时目录并以无窗口方式启动;确认更新器进程创建成功后,主程序退出事件循环。更新器完成替换后自动启动新版。
  8. 同步 app/gui/__init__.py、docs/update-check.md、docs/packaging.md 和 docs/routes.md。普通非强制更新仍不新增提示。

验收要点

  • 命中强制更新后不能创建或进入 MainWindow;点击「立即升级」不调用浏览器。
  • 下载、校验、暂存阶段GUI持续响应且中文进度正确;失败可重试,退出不会遗留运行线程或把part当完整包。
  • 服务端明确强制但hash/大小/格式不完整时阻断自动安装并给中文原因,不降级放行旧版。
  • 有效pending重启后直接继续安装,不重复下载或重复解压。
  • 更新器启动失败时旧程序文件完全不变;启动成功后旧主程序退出,新程序由更新器拉起。
  • 版本接口断网仍按现有策略允许进入,且记录脱敏诊断日志。

测试要求

  • 更新 tests/test_update_check.py、tests/test_gui.py,新增worker/对话框测试,覆盖状态转换、进度、重试、取消、失败放行与强制后阻断。
  • 使用mock更新器验证主程序只在更新器成功创建后退出;不得在自动化测试访问真实线上。
  • 运行ruff、compileall、完整unittest和 git diff --check。

边界(不改什么)

  • 不改变非强制更新产品策略。
  • 不实现早期崩溃健康回滚和失败版本熔断;T-619负责。
  • 不修改五个业务Tab、CDP、AI、Excel、SQLite业务表或蝦皮流程。

执行记录

  • 2026-07-13:新增强制升级模态进度窗口与专用QThread worker,显示中文阶段、百分比和下载字节;取消会等待worker清理并在线程结束后释放引用。
  • 2026-07-13:启动门禁已接入安全暂存、plan生成和临时目录独立更新器启动;强制响应后的元数据/下载/校验/启动失败保持阻断,版本接口自身失败仍按原策略放行。
  • 2026-07-13:干净worktree验证通过:ruff、compileall、完整unittest(411项)和 git diff --check。自动化测试未访问真实线上下载地址。