ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Voquill发布流水线拆解:dev/prod双通道GitHub Actions自动更新系统内幕

Voquill发布流水线拆解:dev/prod双通道GitHub Actions自动更新系统内幕

【免费下载链接】voquill

Open source voice dictation technology

项目地址:https://gitcode.com/gh_mirrors/vo/voquill
点击查看免费下载

Voquill 是一款开源的语音听写工具,而它的桌面版之所以能做到"推送代码即自动发版、应用内自动更新",靠的是一套围绕 dev/prod 双通道设计的 GitHub Actions 发布流水线。这篇文章带你完整拆解 Voquill 自动更新系统内幕:从分支如何映射到发布频道,到版本号如何自动递增,再到 Tauri 更新器如何读取各自频道的latest.json清单,帮助你快速理解一套可复用的多通道 CI/CD 发布方案。

一、30 秒看懂双通道架构

Voquill 的发布模型非常经典:分支即频道。三条长期分支各自对应一条发布轨道,互不干扰:

分支发布频道覆盖组件
maindevCLI、桌面端、桌面端企业版(dev)、企业后台、企业网关
prodprodCLI、桌面端、官方文档
enterpriseenterprise桌面端企业版、企业后台、企业网关

这份对照表就写在仓库的 release/README.md 中,是整个流水线的"宪法"。

💡 核心思想:开发版走main自动发,正式版通过"晋升"操作从main合入prod后再发。普通用户装正式版,尝鲜用户装 dev 版,两边更新通道完全隔离。

二、发布流水线如何触发:编排器 + 变更检测

1. 编排器:按分支解析频道

入口文件是 release.yml,它监听main、prod、enterprise三个分支的 push 事件。第一个 job 会解析当前分支,把它翻译成频道名:

  • prod分支 →prod
  • enterprise分支 →enterprise
  • 其余(即main)→dev

这段逻辑在 release.yml 的 "Resolve channel from branch" 步骤中完成,只有 8 行 shell,却决定了后续所有组件走哪条轨道。

2. 路径过滤:没改动的组件不发布

编排器接着用dorny/paths-filter对比上一次提交,检测哪些目录变了:cli/、apps/desktop/、apps/docs/、enterprise/admin/等(见 release.yml)。

举个例子:如果你只提交了文档修改,只有 Docs 会部署;只改了 CLI,就只会构建发布 CLI。这大大节省了 CI 资源,也避免"改一行代码,六个组件全部重发"的浪费。

3. 发布结果自动播报

每个组件执行完后,notifyjob 会把"哪些组件发了、成功还是失败"汇总成一条消息,推送到 Google Chat 部署频道(release.yml)。没有 webhook 时直接跳过,不会报错——这是个很贴心的防御性设计。

三、dev 通道如何自动递增版本号

真正的重活由可复用工作流 _release-desktop-impl.yml 承担。它的metadatajob 是版本号的核心来源:

  1. 拉取全部 tag,按语义化版本排序找出各频道最新的 tag:desktop-dev-v*、desktop-v*、desktop-enterprise-v*等(见 _release-desktop-impl.yml);
  2. dev 通道自动 patch +1:比如最新 dev tag 是desktop-dev-v1.2.3,本次就发desktop-dev-v1.2.4,并直接打在main当前提交上(见 _release-desktop-impl.yml);
  3. tag 冲突直接中止:如果目标 tag 已存在立即报错退出,杜绝覆盖历史版本(见 _release-desktop-impl.yml)。

也就是说,开发者完全不需要手动改版本号——推代码,版本号、tag、Release 全部自动生成。

发布说明也不用手写:metadatajob 会按频道读取 release/prod.txt 或 release/enterprise.txt,直接作为 Release 的正文。

四、dev → prod 晋升:把"发正式版"变成一次合并

这是整套流水线最优雅的部分。发正式版不是复制代码、不是手动改配置,而是一次 fast-forward 合并:

  • 用main快进合并prod(或enterprise),push 即触发prod频道的发布;
  • prod频道的metadatajob 会找到对应的 dev tag(默认取最新的,也可手动指定某个x.y.z),把同一份 dev 提交重新打成正式 tagdesktop-v<version>重新发布(见 _release-desktop-impl.yml);
  • 回滚也很简单:把prod强制推回旧的 commit,流水线会自动重新发布差异组件。

这些流程在 docs/desktop-release.md 和 release/README.md 中有完整说明。🚀

五、自动更新的秘密:latest.json 与频道隔离

应用内"发现新版本"的能力来自 Tauri 更新器,而频道的隔离靠两份配置文件实现:

  • tauri.dev.conf.json:更新端点指向desktop-dev频道的latest.json;
  • tauri.prod.conf.json:更新端点指向desktop-prod频道的latest.json。

构建时,CI 先用 set-tauri-release-config.mjs 把自动计算的版本号写入 tauri.conf.json,并注入更新器公钥;再由tauri-action生成签名安装包和latest.json上传到版本化 Release。

最后一步是"频道发布":update-channeljob 把本次构建的latest.json覆盖上传到固定的频道 tag(如desktop-prod)下(见 _release-desktop-impl.yml)。

于是形成了两级结构:

  • 版本化 Release(desktop-dev-v1.2.4等):存放具体安装包,永久保留;
  • 频道 Release(desktop-dev/desktop-prod):永远只放最新的latest.json,指向对应的版本化资源。

客户端侧,Voquill 桌面端每分钟自动检查一次更新(AppSideEffects.tsx),发现新版本时托盘图标切换为"有更新"样式;用户如果忽略更新弹窗,三天内不再打扰(updater.actions.ts)。更新逻辑封装在 packages/desktop-utils/src/updater.ts 中。

六、三大平台构建与安装渠道分发

buildjob 用矩阵并行构建三个平台(见 _release-desktop-impl.yml),各自带上了"平台必修课":

平台关键步骤
macOS(universal 双架构)导入 Developer ID 证书、代码签名、Apple 公证(notarize + staple)、额外打包 DMG 和 PKG 安装包
WindowsAzure Trusted Signing 对 NSIS 安装器和便携版安装器签名并验证 Authenticode 签名,随包附带 VC++ 运行时 DLL
Linux安装 Vulkan SDK 等系统依赖,构建 deb/AppImage/RPM

构建完成只是开始,流水线还会把安装包分发到各主流安装渠道(仅限 dev/prod 频道,企业版除外):

  • APT 仓库:prod进stable,dev进devcodename,用 reprepro 入库(_release-desktop-impl.yml);
  • RPM 仓库:rpmsign签名 +createrepo_c更新元数据(_release-desktop-impl.yml);
  • Homebrew:自动生成 cask 并推送到官方 tap(_release-desktop-impl.yml)。

CLI 的发布逻辑(release-cli.yml)与之同构:voquill-dev二进制指向 dev 后端,正式版叫voquill,同样分发到 APT/RPM/Homebrew。

七、可靠性设计:自动重试与并发保护

  • 失败自动重试:GitHub 不允许任务重跑自己所在的 run,所以单独写了 retry-release.yml——监听主流水线结束,若结论是失败且重试次数未达 3 次,就调用gh run rerun --failed只重跑失败的 job。网络抖动、runner 偶发故障由此自愈。
  • 并发保护:主流水线按分支设置 concurrency group(release.yml),避免同一分支的多次 push 互相踩踏。
  • PR 阶段预构建:build-desktop.yml 在 Pull Request 阶段就用临时签名密钥跑一遍三平台构建,把"能构建成功"这个风险挡在合并之前。

八、小结:这套流水线值得抄作业的 5 个点

  1. 分支即频道:main/prod/enterprise与 dev/prod/enterprise 一一对应,心智模型极简;
  2. 路径过滤 + 编排器:只发布变动的组件,省资源、降噪;
  3. tag 即版本号:patch 自动递增、tag 冲突即中止,人工零介入且不可重复;
  4. 版本化 Release + 频道 latest.json 两层结构:历史版本可追溯,频道清单永远指向最新;
  5. 合并即发布、强推即回滚:把发版、回滚都变成 git 操作,权限与评审流程天然复用 PR 机制。

如果你正在为自己的 Tauri/Electron 桌面应用搭建发布流水线,可以从 docs/desktop-release.md 入手,对照.github/workflows/下的 release.yml、_release-desktop-impl.yml、release-cli.yml 三个文件,基本就能复刻出一套属于自己的 dev/prod 双通道自动更新系统。

【免费下载链接】voquill

Open source voice dictation technology

项目地址:https://gitcode.com/gh_mirrors/vo/voquill
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进