EAS Workflows 中的预打包作业

编辑页面

了解如何在 EAS Workflows 中设置和使用预打包作业。


For the complete documentation index, see llms.txt. Use this Use this file to discover all available pages.

预打包作业是即用型工作流作业,可帮助你自动化构建、提交和测试应用等常见任务。它们提供了一种标准化方式来处理这些操作,而无需从头编写自定义作业配置。本指南将介绍可用的预打包作业,以及如何在工作流中使用它们。

构建

将你的项目构建为 Android 或 iOS 应用。

构建作业可以自定义,因此你可以在构建过程中执行自定义命令。更多信息请参见 自定义构建

前提条件

要成功使用构建作业,你需要使用与预打包作业相同的平台和配置文件,通过 EAS CLI 完成一次构建。了解如何 创建你的第一个构建 以开始使用。

语法

jobs: build_app: type: build runs_on: string # 可选 - 可用选项请参见 https://docs.expo.dev/build-reference/infrastructure/ params: platform: android | ios # 必填 profile: string # 可选 - 默认值:production message: string # 可选

参数

你可以向 params 列表传入以下参数:

参数类型描述
platformstring必填。 要构建的平台。可以是 androidios
profilestring可选。要使用的构建配置文件。默认值为 production
messagestring可选。附加到构建上的自定义消息。对应于运行 eas build 时的 --message 标志。

环境变量

如果你在构建过程中需要某些环境变量,可以将它们包含在你指定构建 profileeas.json 中。它们将从 EAS 环境变量 中提取。

输出

你可以在后续作业中引用以下输出:

输出类型描述
build_idstring创建的构建的 ID。
app_build_versionstring应用的版本代码/构建号。
app_identifierstring应用的包标识符/包名。
app_versionstring应用的版本。
channelstring构建所使用的更新通道。
distributionstring使用的分发方式。可以是 internalstore
fingerprint_hashstring构建的指纹哈希。
git_commit_hashstring构建所使用的 git 提交哈希。
platformstring创建构建所对应的平台。为 androidios
profilestring使用的构建配置文件。
runtime_versionstring使用的运行时版本。
sdk_versionstring使用的 SDK 版本。
simulatorstring是否为模拟器构建。

示例

以下是一些使用构建作业的实用示例:

针对特定平台的基础构建

此工作流会在你推送到 main 分支时构建你的 iOS 应用。

.eas/workflows/build-ios.yml
name: Build iOS app on: push: branches: ['main'] jobs: build_ios: name: Build iOS type: build params: platform: ios profile: production
同时为两个平台构建

此工作流会在你推送到 main 分支时并行构建 Android 和 iOS 应用。

.eas/workflows/build-all.yml
name: Build for all platforms on: push: branches: ['main'] jobs: build_android: name: Build Android type: build params: platform: android profile: production build_ios: name: Build iOS type: build params: platform: ios profile: production
使用环境变量构建

此工作流会使用可在构建过程中使用的自定义环境变量来构建你的 Android 应用。

.eas/workflows/build-with-env.yml
name: Build with environment variables on: push: branches: ['main'] jobs: build_android: name: Build Android type: build env: APP_ENV: production API_URL: https://api.example.com params: platform: android profile: production
使用不同配置文件构建

此工作流使用不同配置文件创建两个不同的 Android 构建——一个用于内部分发,另一个用于提交到商店,分别使用 development 和 production 配置文件。

.eas/workflows/build-profiles.yml
name: Build with different profiles on: push: branches: ['main'] jobs: build_android_development: name: Build Android Development type: build params: platform: android profile: development build_android_production: name: Build Android Production type: build params: platform: android profile: production

部署

使用 EAS Hosting 部署你的应用程序。

前提条件

要使用 EAS Hosting 部署你的应用程序,你需要先设置你的项目。更多信息请参见 EAS Hosting 入门

语法

jobs: deploy_web: type: deploy params: alias: string # 可选 prod: boolean # 可选

参数

你可以向 params 列表传入以下参数:

参数类型描述
aliasstring可选。要部署到的 别名
prodboolean可选。是否部署到生产环境。

输出

你可以在后续作业中引用以下输出:

输出类型描述
deploy_jsonstring包含部署详情的 JSON 对象(npx eas-cli deploy --json 的输出)。
deploy_urlstring指向该部署的 URL。如果这是一个生产部署,则使用生产 URL。否则,使用第一个别名 URL 或部署 URL。
deploy_alias_urlstring指向该部署的别名 URL(例如,https://account-project--alias.expo.app)。
deploy_deployment_urlstring指向该部署的唯一 URL(例如,https://account-project--uniqueid.expo.app)。
deploy_identifierstring部署的标识符。
deploy_dashboard_urlstring指向部署仪表板的 URL(例如,https://expo.dev/projects/[project]/hosting/deployments)。

示例

以下是一些使用部署作业的实用示例:

部署到生产环境的基础示例

此工作流会使用 EAS Hosting 将你的应用程序部署到生产环境。

.eas/workflows/deploy-basic.yml
name: Basic Deployment jobs: deploy: name: Deploy to Production type: deploy params: prod: true
仅在合并到 `main` 分支时部署到生产环境

此工作流会在你合并到 main 分支时将应用程序部署到生产环境,并在所有其他分支上进行非生产环境部署。

.eas/workflows/deploy.yml
name: Deploy on: push: branches: ['*'] jobs: deploy: name: Deploy type: deploy params: prod: ${{ github.ref_name == 'main' }}
使用自定义别名进行部署

此工作流会将你的应用程序部署到生产环境中的一个自定义别名。

.eas/workflows/deploy-alias.yml
name: Deployment with Alias jobs: deploy: name: Deploy with Alias type: deploy params: alias: my-custom-alias prod: true

指纹

计算你的项目指纹。

注意: 此作业类型仅支持 CNG(托管) 工作流。如果你提交了 androidios 目录,指纹作业将无法工作。

注意: 为确保指纹与你的构建匹配,请使用与构建配置文件相同的 environment 设置。对于环境变量,我们建议使用 EAS 环境变量 而不是 env 字段,以获得更好的一致性。

语法

jobs: fingerprint: type: fingerprint environment: production | preview | development # 可选,默认值为 production env: # 可选的环境变量列表 ENV_VAR_NAME: value

环境变量

你可以向 env 参数传入一个环境变量列表。这些环境变量将从 EAS 环境变量 中提取。传入的 environment 参数将用于该环境变量所属的环境,当同一个环境变量在不同环境中都被定义时,这会很有用。

参数

你可以向 params 列表传入以下参数:

参数类型描述
unstable_skip_cng_checkboolean可选。是否跳过 Continuous Native Generation (CNG) 兼容性检查。默认值为 false

输出

你可以在后续作业中引用以下输出:

输出类型描述
android_fingerprint_hashstringAndroid 的指纹哈希。
ios_fingerprint_hashstringiOS 的指纹哈希。

示例

以下是一些使用指纹作业的实用示例:

基础指纹计算

此工作流会为 Android 和 iOS 构建都计算指纹。environment 应与构建配置文件匹配,以实现准确的指纹匹配。

.eas/workflows/fingerprint-basic.yml
name: Basic Fingerprint jobs: fingerprint: name: Calculate Fingerprint type: fingerprint environment: production
使用内联环境变量的指纹

注意: 如果你依赖内联环境变量,你需要始终确保在每个位置(构建配置文件、指纹作业、更新作业等)将正确的一组环境变量设置为正确的值,以确保指纹匹配。我们建议改用 EAS 环境变量 在那里你可以将变量集合分组到环境中,并在构建配置文件和工作流作业中引用它们。

.eas/workflows/fingerprint-with-env.yml
name: Fingerprint with Environment Variables jobs: fingerprint: name: Calculate Fingerprint type: fingerprint environment: production # 结果环境将是 "production" 环境与内联环境变量的并集。 # `env` 变量会覆盖 "production" 环境中同名的环境变量。 env: APP_VARIANT: staging API_URL: https://api.staging.example.com

获取构建

从 EAS 中检索一个与提供参数匹配的现有构建。

语法

jobs: get_build: type: get-build params: platform: ios | android # 可选 profile: string # 可选 distribution: store | internal | simulator # 可选 channel: string # 可选 app_identifier: string # 可选 app_build_version: string # 可选 app_version: string # 可选 git_commit_hash: string # 可选 fingerprint_hash: string # 可选 sdk_version: string # 可选 runtime_version: string # 可选 simulator: boolean # 可选 wait_for_in_progress: boolean # 可选

参数

你可以将以下参数传入 params 列表:

参数类型描述
platformstring可选。要获取构建的平台。可以是 iosandroid
profilestring可选。要使用的构建配置文件。
distributionstring可选。发布方式。可以是 storeinternalsimulator
channelstring可选。更新通道。
app_identifierstring可选。包标识符/包名。
app_build_versionstring可选。构建版本。
app_versionstring可选。应用版本。
git_commit_hashstring可选。git 提交哈希。
fingerprint_hashstring可选。指纹哈希。
sdk_versionstring可选。SDK 版本。
runtime_versionstring可选。运行时版本。
simulatorboolean可选。是否获取模拟器构建。
wait_for_in_progressboolean可选。是否等待匹配的进行中构建。默认:false

如果将 wait_for_in_progress 设置为 true,该任务仍会优先立即继续使用成功的构建,但也会查找进行中的构建。如果未找到成功的构建,任务将在继续前等待进行中的构建完成。如果匹配的构建成功,则任务将被标记为成功,并返回该成功构建。如果匹配的构建失败,则任务将被标记为成功,且其输出将为空 — 就像该构建未被匹配一样。

输出

你可以在后续任务中引用以下输出:

输出类型描述
build_idstring检索到的构建 ID。
app_build_versionstring应用的构建版本。
app_identifierstring应用的包标识符/包名。
app_versionstring应用版本。
channelstring构建所使用的更新通道。
distributionstring所使用的发布方式。
fingerprint_hashstring构建的指纹哈希。
git_commit_hashstring构建所使用的 git 提交哈希。
platformstring构建创建所针对的平台。
profilestring所使用的构建配置文件。
runtime_versionstring所使用的运行时版本。
sdk_versionstring所使用的 SDK 版本。
simulatorstring是否为模拟器构建。

示例

以下是一些使用 get-build 任务的实际示例:

获取最新生产构建

此工作流从 store 发布通道中检索 iOS 的最新生产构建。

.eas/workflows/get-build-production.yml
name: 获取生产构建 jobs: get_build: name: 获取最新生产构建 type: get-build params: platform: ios profile: production distribution: store channel: production
按版本获取构建

此工作流根据应用版本和构建版本检索 Android 构建的特定版本。

.eas/workflows/get-build-version.yml
name: 按版本获取构建 jobs: get_build: name: 获取特定版本构建 type: get-build params: platform: android app_identifier: com.example.app app_version: 1.0.0 app_build_version: 42
获取模拟器构建

此工作流为 iOS 开发检索一个模拟器构建。wait_for_in_progress 设置为 true,因此如果已经存在与过滤条件匹配的构建,任务将在继续之前等待其完成。

.eas/workflows/get-build-simulator.yml
name: 获取模拟器构建 jobs: get_build: name: 获取模拟器构建 type: get-build params: platform: ios simulator: true profile: development wait_for_in_progress: true

提交

使用 EAS Submit 将 Android 或 iOS 构建提交到应用商店。

前提条件

提交任务需要额外配置才能在 CI/CD 流程中运行。有关更多信息,请参阅我们的 Apple App Store CI/CD 提交指南Google Play Store CI/CD 提交指南

语法

jobs: submit_to_store: type: submit runs_on: string # 可选 - 可用选项见 https://docs.expo.dev/build-reference/infrastructure/ params: build_id: string # 必需 profile: string # 可选 - 默认:production

参数

你可以将以下参数传入 params 列表:

参数类型描述
build_idstring必需。要提交的构建 ID。
profilestring可选。要使用的提交配置文件。默认是 production

输出

你可以在后续任务中引用以下输出:

输出类型描述
apple_app_idstring已提交构建的 Apple App ID。
ios_bundle_identifierstring已提交构建的 iOS 包标识符。
android_package_idstring已提交构建的 Android 包 ID。

示例

以下是一些使用 submit 任务的实际示例:

提交 iOS 构建

此工作流使用 production 提交配置文件将 iOS 构建提交到 App Store。

.eas/workflows/submit-ios.yml
name: 提交 iOS 构建 jobs: build_ios: name: 构建 iOS type: build params: platform: ios profile: production submit: name: 提交到 App Store type: submit needs: [build_ios] params: build_id: ${{ needs.build_ios.outputs.build_id }} profile: production
提交 Android 构建

此工作流使用 production 提交配置文件将 Android 构建提交到 Play Store。

.eas/workflows/submit-android.yml
name: 提交 Android 构建 jobs: build_android: name: 构建 Android type: build params: platform: android profile: production submit: name: 提交到 Play Store type: submit needs: [build_android] params: build_id: ${{ needs.build_android.outputs.build_id }} profile: production

TestFlight

将 iOS 构建分发到 TestFlight 内部和外部测试组。这是 iOS submit 任务的替代方案,适用于你需要更高级的 TestFlight 功能时。如果你需要控制测试组、更新日志或 Beta App Review 提交,请使用 testflight 任务而不是 submit。

前提条件

TestFlight 任务需要使用 distribution: store 创建的 iOS 构建。你需要配置好 Apple Developer 账户。有关更多信息,请参阅 TestFlight 提交指南

语法

jobs: testflight_distribution: type: testflight runs_on: string # 可选 - 可用选项见 https://docs.expo.dev/build-reference/infrastructure/ params: build_id: string # 必需 profile: string # 可选 - 默认:production internal_groups: string[] # 可选 external_groups: string[] # 可选 changelog: string # 可选 submit_beta_review: boolean # 可选 wait_processing_timeout_seconds: number # 可选 - 默认:1800(30 分钟)

参数

你可以将以下参数传入 params 列表:

参数类型描述
build_idstring必需。要分发的 iOS 构建 ID。
profilestring可选。要使用的提交配置文件。默认是 production
internal_groupsstring[]可选。要将构建添加到的 TestFlight 内部组名称数组。仅包含未启用自动分发的组。
external_groupsstring[]可选。要将构建添加到的 TestFlight 外部组名称数组。
changelogstring可选。TestFlight 测试者的测试说明(“要测试什么”)。
submit_beta_reviewboolean可选。是否提交进行 Beta App Review。如果未指定,当提供 external_groups 时默认为 true,否则为 false
wait_processing_timeout_secondsnumber可选。等待 App Store Connect 构建处理完成的超时时间(秒)。默认为 1800(30 分钟)。

输出

你可以在后续任务中引用以下输出:

输出类型描述
apple_app_idstring已提交构建的 Apple App ID。
ios_bundle_identifierstring已提交构建的 iOS 包标识符。

示例

以下是一些使用 TestFlight 任务的实际示例:

包含内部和外部组的完整分发

此工作流带有更新日志,同时分发到内部和外部 TestFlight 组。

.eas/workflows/testflight-full.yml
name: TestFlight 分发 jobs: build_ios: name: 构建 iOS type: build params: platform: ios profile: production testflight: name: 分发到 TestFlight type: testflight needs: [build_ios] params: build_id: ${{ needs.build_ios.outputs.build_id }} internal_groups: ['QA Team'] external_groups: ['Public Beta'] changelog: | 此版本的新内容: - 新功能 - 错误修复
仅上传更新日志

此工作流上传一个带有更新日志的构建,但不指定任何要显式添加到的组。该构建将仅被添加到启用了“自动分发”的内部组。

.eas/workflows/testflight-changelog.yml
name: TestFlight with Changelog jobs: testflight: name: 上传更新日志 type: testflight params: build_id: ${{ needs.build_ios.outputs.build_id }} changelog: "${{ github.commit_message || '错误修复' }}" # github.commit_message 仅在 push 和 schedule 事件中可用。

更新

使用 EAS Update 发布更新。

前提条件

要发布更新预览并进行空中更新,你需要运行 npx eas-cli@latest update:configure,然后创建新的构建。了解更多关于 配置 EAS Update

语法

jobs: publish_update: type: update environment: production | preview | development # 可选,默认为 production env: # 可选的环境变量列表 ENV_VAR_NAME: value runs_on: string # 可选 - 可用选项请参见 https://docs.expo.dev/build-reference/infrastructure/ params: message: string # 可选 platform: string # 可选 - android | ios | all,默认为 all branch: string # 可选 channel: string # 可选 - 不能与 branch 同时使用 private_key_path: string # 可选 upload_sentry_sourcemaps: boolean # 可选 - 默认为“尝试上传,但如果失败不使作业失败”

环境变量

你可以通过 env 参数传入一个环境变量列表。这些环境变量将从 EAS 环境变量 中提取。传入的 environment 参数将用于该环境变量的环境,这在同一个环境变量跨不同环境定义时很有用。

参数

你可以将以下参数传入 params 列表:

参数类型描述
messagestring可选。用于更新的消息。如果未提供,将使用提交信息。
platformstring可选。用于更新的平台。可以是 androidiosall。默认为 all
branchstring可选。用于更新的分支。如果未提供,将使用工作流运行中的分支。对于手动运行的工作流,你需要提供一个值。示例:${{ github.ref_name || 'testing' }}。请提供 branchchannel 其一,不要同时提供。
channelstring可选。用于更新的频道。请提供 branchchannel 其一,不要同时提供。
private_key_pathstring可选。包含与 EAS Update 配置 中证书对应的、经 PEM 编码的私钥文件路径。你可以使用 "$VARIABLE_NAME" 语法引用一个文件类型的 EAS 环境变量。这等同于向 EAS CLI 传递 --private-key-path
upload_sentry_sourcemapsboolean可选。是否上传 Sentry sourcemaps。如果值为 true,作业将上传 Sentry source maps,并在上传失败时使作业失败。如果值为 false,作业将不会上传 sourcemaps 到 Sentry。如果未提供该值,作业将检查是否安装了 @sentry/react-native,如果已安装,则尝试上传 sourcemaps。如果失败,则只会打印错误信息,并继续执行,且作业仍会被标记为成功。

输出

你可以在后续作业中引用以下输出:

输出类型描述
first_update_group_idstring第一个更新组的 ID。
updates_jsonstring包含所有更新组信息的 JSON 字符串。

示例

以下是一些使用 update 作业的实际示例:

发布到生产频道的基础更新

当你推送到 main 分支时,此工作流会使用提交信息作为更新消息,将更新发布到生产频道。

.eas/workflows/update-production.yml
name: Update Production on: push: branches: ['main'] jobs: update_production: name: Update Production Channel type: update params: channel: production
按平台分别更新

此工作流会分别为 Android 和 iOS 平台发布更新,从而允许进行平台特定的更改。

.eas/workflows/update-platforms.yml
name: Platform-specific Updates on: push: branches: ['main'] jobs: update_android: name: Update Android type: update params: platform: android channel: production update_ios: name: Update iOS type: update params: platform: ios channel: production
基于分支部署的更新

此工作流会根据分支名称发布更新,从而可以基于分支使用不同的环境(staging/production)。

.eas/workflows/update-branches.yml
name: Branch-based Updates on: push: branches: ['main', 'staging'] jobs: update_branch: name: Update Branch type: update params: branch: ${{ github.ref_name }} message: 'Update for branch: ${{ github.ref_name }}'

Maestro

在 Android 模拟器或 iOS 模拟器构建上运行 Maestro 测试。

Maestro 测试处于 alpha 阶段。

语法

jobs: run_maestro_tests: type: maestro environment: production | preview | development # 可选 - 默认为 preview image: string # 可选 - 可用镜像列表请参见 https://docs.expo.dev/build-reference/infrastructure/ params: build_id: string # 必需 flow_path: string | string[] # 必需 shards: number # 可选 - 默认为 1 retries: number # 可选 - 默认为 1 record_screen: boolean # 可选 - 默认为 false include_tags: string | string[] # 可选 exclude_tags: string | string[] # 可选 maestro_version: string # 可选 - 默认为 latest android_system_image_package: string # 可选 device_identifier: string | { android: string, ios: string } # 可选 output_format: string # 可选 - 默认为 junit

参数

你可以将以下参数传入 params 列表:

参数类型描述
build_idstring必需。要测试的构建 ID。
flow_pathstring or string[]必需。要运行的 Maestro flow 文件或目录路径。
shardsnumber可选且实验性。将测试拆分成的分片数量。默认为 1。
retriesnumber可选。失败测试的重试次数。默认为 1。
record_screenboolean可选。是否录制屏幕。默认为 false。注意:录屏可能会影响模拟器性能。录屏时你可能希望使用 large runners。
include_tagsstring or string[]可选。要在测试中包含的 flow 标签。将作为 --include-tags 传递给 Maestro。
exclude_tagsstring or string[]可选。要从测试中排除的 flow 标签。将作为 --exclude-tags 传递给 Maestro。
maestro_versionstring可选。用于测试的 Maestro 版本。如果未提供,将使用最新版本。
output_formatstring可选。Maestro 测试报告格式。默认为 junit。将作为 --format 传递给 Maestro。可以是 junit 或其他受支持的格式。
android_system_image_packagestring可选。要使用的 Android Emulator 系统镜像包。在你的机器上运行 sdkmanager --list 以列出可用包。选择 x86_64 变体。示例:system-images;android-36;google_apis;x86_64system-images;android-35-ext15;google_apis_playstore;x86_64。注意,更高版本的镜像需要更多计算资源,因此你可能希望使用 large runners。
device_identifierstring or { android?: string, ios?: string } object可选。用于测试的设备标识符。你也可以使用单值表达式,例如 pixel_6iPhone 16 Plus${{ needs.build.outputs.platform == "android" ? "pixel_6" : "iPhone 16 Plus" }},以及对象形式 device_identifier: { android: "pixel_6", ios: "iPhone 16 Plus" }。注意,iOS 设备可用性因 runner 镜像而异。可用设备列表可在作业日志中找到。
skip_build_checkboolean可选。跳过对构建的验证(即 iOS 构建是否为模拟器构建)。默认为 false。

示例

以下是一些使用 Maestro 作业的实际示例:

基础 Maestro 测试

此工作流使用默认设置在 iOS 模拟器构建上运行 Maestro 测试。

.eas/workflows/maestro-basic.yml
name: Basic Maestro Test jobs: test: name: Run Maestro Tests type: maestro environment: preview params: build_id: ${{ needs.build_ios_simulator.outputs.build_id }} flow_path: ./maestro/flows
带分片的 Maestro 测试

此工作流在 Android 模拟器构建上运行 Maestro 测试,使用 3 个分片和 2 次失败重试。

.eas/workflows/maestro-sharded.yml
name: Sharded Maestro Test jobs: test: name: Run Sharded Maestro Tests type: maestro environment: preview runs_on: linux-large-nested-virtualization params: build_id: ${{ needs.build_android_emulator.outputs.build_id }} flow_path: ./maestro/flows shards: 3 retries: 2
使用带 Maestro 前缀的环境变量

当变量以 MAESTRO_ 为前缀时,Maestro 可以在工作流中自动读取环境变量。更多信息请参见 Maestro 关于 shell 变量的文档

.eas/workflows/maestro-basic.yml
name: Basic Maestro Test jobs: test: name: Run Maestro Tests type: maestro env: MAESTRO_APP_ID: 'com.yourhost.yourapp' params: build_id: ${{ needs.build_ios_simulator.outputs.build_id }}
录制屏幕并使用特定设备

此工作流在 Android 模拟器构建上运行 Maestro 测试,使用特定设备并录制屏幕。

.eas/workflows/maestro-sharded.yml
name: Pixel E2E Test jobs: test: name: Run Maestro Tests type: maestro runs_on: linux-large-nested-virtualization params: build_id: ${{ needs.build_android_emulator.outputs.build_id }} device_identifier: 'pixel_6' record_screen: true android_system_image_package: 'system-images;android-35;default;x86_64'
保存截图和录屏

要保存由 Maestro 命令创建的资源(例如 takeScreenshotstartRecording),以便日后调试时使用,请使用 MAESTRO_TESTS_DIR 环境变量。

在你的 Maestro flow 文件中,指定资源位置:

maestro/flows/test-flow.yaml
appId: com.myapp --- - launchApp - startRecording: ${MAESTRO_TESTS_DIR}/my_recording - takeScreenshot: ${MAESTRO_TESTS_DIR}/my_screenshot - tapOn: '登录按钮' - takeScreenshot: ${MAESTRO_TESTS_DIR}/after_login_screenshot - stopRecording

这些资源将在 Artifacts 部分中的“Maestro Test Results”产物里可用。

Maestro Cloud

在 Maestro Cloud 上运行 Maestro 测试。

重要 这需要一个 Maestro Cloud 账户和 Cloud Plan 订阅。前往 Maestro 文档 了解更多。

语法

jobs: run_maestro_tests: type: maestro-cloud environment: production | preview | development # 可选 - 默认为 preview image: string # 可选 - 请参阅 https://docs.expo.dev/build-reference/infrastructure/ 了解可用镜像列表。 params: build_id: string # 必需 - 要测试的构建 ID。 maestro_project_id: string # 必需 - Maestro Cloud 项目 ID。示例:`proj_01jw6hxgmdffrbye9fqn0pyzm0`。 flows: string # 必需 - 要运行的 Maestro flow 文件或包含这些 flows 的目录路径。对应 `maestro cloud` 的 `--flows` 参数。 maestro_api_key: string # 可选 - 默认为 `$MAESTRO_CLOUD_API_KEY` include_tags: string | string[] # 可选 - 要包含在测试中的标签。将作为 `--include-tags` 传递给 Maestro。 exclude_tags: string | string[] # 可选 - 要从测试中排除的标签。将作为 `--exclude-tags` 传递给 Maestro。 maestro_version: string # 可选 - 测试中使用的 Maestro 版本。如果未提供,将使用最新版本。 android_api_level: string # 可选 - 测试中使用的 Android API 级别。将作为 `--android-api-level` 传递给 Maestro。 maestro_config: string # 可选 - 测试中使用的 Maestro `config.yaml` 文件路径。将作为 `--config` 传递给 Maestro。 device_locale: string # 可选 - 测试中使用的设备区域设置。将作为 `--device-locale` 传递给 Maestro。运行 `maestro cloud --help` 查看支持值列表。 device_model: string # 可选 - 测试中使用的设备型号。将作为 `--device-model` 传递给 Maestro。运行 `maestro cloud --help` 查看支持值列表。 device_os: string # 可选 - 测试中使用的设备操作系统。将作为 `--device-os` 传递给 Maestro。运行 `maestro cloud --help` 查看支持值列表。 name: string # 可选 - Maestro Cloud 上传的名称。对应 `maestro cloud` 的 `--name` 参数。 branch: string # 可选 - 覆盖 Maestro Cloud 上传来源的分支。默认情况下,如果工作流运行是由 GitHub 触发的,则使用该工作流运行所在的分支。对应 `maestro cloud` 的 `--branch` 参数。 async: boolean # 可选 - 异步运行 Maestro Cloud 测试。如果为 true,作业状态只会表示上传是否成功,_不会_表示测试是否通过。对应 `maestro cloud` 的 `--async` 参数。

参数

你可以将以下参数传入 params 列表:

参数类型描述
build_idstring必需。要测试的构建 ID。示例:${{ needs.build_android.outputs.build_id }}
maestro_project_idstring必需。要使用的 Maestro Cloud 项目 ID。对应 maestro cloud--project-id 参数。示例:proj_01jw6hxgmdffrbye9fqn0pyzm0。前往 Maestro Cloud 查找你的项目 ID。
flowsstring必需。要运行的 Maestro flow 文件或包含这些 flows 的目录路径。对应 maestro cloud--flows 参数。
maestro_api_keystring可选。用于 Maestro 项目的 API 密钥。默认情况下,将使用 MAESTRO_CLOUD_API_KEY 环境变量。对应 maestro cloud--api-key 参数。
include_tagsstring可选。要包含在测试中的标签。对应 maestro cloud--include-tags 参数。示例:"pull,push"
exclude_tagsstring可选。要从测试中排除的标签。对应 maestro cloud--exclude-tags 参数。示例:"disabled"
maestro_versionstring可选。要使用的 Maestro 版本。示例:1.30.0
android_api_levelstring可选。要使用的 Android API 级别。对应 maestro cloud--android-api-level 参数。示例:29
maestro_configstring可选。要使用的 Maestro config.yaml 文件路径。对应 maestro cloud--config 参数。示例:.maestro/config.yaml
device_localestring可选。将在用于测试的设备上设置的区域设置。对应 maestro cloud--device-locale 参数。示例:pl_PL
device_modelstring可选。要用于测试的设备型号。对应 maestro cloud--device-model 参数。示例:iPhone-11。运行 maestro cloud --help 查看支持值列表。
device_osstring可选。要用于测试的设备操作系统。对应 maestro cloud--device-os 参数。示例:iOS-18-2。运行 maestro cloud --help 查看支持值列表。
namestring可选。Maestro Cloud 上传的名称。对应 maestro cloud--name 参数。
branchstring可选。覆盖 Maestro Cloud 上传来源的分支。默认情况下,如果工作流运行是由 GitHub 触发的,则使用该工作流运行所在的分支。对应 maestro cloud--branch 参数。
asyncboolean可选。异步运行 Maestro Cloud 测试。如果为 true,作业状态只会表示上传是否成功,_不会_表示测试是否通过。对应 maestro cloud--async 参数。

重要 你需要在作业环境中设置 maestro_api_key 参数或 MAESTRO_CLOUD_API_KEY 环境变量。前往 Maestro Cloud 的“Settings”生成 API 密钥,然后前往 环境变量 将其添加到你的项目中。

输出

你可以在后续作业中引用以下输出:

输出类型描述
maestro_cloud_urlstringMaestro Cloud 上传结果页面的 URL。
total_flows_countnumber已执行的 flow 总数。
successful_flows_countnumber成功完成的 flow 数量(状态为 SUCCESS 或 WARNING)。
failed_flows_countnumber失败的 flow 数量(状态为 ERROR 或 STOPPED)。
successful_flow_names_jsonstring包含成功 flow 名称的 JSON 数组。
failed_flow_names_jsonstring包含失败 flow 名称的 JSON 数组。

注意: 当使用 async: true 模式时,只有 maestro_cloud_url 输出可以保证有效。其他输出(flow 数量和 flow 名称)可能无效或为空,因为作业不会等待上传完成,flows 也尚未执行。

示例

以下是一些使用 Maestro 作业的实际示例:

基础 Maestro Cloud 测试

此工作流使用默认设置在 iOS 模拟器构建上运行 Maestro 测试。

.eas/workflows/maestro-basic.yml
name: Basic Maestro Test jobs: test: name: 运行 Maestro 测试 type: maestro-cloud environment: preview params: build_id: ${{ needs.build_ios_simulator.outputs.build_id }} maestro_project_id: proj_01jw6hxgmdffrbye9fqn0pyzm0 flows: ./maestro/flows
使用带 Maestro 前缀的环境变量

当工作流中的变量以 MAESTRO_ 为前缀时,Maestro 可以自动读取该环境变量。有关更多信息,请参阅 Maestro 关于 shell 变量的文档

.eas/workflows/maestro-basic.yml
name: Basic Maestro Test jobs: test: name: 运行 Maestro 测试 type: maestro-cloud env: MAESTRO_APP_ID: 'com.yourhost.yourapp' params: build_id: ${{ needs.build_ios_simulator.outputs.build_id }} maestro_project_id: proj_01jw6hxgmdffrbye9fqn0pyzm0 flows: ./maestro/flows
在后续作业中使用 Maestro Cloud 输出

此工作流运行 Maestro Cloud 测试,然后在 Slack 通知中使用测试结果。

.eas/workflows/maestro-with-notification.yml
name: Maestro Cloud with Notification jobs: maestro_test: name: 运行 Maestro Cloud 测试 type: maestro-cloud environment: preview params: build_id: ${{ needs.build.outputs.build_id }} maestro_project_id: proj_xyz flows: ./maestro/flows notify: name: 发送测试结果 after: [maestro_test] type: slack environment: production params: webhook_url: ${{ env.SLACK_WEBHOOK_URL }} # 确保在正确的环境中进行设置(见上方 "environment: ...") message: '测试完成:${{ after.maestro_test.outputs.successful_flows_count }}/${{ after.maestro_test.outputs.total_flows_count }} 通过'

Slack

使用 Slack webhook URL 向 Slack 频道发送消息。

语法

jobs: send_slack_notification: type: slack params: webhook_url: string # 必需 message: string # 如果未提供 payload,则必需 payload: object # 如果未提供 message,则必需

参数

你可以将以下参数传入 params 列表:

参数类型描述
webhook_urlstring必需。用于发送消息的 Slack webhook URL。目前仅支持硬编码字符串。使用存储在 env 中的 webhook 即将支持,但尚未支持。
messagestring如果未提供 payload,则必需。要发送的消息。
payloadobject如果未提供 message,则必需。要发送的 Slack Block Kit payload。

示例

以下是使用 Slack 作业的一些实际示例:

基础构建通知

此工作流构建一个 iOS 应用,然后使用构建作业输出中的应用标识符和版本发送通知。

.eas/workflows/slack-build-notification.yml
name: Build Notification jobs: build_ios: name: Build iOS type: build params: platform: ios profile: production notify_build: name: Notify Build Status needs: [build_ios] type: slack params: webhook_url: https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX message: '针对应用 ${{ needs.build_ios.outputs.app_identifier }}(版本 ${{ needs.build_ios.outputs.app_version }})的构建已完成'
使用 Block Kit 的丰富构建通知

此工作流构建一个 Android 应用,并使用构建作业输出发送丰富通知。

.eas/workflows/slack-rich-notification.yml
name: Rich Build Notification jobs: build_android: name: Build Android type: build params: platform: android profile: production notify_build: name: Notify Build Status needs: [build_android] type: slack params: webhook_url: https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX payload: blocks: - type: header text: type: plain_text text: '构建已完成' - type: section fields: - type: mrkdwn text: "*应用:*\n${{ needs.build_android.outputs.app_identifier }}" - type: mrkdwn text: "*版本:*\n${{ needs.build_android.outputs.app_version }}" - type: section fields: - type: mrkdwn text: "*构建 ID:*\n${{ needs.build_android.outputs.build_id }}" - type: mrkdwn text: "*平台:*\n${{ needs.build_android.outputs.platform }}" - type: section text: type: mrkdwn text: '分发:${{ needs.build_android.outputs.distribution }}'

GitHub Comment

自动将你的工作流已完成的构建、更新和部署报告发布到 GitHub 拉取请求中。它特别适用于为 PR 构建提供即时反馈、通过二维码共享测试构建以便轻松在设备上测试、展示 EAS Hosting 部署预览,以及自动化部署通知。你也可以通过提供 payload 参数来覆盖评论内容。

前提条件

要使用 GitHub Comment 作业,你的项目必须已连接 GitHub 仓库。了解如何 连接你的 GitHub 仓库 以开始使用。

语法

jobs: github_comment: type: github-comment params: message: string # 可选 - 要包含在报告中的自定义消息 build_ids: string[] # 可选 - 要包含的特定构建 ID,默认是与正在运行的工作流相关的全部构建 update_group_ids: string[] # 可选 - 要包含的特定更新组 ID,默认是与工作流相关的全部更新 deployment_ids: string[] # 可选 - 要包含的特定部署 ID,默认是与工作流相关的全部部署 # 不使用 message 以及 builds、updates 和 deployments 表格的情况下,你也可以通过 `payload` 覆盖评论内容 custom_github_comment: type: github-comment params: payload: string # 可选 - 用于完全自定义评论的原始 markdown/HTML 内容

参数

该作业有两种互斥模式:

模式 1:自动发现并可覆盖模式

默认行为是自动发现构建和更新,如果你愿意,也可以指定以下任意参数:

参数类型描述
messagestring可选。要包含在评论顶部的自定义消息。默认为 "Your builds, updates, and deployments are ready for testing!"
build_idsstring[]可选。要包含的特定构建 ID 数组。如果未指定,则自动发现所有已完成/失败/已取消的构建。使用空数组 [] 可排除构建。
update_group_idsstring[]可选。要包含的特定更新组 ID 数组。如果未指定,则自动发现所有成功的更新。使用空数组 [] 可排除更新。
deployment_idsstring[]可选。要包含的特定部署 ID 数组。如果未指定,则自动发现所有成功的部署。使用空数组 [] 可排除部署。

自动发现行为:当未指定(即未定义)build_idsupdate_group_idsdeployment_ids 时,作业会自动发现当前工作流中所有相关的构建、更新和部署。若要明确排除构建、更新或部署,请传入空数组 []

模式 2:Payload 模式

使用 payload 模式时,不能指定任何其他参数。

参数类型描述
payloadstring作为评论发布的原始 markdown 或 HTML 内容。支持工作流变量插值。

输出

你可以在后续作业中引用以下输出:

输出类型描述
comment_urlstring已发布 GitHub 评论的 URL(仅在评论成功发布时可用)。

示例

以下是演示 GitHub Comment 作业两种模式的实际示例:

自动发现并可覆盖模式示例

自动发现所有构建、更新和部署

这是最简单的用法——自动发现并发布工作流中的所有构建、更新和部署。

.eas/workflows/pr-auto-comment.yml
name: PR Auto Comment on: pull_request: {} jobs: # ... comment_on_pr: name: Post Results to PR after: [build_ios, build_android, publish_update, deploy] type: github-comment # 无需 params - 自动发现所有构建、更新和部署
带自动发现的自定义消息

在自动发现所有构建、更新和部署的同时添加自定义消息。

.eas/workflows/pr-custom-message.yml
name: PR Custom Message on: pull_request: {} jobs: # ... comment_on_pr: name: Post Build to PR after: [build_ios, build_android, publish_update, deploy] type: github-comment params: message: '🎉 预览构建已就绪!请在批准 PR 之前测试这些更改。' # build_ids、update_group_ids 和 deployment_ids 未定义,因此已启用自动发现
带 EAS Hosting 部署的 PR 预览

此工作流使用 EAS Hosting 部署你网站的预览,并将部署详情发布到拉取请求中。

.eas/workflows/pr-preview.yml
name: PR Preview on: pull_request: {} jobs: deploy: type: deploy name: Deploy PR Preview comment: needs: [deploy] type: github-comment
指定确切的构建和更新

明确指定要包含在评论中的构建和更新。

.eas/workflows/pr-specific-builds.yml
name: PR Specific Builds on: pull_request: {} jobs: # ... comment_update: name: Post Update to PR after: [build_ios, build_android, publish_update] type: github-comment params: message: '等待 QA 审查的测试构建已就绪' build_ids: - ${{ after.build_ios.outputs.build_id }} - ${{ after.build_android.outputs.build_id }} update_group_ids: - ${{ after.publish_update.outputs.first_update_group_id }}
排除构建、更新或部署

使用空数组来排除特定内容类型。

.eas/workflows/pr-updates-only.yml
name: PR Updates Only on: pull_request: {} jobs: # ... comment_updates_only: name: Post Updates Only after: [publish_update] type: github-comment params: message: '有新的更新可供测试!' build_ids: [] # 空数组会排除所有构建 deployment_ids: [] # 空数组会排除所有部署 # update_group_ids 未定义 = 自动发现更新

Payload 模式示例

使用 payload 的完全自定义评论

Payload 模式让你可以完全控制评论内容。请注意,使用 payload 时,不能指定任何其他参数。

.eas/workflows/custom-pr-comment.yml
name: Custom PR Comment on: pull_request: {} jobs: # ... custom_comment: name: Post Custom Comment needs: [build_ios] type: github-comment params: # Payload 模式:完全控制内容 # 不能将 message、build_ids 或 update_group_ids 与 payload 一起使用 payload: | ## 🚀 构建状态更新 ### iOS 构建已完成 - **构建 ID**: `${{ needs.build_ios.outputs.build_id }}` - **版本**: ${{ needs.build_ios.outputs.app_version }} - **构建号**: ${{ needs.build_ios.outputs.app_build_version }} ### 下一步 1. 从 [EAS Dashboard](https://expo.dev/accounts/[account]/projects/[project]/builds/${{ needs.build_ios.outputs.build_id }}) 下载构建 2. 在实体设备上测试 3. 批准以进行 TestFlight 分发 --- *此评论由 EAS Workflows 自动生成*
基于构建状态的条件评论

此工作流会根据构建成功或失败发布不同的评论。

.eas/workflows/conditional-comment.yml
name: Conditional PR Comment on: pull_request: {} jobs: build_android: name: Build Android type: build params: platform: android profile: preview comment_success: name: Post Success Comment needs: [build_android] if: ${{ needs.build_android.status == 'success' }} type: github-comment params: message: '✅ Android 构建成功!可供测试。' build_ids: # 仅为说明目的提供,你也可以在这里省略它 - ${{ needs.build_android.outputs.build_id }} comment_failure: name: Post Failure Comment after: [build_android] if: ${{ after.build_android.status == 'failure' }} type: github-comment params: payload: | ❌ **Android 构建失败** 请查看 [工作流日志](https://expo.dev/accounts/[account]/projects/[project]/workflows) 以获取详情。

需要审批

在继续工作流之前,需要先获得用户的批准。用户可以批准或拒绝,这分别会转换为任务的成功或失败。

语法

jobs: require_approval: type: require-approval

参数

这个任务不接受任何参数。

示例

以下是一些使用 Require Approval 任务的实际示例:

在部署到生产环境之前请求批准

此工作流会先将一个 Web 应用部署到预览环境,然后在部署到生产环境之前要求用户批准。

.eas/workflows/web.yml
jobs: web_preview: name: 部署 Web 预览版 type: deploy require_approval: name: 将 Web 部署到生产环境? needs: [web_preview] type: require-approval web_production: name: 部署 Web 生产版 needs: [require_approval] type: deploy params: prod: true
控制工作流的流程

这个工作流通过在揭晓结局之前要求批准,让用户决定故事如何收尾。

.eas/workflows/dragon-knight-interactive.yml
jobs: show_story_intro: name: 龙与骑士故事开场 type: doc params: md: | # 龙与骑士 很久以前,在一个遥远的国度里,一位勇敢的骑士踏上征程,去面对一条强大的巨龙。 巨龙咆哮着,向山谷喷吐火焰,但骑士坚定不移,高举盾牌。 现在,他们这场相遇的命运掌握在你手中…… require_approval: name: 骑士和巨龙应该成为朋友吗? needs: [show_story_intro] type: require-approval happy_ending: name: 友谊结局 needs: [require_approval] type: doc params: md: | ## 一段新的友谊 骑士放下了剑,巨龙也停止了喷火。他们意识到彼此都渴望和平。从那天起,他们成为了最好的朋友,一起守护王国。 epic_battle: name: 史诗战斗结局 after: [require_approval] if: ${{ failure() }} type: doc params: md: | ## 史诗之战 骑士向前冲锋,巨龙发出震天怒吼。他们的战斗震动了群山,并在岁月中回响。最终,他们都被铭记为凶猛而高贵的对手。

文档

在工作流日志中显示一个 Markdown 区块。

语法

jobs: show_whats_next: type: doc params: md: string

参数

你可以向 params 列表传入以下参数:

参数类型描述
mdstring必需。要显示的 Markdown 内容。你可以使用 ${{ ... }} 工作流插值。

示例

以下是一些使用 Doc 任务的实际示例:

显示说明

此工作流会构建一个 iOS 应用,然后在工作流日志中显示一个 Markdown 区块。

.eas/workflows/build-and-submit-ios.yml
jobs: build_ios: name: 构建 iOS type: build params: platform: ios profile: production submit: name: 提交到 App Store type: submit needs: [build_ios] params: build_id: ${{ needs.build_ios.outputs.build_id }} profile: production next_steps: name: 后续步骤 needs: [submit] type: doc params: md: | # 接下来要做什么 你的应用刚刚已发送到 [App Store Connect](https://appstoreconnect.apple.com/apps)。 1. 从 TestFlight 下载应用。 2. 充分测试应用。 3. 提交应用进行审核。

重打包

基于现有构建对应用进行重新打包。此任务会重新打包应用的元数据和 JavaScript bundle,而不执行完整的原生重建,这对于创建与特定指纹兼容、速度更快的构建非常有用。

语法

jobs: repack: type: repack runs_on: string # 可选 - 可用选项请参见 https://docs.expo.dev/build-reference/infrastructure/ params: build_id: string # 必需 profile: string # 可选 embed_bundle_assets: boolean # 可选 message: string # 可选 repack_version: string # 可选

注意: 如果构建可能仍在进行中,请使用 get-build 并设置 wait_for_in_progress: true,然后将其 build_id 传递给 repack

常见问题

何时使用重打包,何时不使用?

Repack 任务适用于以下场景:

  • 通过复用现有构建来减少 CI 构建时间
  • 在需要时触发完整的原生构建
  • 为团队提供更快的反馈循环

Repack 任务不适用于以下场景:

  • 需要完整流程才能正确完成符号化和应用签名的生产构建

参数

你可以向 params 列表传入以下参数:

参数类型描述
build_idstring必需。要重打包的构建的源构建 ID。
profilestring可选。要使用的构建配置文件。默认使用从 build_id 获取的源构建配置文件。
embed_bundle_assetsboolean可选。是否将 bundle 资源嵌入到重打包后的构建中。默认会根据源构建自动确定。
js_bundle_onlyboolean可选。是否只重打包 JavaScript bundle。默认值为 false,表示会更新整个应用元数据。
messagestring可选。附加到构建上的自定义消息。对应于运行 eas build 时的 --message 标志。
repack_versionstring可选。要使用的 @expo/repack-app 版本。默认使用最新版本。

示例

以下是一些在 Repack 任务中使用 Fingerprint 的实际示例:

结合 Fingerprint 和 Repack 的持续部署

此工作流首先生成指纹,然后根据该指纹是否已存在兼容构建来决定是构建还是重打包应用。最后,它运行 Maestro 测试。

.eas/workflows/cd-fingerprint-repack.yml
name: continuous-deploy-fingerprint jobs: fingerprint: id: fingerprint type: fingerprint environment: production android_get_build: needs: [fingerprint] id: android_get_build type: get-build params: fingerprint_hash: ${{ needs.fingerprint.outputs.android_fingerprint_hash }} platform: android android_repack: needs: [android_get_build] id: android_repack if: ${{ needs.android_get_build.outputs.build_id }} type: repack params: build_id: ${{ needs.android_get_build.outputs.build_id }} android_build: needs: [android_get_build] id: android_build if: ${{ !needs.android_get_build.outputs.build_id }} type: build params: platform: android profile: preview-simulator android_maestro: after: [android_repack, android_build] id: android_maestro type: maestro image: latest params: build_id: ${{ needs.android_repack.outputs.build_id || needs.android_build.outputs.build_id }} flow_path: ['maestro.yaml'] ios_get_build: needs: [fingerprint] id: ios_get_build type: get-build params: fingerprint_hash: ${{ needs.fingerprint.outputs.ios_fingerprint_hash }} platform: ios ios_repack: needs: [ios_get_build] id: ios_repack if: ${{ needs.ios_get_build.outputs.build_id }} type: repack params: build_id: ${{ needs.ios_get_build.outputs.build_id }} ios_build: needs: [ios_get_build] id: ios_build if: ${{ !needs.ios_get_build.outputs.build_id }} type: build params: platform: ios profile: preview-simulator ios_maestro: after: [ios_repack, ios_build] id: ios_maestro type: maestro image: latest params: build_id: ${{ needs.ios_repack.outputs.build_id || needs.ios_build.outputs.build_id }} flow_path: ['maestro.yaml']