不想每次都手动换 DMG,我给砚接了自动更新
预览版一版接一版发,下载安装包、退出应用、拖到 Applications、替换,再打开。前几次还好,频繁起来,这套动作就显得有点重复。
alpha.11 开始,砚可以在「帮助 → 检查更新」里完成下载、安装和重启,也会每天检查一次。不想自动检查,可以在同一个菜单里关掉。
接这个功能时,真正花心思的地方在下载按钮后面。
安装包得先让人拿得到
源码仓库目前是私有的。更新器如果直接去那里下载,每个人都得先解决 GitHub 权限,这个更新入口就不太能用了。
我把安装包放到单独的公开仓库 yan-releases。源码和 Git 历史留在原仓库,发布脚本只上传明确列出的分发文件。
这样分享下载地址、应用自动检查更新,都不再依赖读者登录 GitHub。这也是这组博客现在能直接附安装链接的原因。
下载完,先确认拿到的东西对不对
更新接入 MyGo 的原生更新器,使用 Ed25519 签名验证下载内容。公钥跟应用一起分发,私钥放在仓库之外。校验不对,就不能替换应用。
这里有两种“签名”,很容易说混:更新包签名用来核验更新内容;Apple Developer ID 和公证处理的是 macOS 分发信任。做了前一种,后一种不会自动完成。目前安装包仍是 ad-hoc 签名、没有 Apple 公证。
验证时用的是可丢弃的应用目录,让下载器实际走替换流程,也分别喂过错误签名和损坏的压缩包。检查不能只做到“解析出了清单”。
alpha.9 到 alpha.11,也得算升级
版本号里有 alpha,比较时就要保留完整版本。只留下 0.1.0,两个预览包看起来全是同一版,自然检查不出更新。
预览版和稳定版也分开使用更新地址,避免一条清单把两个渠道搅在一起。
发布顺序则是先上传编号版本的资产,验证公开下载与签名,最后更新渠道清单。否则清单已经告诉应用“有新版”,文件却还没传完。
渠道清单提升单独留了重试入口。某一步失败以后,可以继续发布已经核验的版本,不用靠手改文件碰运气。
最后一步重启,不能把没保存的文件丢了
更新器想重启,编辑器却可能还有未保存内容。选择保存以后,重启请求要继续;取消、保存失败或者发生冲突,就留在当前窗口。
这部分还得防重入:关闭窗口触发保存,保存过程又牵出窗口事件,不能来回进入同一段关闭逻辑。
当时的原生验证用了独立应用副本和配置,真的创建窗口、保存文件、重启到新进程。验证替身回答了保存对话框,后面的进程和文件写入是实际执行的。
同批还把 Windows 后台 Git 进程的不弹控制台处理接进了统一进程入口。这里只做了相应测试与交叉编译,Windows 安装包还没交付。
自动更新做完,发一个新版终于不用再让试用的人重复搬安装包。分发本身也成了需要维护的一段功能:版本、文件、签名、重启,少接一步都不行。
下载试用
本文功能进入 v0.1.0-alpha.11,可以下载对应版本体验。
下载地址核对于 2026-10-19。安装包适用于 macOS 13+、Apple Silicon,目前尚未 Apple 公证,首次打开说明见发布页。
仓库留档
- 实现与设计:docs/automatic-updates.md、ui/gui/updates.go、internal/updatepack/pack.go、scripts/promote-updates.sh。
- 测试入口:ui/gui/updates_test.go、internal/updatepack/integration_test.go、ui/gui/updates_selftest.go。本轮只核对源码、历史报告与发布信息,没有重跑产品测试或安装包。