Files
qiming/qimingclaw/crates/agent-electron-client/docs/architecture/auto-update.md

7.4 KiB
Raw Blame History

应用自动更新

概述

基于 electron-updater 实现应用内自动更新,支持 macOS / Windows (NSIS) / Linux 自动下载安装Windows MSI 安装引导到下载页(优先 OSS 安装包直链)。

强制使用 latest.json:应用与 Release 流程均以 OSS 上的 latest.json唯一数据源。版本检查、各平台下载地址、签名与大小均来自该文件;不直接依赖 GitHub Release 或 electron-builder 生成的 yml 作为来源。

更新源macOS / Linux 应用内升级):检查与下载均走阿里云 OSS。

  • 检查更新拉取 OSS latest/latest.json 获取最新版本;其中 platforms 已包含各平台完整的 OSS 下载包地址url、signature、size。若有更新则将 electron-updater 的 feed 设为版本化 OSS 路径 ${OSS_BASE}/electron-v${version}
  • 下载安装包:安装包地址来自 latest.jsonplatforms(已是完整 OSS URL。electron-updater 实际下载时从 feed 请求的 latest-mac.yml / latest-linux.yml 等,必须由同一份 latest.jsonplatforms 在 Release 流程中派生生成,不得使用 GitHub 自带的 yml。
  • 失败处理OSS 不可达或元数据异常时,直接报错并引导用户前往下载页,不回退到 GitHub。

核心文件

文件 职责
src/main/services/autoUpdater.ts 更新服务:检查、下载、安装、状态管理
src/renderer/components/pages/AboutPage.tsx 关于页面:手动检查更新 UI
src/main/window/trayManager.ts 托盘菜单:检查更新入口
src/main/ipc/appHandlers.ts IPC 处理checkUpdate / downloadUpdate / installUpdate / openReleasesPage
src/preload/index.ts preload 暴露 API
src/shared/types/updateTypes.ts 类型定义UpdateState / UpdateInfo / UpdateProgress
dev-app-update.yml 开发模式更新源配置

更新流程

1. 启动自动检查

App 启动 → 延迟 10s → checkForUpdates()
                         │
                         ├── 无更新 → 静默,不提示
                         │
                         ├── 有更新 → 检查 skipped version
                         │              │
                         │              ├── 已跳过 → 不弹窗
                         │              │
                         │              └── 未跳过 → 弹窗提示
                         │                            │
                         │                            ├── "立即更新" → 下载 → 二次确认 → 重启安装
                         │                            │
                         │                            └── "跳过此版本" → 记录到文件,下次不再提示
                         │
                         └── 失败 → 静默记录日志

2. 手动检查About 页面)

用户点击 "检查更新"
  │
  ├── 检查中... (loading 状态)
  │
  ├── 无更新 → 提示 "当前已是最新版本",重置按钮
  │
  ├── 有更新 → 显示 "下载更新" 按钮
  │              │
  │              └── 点击 → 下载(显示进度条)→ 完成 → Modal 确认 → 重启安装
  │
  └── 错误 → 显示错误信息 + 重试按钮

3. 手动检查(托盘菜单)

与 About 页面类似,但使用原生 dialog.showMessageBox 弹窗交互。

Windows 安装类型检测

通过检查 NSIS 卸载程序文件是否存在来区分安装方式:

// NSIS 安装会生成: {appDir}/Uninstall {productName}.exe
// MSI 安装由 Windows Installer 管理,无此文件
function detectInstallerType(): InstallerType {
  const nsisUninstaller = path.join(appDir, `Uninstall ${productName}.exe`);
  return fs.existsSync(nsisUninstaller) ? 'nsis' : 'msi';
}
安装类型 自动更新 行为
NSIS (.exe) 支持 下载 → 重启安装
MSI (.msi) 不支持 引导到下载页(按 MSI 优先解析下载包)
macOS (.dmg) 支持 下载 → 重启安装
Linux (.AppImage/.deb) 支持 下载 → 重启安装

跳过版本

  • 用户在启动弹窗中选择"跳过此版本"后,版本号写入 ~/.qimingclaw/.skipped-update-version
  • 下次启动时,若远程最新版本与已跳过版本相同,不弹窗
  • 出现更新的版本(高于已跳过版本)时,重新弹窗提示
  • 手动检查更新About 页面 / 托盘菜单)不受跳过逻辑影响

安装前清理

installUpdate() 在调用 quitAndInstall() 之前,先执行 cleanupAllProcesses()

  • 停止 Computer Server
  • 销毁 Unified Agent Service
  • 终止 Agent Runner / Lanproxy / File Server 进程
  • 清理 MCP Proxy
  • 停止所有 Engine 进程

开发模式

  • 通过 dev-app-update.yml 配置更新源GitHub
  • forceDevUpdateConfig = true 启用开发模式检查
  • 允许检查更新(验证 API 通路)
  • 下载和安装被阻止Squirrel.Mac bundle ID 不匹配会导致崩溃)
  • autoInstallOnAppQuit = false

OSS 单源策略(强制 latest.json

所有更新元数据强制以 latest.json 为准:应用端只读 OSS latest/latest.json 做版本判断与地址解析Release 流程只产出并上传由该文件派生的 yml禁止使用或上传 GitHub 自带的 yml。

步骤 策略
检查更新 仅 OSS latest.json
Feed 基地址 仅 OSS 版本化路径
下载安装包 仅 OSSyml 必须由 latest.json 的 platforms 派生)
OSS 异常 报错 + 引导下载页,不回退 GitHub

数据源规则OSS 上维护并信任 latest.json(含 version、notes、pub_date、platforms 多架构与完整 OSS 下载地址。Release 流程(.github/workflows/release-electron.yml必须根据该 latest.jsonplatforms 生成 electron-updater 所需的 latest-mac.ymllatest-linux.ymllatest.yml,并写入 release-assets 后一并上传;禁止使用或上传 GitHub 自带的 ymlyml 内下载地址为相对路径(相对 feed 基地址即 OSS 版本化路径)。

本地触发 OSS 同步时,可在本 crate 下执行 scripts/sync-oss.sh <tag>(如 electron-v0.8.0),会触发上述 workflow 并轮询直至完成;依赖 ghjq

自定义更新源

通过环境变量 QIMING_UPDATE_SERVER 可指定自定义更新服务器:

QIMING_UPDATE_SERVER=http://localhost:8080/updates npm run dev

使用 generic provider适合本地测试。

UpdateState 类型

interface UpdateState {
  status: 'idle' | 'checking' | 'available' | 'not-available' | 'downloading' | 'downloaded' | 'error';
  version?: string;
  progress?: { percent: number; bytesPerSecond: number; transferred: number; total: number };
  error?: string;
  canAutoUpdate?: boolean;  // false 表示 MSI 安装,需手动下载
}

IPC 通道

通道 方向 说明
app:checkUpdate renderer → main 手动检查更新
app:downloadUpdate renderer → main 下载更新
app:installUpdate renderer → main 重启安装
app:getUpdateState renderer → main 获取当前更新状态
app:openReleasesPage renderer → main 打开下载页(从 latest.json 解析 OSS 安装包直链)
update:status main → renderer 推送更新状态变化