跳到主要内容

发布体系:桌面、移动端、Web 与 OTA 如何同时交付

一、发布是架构的一部分

根目录的 workflow 不只是 CI 检查,还定义了版本、制品、渠道和平台责任:

  • build-desktop.yml / 相关工作流:Electron 构建、商店和发布制品;
  • build-android.ymlbuild-ios.yml:移动原生构建;
  • publish-ota.yml:移动 JS bundle、manifest、策略和同步;
  • tag.yml:从分支和版本信息创建 tag、触发构建;
  • sync.yaml:release 分支同步回 dev;
  • PR 质量、翻译和相似 issue 工作流:社区与维护流程。

这说明 Folo 的版本不是一个 npm version 能解释的字符串,而是平台化的 release graph。

二、版本的三层语义

应用版本

例如 apps/desktop/package.jsonversionruntimeVersionmainHash 服务于桌面构建、运行时和代码完整性。

原生运行时版本

Expo OTA 不能更新原生模块不支持的 JS。runtime_version 是兼容性闸门,必须和 bundle 的发布版本分开。

分发渠道

OTA workflow 明确接收 productionpreview channel。它影响 manifest、下载地址和更新策略,不应隐含在代码分支命名里。

三、OTA workflow 的安全链

publish-ota.yml 的核心过程是:

  1. 接收 release、runtime、channel 输入;
  2. 检查对应 mobile tag 存在;
  3. checkout tag;
  4. 安装 pnpm/Node 依赖;
  5. expo export 生成 bundle;
  6. 构建 ota-release.json 和压缩资产;
  7. 上传 GitHub Release 资产;
  8. 调用同步端点通知 OTA 服务。

这样做比“直接从 main 打包”更可靠:发布内容由不可变 tag 固定,workflow 的输入决定运行时和渠道,制品可回溯到源码。

四、OTA 服务端的职责

apps/ota/src 按 route/lib 拆分,包含 manifest、versions、policy、download、assets、internal、store-version、code-signing、GitHub、R2 和 KV 适配。

OTA Worker 不只是一个文件下载器,它还要回答:

  • 哪个客户端/平台可以看到哪个版本?
  • 当前 runtime 是否兼容?
  • 版本是否被 policy 禁用或强制升级?
  • 资产来自 GitHub Release 还是 R2?
  • 下载是否需要签名/校验?
  • 同步操作是否可重试且幂等?

五、制品证明与签名

README 提到代码签名、Apple notarization、SignPath 和 GitHub artifact attestations。对桌面和移动客户端,构建成功并不等于用户能安全安装;发布链还要证明:

  • 谁构建了制品;
  • 制品来自哪个 commit/tag;
  • 哪个平台签名;
  • 更新下载的是不是 workflow 生成的文件。

六、为什么 tag workflow 需要分支语义

tag.yml 监听 mainmobile-main,根据分支和 release 信息决定 desktop/mobile 平台,再触发对应构建。sync.yaml 反过来把 release 分支的提交同步到 dev

分支名在这里是产品发布状态的一部分,不只是 Git 协作偏好。改动发布分支、tag 规则或 workflow 输入时,必须把它当作状态机来评估。

七、Docusaurus 站点的发布

本拆解仓库使用独立的 deploy.yml

  1. main push 或手动触发;
  2. Node 20 + npm ci
  3. npm run build 生成静态 build
  4. upload-pages-artifact 上传构建产物;
  5. deploy-pages 发布到 GitHub Pages。

仓库设置需要将 Pages Source 设为 GitHub Actions。站点配置中的 urlbaseUrlprojectName 必须与实际仓库名一致,否则静态资源会出现 404。

八、生产化检查清单

  • tag 是否指向预期 commit;
  • native runtime 和 OTA bundle 是否兼容;
  • release asset 是否可下载、可校验;
  • workflow 权限是否最小化;
  • Pages 是否使用 Actions source;
  • Docusaurus 的 baseUrl 是否与 repository name 一致;
  • 构建失败时是否保留日志和可重试入口;
  • 回滚是回到旧 tag、旧 bundle 还是旧 policy。