Skip to content

feat(update): 增加应用内更新与各平台一键安装脚本 - #9

Merged
sunerpy merged 2 commits into
mainfrom
feat/in-app-updates
Oct 1, 2026
Merged

sunerpy merged 2 commits into
mainfrom
feat/in-app-updates

Conversation

@sunerpy

@sunerpy sunerpy commented Oct 1, 2026

Copy link
Copy Markdown
Owner

参考 Voltip,给 Lockra 加上应用内更新和各平台的一键安装脚本。

应用内更新

  • 「设置 › 关于」:检查更新、查看更新内容(发布说明转成纯文本)、下载并安装(进度条)、失败原因与重试;另有「自动检查更新」开关,默认关闭。开启后启动 10 秒检查一次、之后每天一次,只提示,不会自行下载或安装;同一版本只提示一次。
  • 状态机在 lockra-core(Updater port,暂停时钟 + fake 测试);外壳用 tauri-plugin-updater =2.12.0 实现,网络请求全部在 Rust 侧,webview 没有插件权限,CSP 不变。
  • 只有从安装包运行的副本能自我更新(安装方式读自打包时写进可执行文件的 bundle type;macOS 看是否在 .app 里),源码构建的副本会说明无法更新,不会替换自身。
  • 安全:每个安装包用新生成的 minisign 密钥签名(公钥在 tauri.conf.json,私钥与密码已设为仓库 secret);requireSignedVersion 要求签名里的版本等于清单宣布的版本,拒绝“旧包冒充新版本”的降级。安装前先写入防抖中的自动备份。

发布侧

  • latest.json 除了每个目标的 {os}-{arch},还为每个已签名的包写 {os}-{arch}-{安装方式} 键。插件先按安装方式查找:只写 {os}-{arch} 时,用 .deb 安装的副本会下载 AppImage 并以 InvalidUpdaterFormat 失败(v0.1.1 的 deb 里实测含 __TAURI_BUNDLE_TYPE_VAR_DEB)。这个修复做在 github-project-scaffold 模板里,tauri-release.py 与模板保持一致。
  • 本地 make linux-x64 / windows-x64 在没有私钥时不签名(--config 关掉 updater 产物)。

一键安装

  • scripts/install.sh(Linux x64/ARM64:有 apt 用 deb,有 dnf/zypper/yum 用 rpm,否则 AppImage;macOS:对应芯片的 dmg,Rosetta 下也选 Apple 芯片)与 scripts/install.ps1(Windows x64/ARM64,按用户静默安装),都先校验 SHA256SUMS,不符则不安装。
  • 离线测试:scripts/test-install.sh(假 GitHub、假包管理器,14 种情况)与 scripts/test-install.ps1(pwsh,替换联网与注册表 cmdlet),两者都做过变异检查;接进 CI 的 Repository gates 与 make check。
  • install-scripts.yml 在真实 runner 上对最新正式版运行:Ubuntu x64/ARM64(apt 与 AppImage)、Fedora(dnf)、macOS、Windows x64/ARM64(irm | iex 方式)。非必需检查。

依赖与文档

  • deny.toml 原本禁止任何 HTTP/TLS crate;现在只允许经 tauri-plugin-updater 引入(wrappers),其他 crate 引入仍会失败。
  • README、文档站(中英)、docs/security.md、docs/release.md、docs/architecture.md:所有“从不联网”改为“只在检查更新时连接 GitHub”,写明检查发送什么、信任链和残余风险;新增 docs/acceptance/updates.md。

验证

  • make check 全部通过(crates 行覆盖率 97.96%,update.rs 100%;web 三个包 ≥98%);cargo deny check licenses bans sources advisories 通过。
  • 外壳测试用真实插件对本地 manifest 服务:验签通过、签名版本不符被拒、篡改被拒、404、断网。
  • make smoke-update:两个 release AppImage(9.0.0 → 9.0.1,临时密钥)在 Xvfb 下真实升级,磁盘上的 AppImage 被替换为 9.0.1,Lockra 从新文件重启。
  • 本地同步并构建文档站通过。
  • 未在真机验证:Windows、macOS 的实际升级,deb/rpm 的 pkexec 授权(docs/acceptance/updates.md 列出手动步骤)。0.1.x 没有更新器,0.2.0 起才能应用内升级。

🤖 Generated with Claude Code

- 核心新增 Updater port 与更新状态机:检查、下载进度、验签、安装后重启;自动检查默认关闭
- 外壳用 tauri-plugin-updater 实现,只有从安装包运行的副本可用;开启 requireSignedVersion 防止降级
- 发布时签名每个安装包,latest.json 按安装方式给出平台键(deb、rpm、AppImage、nsis、msi、app)
- scripts/install.sh 与 install.ps1:Linux、macOS、Windows 一键安装并校验 SHA256SUMS,附离线测试与真实 runner 工作流
- deny.toml 只允许经 tauri-plugin-updater 引入 HTTP 与 TLS;文档中“从不联网”的说法改为准确表述
- 匿名 API 按 IP 限流,macOS runner 上返回 403;共用出口 IP 的网络同样会遇到
- 改为下载 releases/latest/download/SHA256SUMS,从安装包文件名中读出版本号
@sunerpy
sunerpy merged commit bd84c36 into main Oct 1, 2026
16 checks passed
@sunerpy
sunerpy deleted the feat/in-app-updates branch October 1, 2026 12:33
@github-actions github-actions Bot mentioned this pull request Oct 1, 2026
sunerpy pushed a commit that referenced this pull request Oct 1, 2026
- Features: 增加应用内更新与各平台一键安装脚本 (#9)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant