返回博客

Tauri 2 NSIS 自动更新流水线静默失败:.nsis.zip 已被移除

给一个 Tauri 桌面应用做 Windows 自动更新流水线,CI 从始至终全绿,发布日志显示一切正常。但部署上线两周后,用户反映「从来没弹过更新提示」。打开 Tauri 日志一看:更新服务端返回 404,或签名校验失败。究竟哪里断了?

根因只有一句话:Tauri 2 把 .nsis.zip 从构建产物里彻底删掉了,而绝大多数流水线脚本还在等一个永远不会出现的文件——然后静默跳过,退出码 0。

现象

CI 构建日志里只有这两行:

Finished 1 bundle at:
  ...\release\bundle\nsis\MyApp_1.2.0_x64-setup.exe
  ...\release\bundle\nsis\MyApp_1.2.0_x64-setup.exe.sig

没有任何 .nsis.zip。但 actions/upload-artifact@v4path 配置里写的是 *.nsis.zip,它打了一行 warning 后直接放行,artifact 里只有 -setup.exe,签名文件 .sig 根本没上传到 CDN。

update.json 里的 signature 字段最终是空字符串,Tauri updater 拿到之后验证失败,静默退出。

根因

Tauri 1.x 时代,NSIS 更新流程产出三件套:

  • *-setup.exe(安装包)
  • *.nsis.zip(updater payload)
  • *.nsis.zip.sig(minisign 签名)

Tauri 2 稳定版对此做了合并:安装包本身就是 updater payload,签名文件改为 -setup.exe.sig.nsis.zip 不再生成。

坑:旧 glob 静默跳过,CI 全绿但签名从未上传

上传脚本对 *.nsis.zip 进行正则匹配,找不到文件时通常打一行 warning 然后以 exit 0 退出。actions/upload-artifact@v4 的 path 不匹配时同理——只是 warning,不是 error。结果是整条流水线显示 ✅,但 .sig 文件从来没进 CDN,用户永远拿不到更新。

正解

需要同步修改三处,缺一不可。

1. GHA artifact 上传路径

- bundle/nsis/*.nsis.zip
- bundle/nsis/*.nsis.zip.sig
+ bundle/nsis/*-setup.exe
+ bundle/nsis/*-setup.exe.sig

同时修正 CI 日志里的 find 调试命令,否则日志仍然对着空结果假装正常:

- find "$BUNDLE_DIR" -type f \( -name '*.exe' -o -name '*.nsis.zip*' \) -print
+ find "$BUNDLE_DIR" -type f \( -name '*.exe' -o -name '*.exe.sig' \) -print

2. 云端上传脚本(OSS / S3)

把 3 条匹配规则改为 2 条:

  const PLAN = [
    { match: /-setup\.exe$/i,      key: 'windows-x64/app-x64-setup.exe' },
-   { match: /\.nsis\.zip$/i,      key: 'windows-x64/app-x64.nsis.zip' },
-   { match: /\.nsis\.zip\.sig$/i, key: 'windows-x64/app-x64.nsis.zip.sig' },
+   { match: /-setup\.exe\.sig$/i, key: 'windows-x64/app-x64-setup.exe.sig' },
  ]

3. update.json 生成器

url 指向 -setup.exesignature 读取 -setup.exe.sig 的完整文件内容(一段以 untrusted comment: signature from tauri secret key 开头的 base64 字符串):

WIN_SIG=$(find "$ARTIFACTS_DIR" -name '*-setup.exe.sig' -type f | head -1 \
          | xargs cat)
 
cat > update.json <<JSON
{
  "version": "$VERSION",
  "platforms": {
    "windows-x86_64": {
      "url": "https://cdn.example.com/windows-x64/app-x64-setup.exe",
      "signature": "$WIN_SIG"
    }
  }
}
JSON

平台键必须是 windows-x86_64(Tauri 2 约定),不能写成 windows-x64

正解:三处全改,然后 curl 验证 .sig 是否上到 CDN

修复之后先用 curl -sI 验证签名文件确实存活:

curl -sI https://cdn.example.com/windows-x64/app-x64-setup.exe.sig | head -3
# 期望:HTTP/2 200,Content-Length ≈ 400-450 字节

再用 curl -s update.json | jq .platforms 确认 signature 字段非空且以正确前缀开头。

提示:没有 .sig 文件?检查 createUpdaterArtifacts

如果 CI 日志里连 -setup.exe.sig 都不见踪影,说明 Tauri 根本没有执行签名步骤。检查 tauri.conf.json

{ "bundle": { "createUpdaterArtifacts": true } }

缺少这个字段时,Tauri 2 只打包安装包,不生成签名文件。

一句话外卖

CI 全绿不等于更新链路通畅——Tauri 2 把 .nsis.zip 合并进 -setup.exe.sig,所有匹配旧格式的 glob / 上传脚本 / update.json 生成器都会静默跳过,必须三处联动修改。