8.9 KiB
8.9 KiB
版本升级链走查(2026-10-10)
走查方式:用户要求的只读走查 + 本地全链演练(零线上影响),源码与现场日志取证;本文为全文落档(看板/汇总仅摘要)。 铁证来源:应用 trace(
%TEMP%/devflow-trace.log)· 演练服务访问日志(temp/upgrade-drill/access.log)· 脚本与配置现场(scripts/publish-release.ps1/scripts/package-devflow.ps1/src-tauri/tauri.conf.json/src-tauri/src/commands/update.rs)。 结论先行:升级核心机制本身零缺陷——四发现全在链路外围(端点发布/脚本产物格式/传输协议/本地打包拆分),这也是本地演练能全链闭环的前提。
一、链路全景(走查基线:代码链本身完整 ✓)
- 后端:
app_check_update/app_download_install_update(src-tauri/src/commands/update.rs)——走 Tauri updatercheck()拉tauri.conf.json的plugins.updater.endpoints配置的 latest.json,内建 ed25519 签名校验(公钥tauri.conf.json:47);无更新返回has_update=false,网络/解析失败返回 Err(前端据此提示,不谎报「已是最新」)。 - 前端:
useUpdateCheck→ 徽章 / 设置页(徽章事件通道错配——Tauri 事件 vs window CustomEvent 同名不同通道致徽章永不触发——已于前批修复并登记看板 925)。 - 发布侧:
publish-release.ps1六步(版本双源校验 → 构建 → 定位产物 → 生成 latest.json → 上传 app.1216.top);版本双源校验:28-38(tauri.conf.json vs Cargo.toml 必须同值,防 D1 复发);私钥已就位~/.tauri/devflow.key。 - 版本一致性闸:
update.rs:89-104用CARGO_PKG_VERSION与 latest.json 的version比较,非更新返回has_update=false(演练中验证其正确拦截,见 §三)。
二、四发现(按严重度)
发现 1 🔴 线上端点从未发布——应用内升级从未真正可用【已修复:v0.1.2 发布上线】
- 事实:
https://app.1216.top/download/devflow/latest.json404;目录 403(存在但空)——从未有产物上传过。 - 铁证:应用 trace 每 15 分钟报
update endpoint did not respond with a successful status code,07:33 / 07:48 / 08:03 / 08:18 / 08:23 连续五次——自动检查一直在跑、一直失败。 - 影响:发布流程「能构建能上传产物」但 latest.json 这最后一环缺失,应用内升级通道自上线以来形同虚设。
发现 2 🟠 发布脚本产物名与 Tauri v2 不匹配——跑通也会 404【已修复:脚本 v2 适配】
- 事实:
publish-release.ps1期待 v1 格式...setup.nsis.zip+.nsis.zip.sig;而createUpdaterArtifacts: true(tauri.conf.json:33)在 Tauri v2 实际产出...setup.exe.sig(更新包即安装器本身)。 - 两个后果:① 脚本停在「未找到 .sig 签名文件」直接 exit;② 即使产物名对上,它写进 latest.json 的 url 也指向不存在的
.nsis.zip→ 客户端下载 404。 - 修法二选一(当时列出):脚本改读
.exe.sig+ url 指 exe(v2 格式,已采纳);或配置改createUpdaterArtifacts: "v1Compatible"。
发现 3 🟡 updater 强制 https——自建 http 更新源不可行【机制确认,线上无碍】
- 事实:本地 http 端点被 updater 拒绝,实测报错原文
The configured updater endpoint must use a secure protocol like https。 - 判定:线上是 https 无碍;但演练/私有 http 更新源必须二选一——真证书,或构建期
--config注入dangerousInsecureTransportProtocol: true(演练采纳后者,见 §三,仅演练专用构建携带、不改生产配置语义)。
发现 4 🟡 本地 package-devflow -Mode full 缺密钥必报「失败」并跳过安装段【已修复:换装与签名拆开】
- 事实:本机未设
TAURI_SIGNING_PRIVATE_KEY时,产包 updater 签名段必报失败并跳过安装段——这正是此前每次都要手工跑swap-install.ps1的根因(2026-10-10 实录:package-devflow -Mode full产包后因缺密钥报失败跳过安装)。 - 本质:本地换装(自用安装最新构建)与发版签名(updater 产物)是两类需求被一个开关捆死。修法:本地换装不需要签名产物,两者拆开。
三、本地全链演练(零线上影响)
演练设施
| 件 | 位置 | 说明 |
|---|---|---|
| 端点覆盖 | update.rs:63-84 build_updater |
env DEVFLOW_UPDATER_ENDPOINT 覆盖端点,不设即走 tauri.conf 配置(生产零影响);覆盖时 warn 日志「更新端点被环境变量覆盖(本地演练模式)」 |
| 传输放开 | temp/drill-tauri-override.json |
仅 dangerousInsecureTransportProtocol: true,演练专用构建以 --config 注入(治发现 3 的演练侧) |
| 真 v2 产物 | temp/upgrade-drill/ |
devflow_0.1.2_x64-setup.exe(13.4MB)+ .exe.sig(436B,base64 minisign 格式,与 tauri.conf.json:47 pubkey 配对)+ latest.json(version/notes/pub_date/platforms.windows-x86_64.{signature,url},url 指 http://127.0.0.1:8765/...exe) |
| 带日志本地源 | 同目录 access.log |
8765 端口静态服务,全量记录请求 |
演练链与现场证据(access.log 时间线)
- 端点覆盖生效 → 检查 200:
08:47:51 GET /latest.json 200——env 覆盖后的首次检查即通(对照发现 1 的 trace 连续失败,同一检查链路换个可用端点立即恢复)。 - 发现更新 → 下载 200:
09:31:36-09:32:16latest.json 200 →GET /devflow_0.1.2_x64-setup.exe 200(完整下载 13.4MB)。 - 验签通过:latest.json 的 signature(ed25519)经
tauri.conf.json:47公钥校验通过——签名/公钥/私钥三件套自洽(此后下载才允许进入安装)。 - 版本一致性闸正确拦截:
update.rs:89-104以CARGO_PKG_VERSION与 latest.jsonversion比较——当本机版本 ≥ 通告版本时返回has_update=false拒绝安装(闸本身行为正确);演练初期版本差未成立即被此闸拦下,0.1.2 产物重建(本机保持 0.1.1 演练版)后版本差成立。 - 闭环复现:
12:43:03-12:43:50第二轮完整通过(latest.json 200 → exe 200 → 回查 latest.json)——检查→下载→验签→版本判定全链跑通;且09:43:43→11:46:37每 ~15 分钟一次的周期自动检查连续 9 次全部 200——自动检查定时器在演练端点下工作正常(对照发现 1:同一台机器同一定时器,此前对线上端点连续失败)。
演练结论:升级核心链(检查→下载→ed25519 验签→版本一致性闸→安装)在本机全链可用,四发现均为外围问题且逐一有解。
四、已落地修复清单(截至当日收盘,均在盘待提交)
| # | 修复 | 落点 | 治哪个发现 |
|---|---|---|---|
| 1 | env 端点覆盖 DEVFLOW_UPDATER_ENDPOINT(不设即走配置 + warn 日志) |
src-tauri/src/commands/update.rs:63-84 |
演练设施(兼私有源能力) |
| 2 | 脚本 v2 产物适配:.exe.sig/.nsis.zip.sig 双格式探测,与更新产物正确配对(v2 签名配 setup.exe,v1 配 zip);url 指向真实产物 |
scripts/publish-release.ps1:65-71 |
发现 2 |
| 3 | SHA256 计算兜底:本机 PowerShell 5.1 缺 Get-FileHash,异常走 certutil -hashfile(同 swap-install 兜底口径) |
scripts/publish-release.ps1:84-87 |
发布机环境鲁棒性 |
| 4 | v0.1.2 正式发布上线:publish-release.ps1 -SkipBuild 上传成功,线上 latest.json 实测 200(version 0.1.2)——应用内升级通道正式激活 |
线上 app.1216.top/download/devflow/ |
发现 1(🔴 404 清零) |
| 5 | 本地换装与发版签名拆开:未设 TAURI_SIGNING_PRIVATE_KEY 时以 --config 关掉 createUpdaterArtifacts,不再假失败、不再跳过安装段;发版(需签名)走 publish-release.ps1 |
scripts/package-devflow.ps1:39-44 |
发现 4 |
| 6 | (前批)UpdateBadge 通道错配修复:补 window CustomEvent 监听 + 卸载清理 | src/components/layout/UpdateBadge.vue |
前端侧「有更新不亮徽章」 |
五、待办与纪律留痕
- 正式验收未走完:本机装的仍是 0.1.1 演练版(带 env 覆盖构建)。验收动线:正常重启应用(不设 env)→ 检查更新 → 从线上发现 0.1.2 → 升级 → 关于页显示 v0.1.2 → 再查一次显「已是最新」。
- 纪律事件:当日 e296c84 提交经用户令「撤」已回退,升级链 4 文件(update.rs / publish-release.ps1 / package-devflow.ps1 / tauri.conf.json)回工作区零丢失;纪律强化为一切提交攒批、最后由用户显式发令。
- 遗留提示:发现 3 的
dangerousInsecureTransportProtocol仅存在于演练 override 配置,生产tauri.conf.json未含、也不应含;若未来要私有 http 源,正路是证书而非放开传输。