用 EAS Workflows 和自定义构建自动化移动端 CI/CD
EAS Workflows 让你用一个 YAML 文件就能自动化构建、测试、更新等流程。了解开箱即用的功能,以及需要时如何自定义。
中文
复制

EAS Build 刚推出时,构建流程能做的定制仅限于 eas.json 允许的范围。既没法跳过某些步骤,也没法用项目自己的实现替换它们。build hooks 虽然有用,但要用它在构建前后编排复杂流程,并不方便。
2023 年我们发布了完全可定制构建功能的预览版,开发者可以替换构建流程中的部分环节,也可以写出全新的构建流程。
如今这些能力已经并入 EAS Workflows——Expo 统一的 CI/CD 编排系统。你可以在单个 YAML 配置里定义完整流水线,包括构建、测试、提交、更新和通知。
Expo 已弃用 GitHub build triggers,改用 EAS Workflows,后者是更强大、更灵活的编排平台。
.eas/build 中的自定义构建任务配置决定单个构建任务如何执行;.eas/workflows 中的 EAS Workflows 配置决定包括构建任务在内的各个任务如何编排成完整流水线。
用 EAS Workflows 编排移动端 CI/CD 流水线
EAS Workflows 是 Expo 的 CI/CD 编排系统,用 YAML 定义的流水线把构建、测试、提交、更新和通知自动化。
Workflows 决定流水线何时运行、任务之间如何相互依赖。构建任务——包括自定义构建任务——作为组件在这些流水线中运行。
Workflows 定义在 .eas/workflows/*.yml 中,支持的触发方式包括:
-
push 和 pull request 事件
-
定时运行
-
手动执行
团队因此可以在一个系统里自动化整条移动端交付流水线。
on:
push:
branches: ['main']
pull_request:
branches: ['main']
schedule:
cron: '0 2 * * 1-5' # Weekdays at 2 AM UTC
任何 workflow 都可以用 eas workflow:run 手动运行,不受 on: 配置影响。路径过滤和基于标签的触发(pull_request_labeled)同样支持——参见触发器文档。

可定制构建的使用场景
过去几个月我们一直在和用户聊他们实际跑哪些流程,现在这些步骤可以直接作为 EAS Workflows 流水线的一部分运行,我们很高兴。下面是几个例子:
-
在单条流水线中为多个 target 创建归档。例如,在构建 Android 生产应用(.aab)的同时,额外生成一个用于测试的预览构建
-
构建成功后自动将构建提交到 TestFlight 或 Google Play(Android 示例、iOS 示例)
-
验证通过后发布 OTA 更新
这些构建任务和自动化步骤可以用 EAS Workflows 编排组合成完整的流水线。
预置任务:开箱即用的能力
除了自定义构建任务,EAS Workflows 还内置了常见移动端 CI/CD 场景的任务类型。这些任务无需自定义配置——只需在 YAML 中声明任务类型:
-
submit— 将构建提交到 App Store 或 Google Play -
testflight— 分发到 TestFlight 群组,支持 changelog 和 beta 审核控制 -
update— 通过 EAS Update 发布 OTA 更新 -
deploy— 通过 EAS Hosting 部署 Web 应用 -
maestro/maestro-cloud— 在模拟器上运行 Maestro E2E 测试 -
fingerprint— 对项目的原生特征做哈希,以判断何时需要完整构建 -
get-build— 查找与 fingerprint 匹配的现有构建,避免重复构建 -
repack— 在约 2 分钟内将 JS 重新打包到现有构建上,无需完整的原生重新构建 -
slack— 通过 webhook 发送 Slack 通知 -
github-comment— 自动将构建链接和二维码发布到 pull request -
require-approval— 用人工审批为生产部署设置关卡 -
doc— 在工作流日志中显示 Markdown 说明
完整的语法和示例见预置任务文档。
如何自定义构建
初始设置
构建 profile 配置接受一个 ,用于指定位于 .eas/build 下的自定义构建任务配置。这些自定义构建任务可以单独执行,也可以作为 EAS Workflows 流水线的一部分被编排。
这是一个示例:
{
"build": {
"production": {
// Builds with profile "production"
// will use .eas/build/production.yml file
"config": "production.yml"
},
// You can also specify platform-specific workflows
// by placing the property under platform-specific config.
"development": {
"android": {
// uses .eas/build/development-android.yml
"config": "development-android.yml"
},
"ios": {
// uses .eas/build/development-ios.yml
"config": "development-ios.yml"
}
}
}
}
自定义构建的基本流程
最简单的 Custom Builds 流程如下:
build:
steps:
- eas/build
The eas/build 函数会使用配置好的构建配置文件来构建你的应用。这一步也可以作为更大的 EAS Workflows 流水线的一部分,与测试、提交和部署任务一起编排。
Bash 步骤
我们再添加一个步骤,在构建成功后向 Discord 发送一条消息。
对于 Slack,EAS Workflows 内置了 slack 任务类型,无需自己编写脚本。下面展示的 run 步骤适用于没有内置支持的服务,比如 Discord 或 Microsoft Teams。
首先配置一个 Discord webhook。你可以参考这个 Discord 教程。
拿到 webhook URL 后,就可以在流程中添加一个 run 步骤:
build:
steps:
- eas/build
- run:
command: |
# Post a new message to Discord
# https://support.discord.com/hc/en-us/articles/228383668-Intro-to-Webhooks
curl \
-H 'Content-Type: application/json' \
-d '{"content": "New build succeeded! URL: ${ eas.job.expoBuildUrl }"}' \
https://discord.com/api/webhooks/... # your webhook URL here

run 命令会作为 Bash 脚本执行。你可以使用 curl、Fastlane、Node.js 脚本,或者任何自定义的自动化逻辑。
这些步骤同样可以集成到完整的 EAS Workflows 流水线中,与提交、测试、通知等其他任务一起运行。
自定义 JavaScript 函数
Bash 脚本适合处理简单的任务。对于更复杂的任务,我们建议编写 JS 函数。
这样做的好处是:
-
以类型化的方式访问构建属性
-
更容易在工作流之间复用
-
更好的可维护性
自定义函数既可以集成到自定义构建任务中,也可以集成到完整的 EAS Workflows 流水线中。如何配置请参考 EAS Build 文档中的“TypeScript functions”指南。
自定义 eas/build
如果你需要对构建过程做更深入的定制,可以把单个 eas/build 函数替换为它底层的各个步骤。
这样可以让你:
-
解锁加密的 secrets
-
修改构建环境
-
动态安装依赖
-
在构建前运行校验脚本
有四个主要示例可以作为起点(2 个平台 × 有无凭据):
-
带凭据的 Android(构建签名的 AAB)
-
Android 无凭据(构建 Emulator APK)
-
iOS 有凭据(构建可分发的 IPA)
-
iOS 无凭据(构建 Simulator APP)
复制之后,按需做相应修改。
例如,你可以解锁用 git-crypt 加密的文件。为此,先在 EAS 项目中添加一个 GIT_CRYPT_KEY 密钥,内容为 base64 编码的 key。在已解锁的环境中运行下面的命令,即可将其复制到剪贴板:
然后,确认项目已按 Full Git Workflow 配置好(eas.json 中的 cli.requireCommit 应设为 true)。接下来就可以在 eas/checkout 步骤之后加入下面这段 Bash 脚本。

在 EAS Workflows 中使用自定义构建任务
EAS Workflows 可以把构建任务当作组件,编排完整的流水线。
示例:
name: Build and Submit
on:
push:
branches: [main]
jobs:
build:
type: build
params:
platform: ios
profile: production
submit:
type: submit
needs: [build] # Only runs if build succeeds
params:
build_id: ${{ needs.build.outputs.build_id }}
notify:
type: slack
after: [build, submit] # Runs regardless of success or failure
params:
webhook_url: https://hooks.slack.com/services/...
message: 'Pipeline finished for ${{ needs.build.outputs.app_version }}'
needs 表示该任务仅在其依赖成功时才运行。after 表示无论依赖结果如何都会运行——适合做通知和清理。这样就能把移动端 CI/CD 流程完全自动化。
从旧版构建编排迁移
已有的自定义构建配置可以继续使用,并直接接入 Workflows 流水线。已经在用 GitHub Actions 或其他 CI 系统的团队不必放弃现有方案——可以用 eas workflow:run 从现有流水线调用 EAS Workflows,把 iOS 构建、代码签名、商店提交这类移动端专属任务交给 Workflows,而 lint、单元测试和代码审查仍由现有 CI 负责。
EAS 服务接下来会做什么?
构建项目只是交付高质量移动应用的一步。EAS Workflows 提供了一套完整的 CI/CD 编排系统,让团队在同一个平台上自动化构建、测试、提交和更新。
EAS Workflows 负责 CI/CD 流水线中移动端专属的部分——构建、代码签名、提交和 OTA 更新,全部直接在 Expo 项目内完成。
自定义构建任务依然重要,它让你能在这些流水线中深度定制构建行为。
我们正在持续扩展 EAS Workflows,新增任务类型、增强自动化能力,并深化集成,帮助团队更快、更可靠地交付。
欢迎在构建和自动化工作流的过程中向我们提供反馈。以下是一些不错的后续步骤:
-
部署到生产环境工作流 — 从指纹检测到提交商店的完整流水线
-
使用 Maestro 进行端到端测试 — 在每个 PR 上运行测试
-
预打包任务参考 — 所有任务类型的完整语法
-
工作流语法 — 完整的 YAML 规范