在 SWSH 基于 Expo 的自动化移动端发布流水线内部

SWSH 用一套 React Native 代码驱动四个平台,每月在自有硬件上跑 300 次构建,签名凭据团队从不经手。

中文
复制
Inside SWSH's automated mobile release pipeline with Expo

“Expo 的生态帮我们消除了发布流程中的人为失误和人力投入,从本地构建到验证发布都是如此。”

— Nathan Ahn,SWSH 首席技术官

一套代码,全平台

SWSH 是一款社交照片分享应用,用于共享相册和活动。一个团队要同时发布 iOS、iOS App Clip、Android 和 Web 版本,你大概会以为他们得维护四套构建工具,外加一份对应的发布清单。实际上,这一切都由同一套 React Native 代码驱动,发布时几乎不需要任何人手动推进。

SWSH 上架 App Store

这个案例讲的是 SWSH 如何走到这一步:每月在自己的硬件上跑 300 次构建,签名凭据团队从不经手,App Store Connect 通过 API 而不是浏览器操作,还有一套自己写的端到端测试套件,每次发布前都要跑一遍。

Web 走的是另一条独立的发布轨道,所以接下来的内容只讲三个原生目标。一次改动从本地构建开始,经过 iOS 模拟器和 Android 模拟器上的端到端测试套件,最后落到两个应用商店,全程几乎不需要人插手。原生版本大约每周发一次,流水线负责让它们安全落地。

让发布变成一件平常事

如果你发过移动应用,这条链路你肯定熟:出构建、处理签名凭据、提交到 App Store Connect 和 Google Play,然后确认这一路没出回归。手工做的话,每一步都是发布可能悄悄崩掉的地方,而且发得越频繁,这些错误的代价就越大。

所以 SWSH 直接对整个链路下手:把整条发布流水线自动化,让人为失误无处可入。 Expo 的构建和提交工具开箱就提供了这套自动化,而且底子足够扎实,可以在上面继续搭别的东西。

为什么 Expo 是运行自动化发布流水线的最佳基础设施

Expo 给 SWSH 提供了一条从源码到商店的单一自动化路径:构建、凭据、提交,以及 OTA 更新。

Continuous Native Generationexpo prebuild)让团队可以按需重新生成原生工程,而不必手工维护 Xcode 和 Gradle 工程;需要的时候,他们仍然可以直接写原生代码。而且因为 EAS 在本地和云端跑的是同一套构建工具,SWSH 可以拿来 EAS 的编排、凭据管理和提交能力,同时不必放弃对构建实际运行位置的控制权。

走进 SWSH 的发布流水线

规模化本地构建:EAS Build

对世界上几乎所有移动团队来说,Expo 的云端构建都是稳妥的选择。SWSH 是个例外,原因在于量:每个涉及原生代码的 pull request 都要跑完整的 iOS 和 Android 构建,再加上各环境的发布构建,一个月加起来有 300 次。到了这个量级,账就不一样了,于是团队用 本地 EAS 构建,把编译搬到了自己的 macOS 和 Android runner 上。

EAS 有一点很容易被忽略。因为 eas build 在本地的行为和在云端一致,所以 SWSH 保留了编排、凭据处理和提交环节,只把最吃资源的编译步骤挪到自己的硬件上。

团队从不需要管理的凭据:EAS

App Store Connect 和 Google Play 的签名凭据都存放在 EAS 里。SWSH 的 CI 只持有一个 Expo access token,仅此而已。代码签名是移动端发布中最不该散落在 CI 配置或仓库里的东西,而在 SWSH 这里,它压根就不在那里。

提交到两个商店:EAS Submit 与自定义的 App Store Connect 流水线

智能体发布流水线

EAS Submit 负责向两个商店提交,把每次构建直接推送到 Google Play 和 App Store Connect,无需任何自定义胶水代码。在 Google Play 上,这就够了。iOS 则要求围绕二进制文件做更多事情:新建一个 App Store 版本、元数据和发布说明、配置好的 App Clip 体验,以及提交审核。

因此,SWSH 在 EAS Submit 之外,自己搭了一条 App Store Connect 流水线。构建上传完成后,这条流水线直接调用 App Store Connect API。它轮询已处理完成的构建,创建 App Store 版本,并设置元数据和「What's New」文案。接着配置 App Clip 的默认体验,细到卡片副标题和卡片图片,最后提交版本审核。

如果你手动配置过 App Clip 体验,就知道那要开多少个窗口。SWSH 把整件事变成了发布流程里又一个自动化步骤。

SWSH 通过自定义流水线管理 App Store 元数据,而不是用 EAS Metadata——Expo 的声明式元数据方案。大多数团队不需要自己写一条,直接用 EAS Metadata 就好。

验证每一次发布:Meridian

在任何东西发布之前,SWSH 都会跑一遍 Meridian——他们自研的端到端测试框架,基于 Appium 和 WebDriverIO,由 Vitest 驱动。Meridian 在 CI 中的模拟器和仿真器上,覆盖 iOS、App Clip 和 Android,跑通真正重要的流程:登录、注册、上传和深度链接。所以当 SWSH 说一次发布已经通过验证,意思是应用真的被驱动着走完了这些流程,而不只是编译成功。

SWSH 验证门禁与端到端测试

交付 JS 修复:EAS Update

对于不涉及原生代码的改动,EAS Update 让 SWSH 可以立即推送 JavaScript 修复。

Meridian 同样会验证这些更新,这一点值得借鉴。EAS Update 是将新的 JavaScript 投递到用户手中已有的原生构建上,因此 SWSH 会针对更新后的 bundle 跑一遍测试套件,确认新代码与它所落到的那个构建兼容,并且没有引入回归。

在生产环境中捕获回归:EAS Observe

发布并不是终点。SWSH 用 EAS Observe 监控生产环境中的应用表现,跟踪首次渲染、可交互时间等运行时指标。一旦某个版本引入了启动或渲染回归,就会在这里暴露出来,团队可以直接通过空中推送修复。

自动化发布流水线带来的影响

工程师推完改动就可以去做别的事。流水线替他们完成每个版本的构建、验证、提交和监控,每月大约 300 次构建,原生版本大约每周一次,JavaScript 修复当天就能通过空中推送发出。

SWSH 证明了高频发布和安全发布并非取舍关系。把流水线一次性做对,原本花在发布琐事上的精力就能重新回到应用本身。

来源: Expo Blog← 返回首页