EAS 工作流语法

编辑页面

EAS Workflows 配置文件语法参考指南。


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

一个 workflow 是由一个或多个 job 组成的可配置自动化流程。你必须创建一个 YAML 文件来定义你的 workflow 配置。

要开始使用 workflows,请参阅 开始使用 EAS Workflows,或查看 示例 以获取完整的 workflow 配置。

Workflow 文件

Workflow 文件使用 YAML 语法,且必须具有 .yml.yaml 文件扩展名。如果你刚接触 YAML,并想了解更多,请参阅 在 1 分钟内学习 YAML

Workflow 文件位于项目中的 .eas/workflows 目录下。.eas 目录应与 eas.json 文件位于同一级别。

例如:

my-app
.eas
  workflows
   create-development-builds.yml
   publish-preview-update.yml
   deploy-to-production.yml
eas.json

配置参考

下面是 workflow 配置文件语法的参考。

name

workflow 的易读名称。它会显示在 EAS 仪表盘的 workflows 列表页上,并作为 workflow 详情页的标题。

name: 我的 workflow

on

on 键定义哪些 GitHub 事件会触发 workflow。无论 on 键如何,任何 workflow 都可以通过 eas workflow:run 命令触发。

on: # 在推送到 main 分支时触发 push: branches: - main # 以及在以 'version-' 开头的 pull request 上触发 pull_request: branches: - version-*
你可以在提交信息中包含 [eas skip][skip eas][no eas] 来跳过由 pushpull_request 触发的 workflow 运行。

on.push

当你向匹配的分支和/或标签推送提交时运行你的 workflow。

使用 branches 列表时,你可以仅在推送到这些指定分支时触发 workflow。例如,如果使用 branches: ['main'],只有推送到 main 分支才会触发 workflow。支持 glob。通过使用 ! 前缀,你可以指定要忽略的分支(你仍然需要提供至少一个不带 ! 的分支模式)。

使用 tags 列表时,你可以仅在推送这些指定标签时触发 workflow。例如,如果使用 tags: ['v1'],只有推送 v1 标签才会触发 workflow。支持 glob。通过使用 ! 前缀,你可以指定要忽略的标签(你仍然需要提供至少一个不带 ! 的标签模式)。

使用 paths 列表时,你可以仅在对匹配指定路径的文件进行更改时触发 workflow。例如,如果使用 paths: ['apps/mobile/**'],只有对 apps/mobile 目录中文件的更改才会触发 workflow。支持 glob。默认情况下,对任意路径的更改都会触发 workflow。

当未提供 branchestags 时,branches 默认为 ['*']tags 默认为 [],这意味着 workflow 会在所有分支的 push 事件上触发,而不会在 tag push 上触发。如果只提供其中一个列表,另一个默认为 []

on: push: branches: - main - feature/** - !feature/test-** # 其他分支名称和 glob tags: - v1 - v2* - !v2-preview** # 其他标签名称和 glob paths: - apps/mobile/** - packages/shared/** - !**/*.md # 忽略 markdown 文件

on.pull_request

当你创建或更新一个目标分支匹配的 pull request 时运行你的 workflow。

使用 branches 列表时,你可以仅在 pull request 的目标分支为这些指定分支时触发 workflow。例如,如果使用 branches: ['main'],只有合并到 main 分支的 pull request 才会触发 workflow。支持 glob。未提供时默认为 ['*'],这意味着 workflow 会在所有分支的 pull request 事件上触发。通过使用 ! 前缀,你可以指定要忽略的分支(你仍然需要提供至少一个不带 ! 的分支模式)。

使用 types 列表时,你可以仅在指定的 pull request 事件类型上触发 workflow。例如,如果使用 types: ['opened'],只有 pull_request.opened 事件(在 pull request 首次打开时发送)才会触发 workflow。未提供时默认为 ['opened', 'reopened', 'synchronize']。支持的事件类型:

  • opened
  • ready_for_review
  • reopened
  • synchronize
  • labeled

使用 paths 列表时,你可以仅在对匹配指定路径的文件进行更改时触发 workflow。例如,如果使用 paths: ['apps/mobile/**'],只有对 apps/mobile 目录中文件的更改才会触发 workflow。支持 glob。默认情况下,对任意路径的更改都会触发 workflow。

on: pull_request: branches: - main - feature/** - !feature/test-** # 其他分支名称和 glob types: - opened # 其他事件类型 paths: - apps/mobile/** - packages/shared/** - !**/*.md # 忽略 markdown 文件

on.pull_request_labeled

当 pull request 被匹配的标签标记时运行你的 workflow。

使用 labels 列表时,你可以指定当哪些标签被添加到 pull request 上时会触发 workflow。例如,如果使用 labels: ['Test'],只有为 pull request 添加 Test 标签才会触发 workflow。未提供时默认为 [],这意味着没有任何标签会触发 workflow。

你也可以直接向 on.pull_request_labeled 提供匹配标签列表,以获得更简洁的语法。

on: pull_request_labeled: labels: - Test - Preview # 其他标签

或者:

on: pull_request_labeled: - Test - Preview # 其他标签

on.app_store_connect

当所选的 App Store Connect 事件之一发生时运行你的 workflow。

要使用此触发器,请在 EAS 仪表盘 中配置你的 App Store Connect 连接。设置步骤请参阅 App Store Connect 触发器设置 部分。

当存在 on.app_store_connect 时,你必须至少指定一个事件域(app_versionbuild_uploadexternal_betabeta_feedback)。在已配置的事件域中,你可以指定哪些状态应触发 workflow。

on.app_store_connect.app_version.states

过滤应用商店应用版本状态变更事件。未提供时默认为所有受支持的应用版本状态。

支持的值:

  • accepted
  • developer_rejected
  • in_review
  • invalid_binary
  • metadata_rejected
  • pending_apple_release
  • pending_developer_release
  • prepare_for_submission
  • processing_for_distribution
  • ready_for_distribution
  • ready_for_review
  • rejected
  • replaced_with_new_version
  • waiting_for_export_compliance
  • waiting_for_review

on.app_store_connect.build_upload.states

按状态过滤构建上传事件。未提供时默认为所有受支持的构建上传状态。

支持的值:

  • complete
  • failed
  • processing
  • awaiting_upload

on.app_store_connect.external_beta.states

按状态过滤外部测试版事件。未提供时默认为所有受支持的外部测试版状态。

支持的值:

  • processing
  • processing_exception
  • missing_export_compliance
  • ready_for_beta_testing
  • in_beta_testing
  • expired
  • ready_for_beta_submission
  • in_export_compliance_review
  • waiting_for_beta_review
  • in_beta_review
  • beta_rejected
  • beta_approved

on.app_store_connect.beta_feedback.types

按测试人员报告的 beta 反馈类型进行过滤。未提供时默认为所有受支持的 beta 反馈类型。

支持的值:

  • crash
  • screenshot

所有过滤值都必须为小写,且区分大小写。

# 在以下情况触发: # - 应用版本进入审核, # - 构建上传完成或失败, # - 外部测试版构建已准备好测试或已批准, # - 测试人员通过 TestFlight 报告崩溃。 on: app_store_connect: app_version: states: - ready_for_review - waiting_for_review build_upload: states: - complete - failed external_beta: states: - ready_for_beta_testing - beta_approved beta_feedback: types: - crash
# 在任何应用版本或构建上传状态变更时触发。 on: app_store_connect: app_version: {} build_upload: {}

on.schedule.cron

使用 unix-cron 语法按计划运行你的 workflow。你可以使用 crontab guru 及其 示例 来生成 cron 字符串。

  • 计划任务 workflow 只会在仓库的默认分支上运行。在许多情况下,这意味着位于 main 分支上的 workflow 文件中的 cron 会被调度,而位于功能分支中的 workflow 文件中的 cron 则不会被调度。
  • 在高负载期间,计划任务 workflow 可能会延迟。高负载时段包括每小时的开始时间。在极少数情况下,job 可能会被跳过或运行多次。请确保你的 workflow 具有幂等性,并且不会产生有害的副作用。
  • 一个 workflow 可以有多个 cron 计划。
  • 计划任务 workflow 以 GMT 时区运行。
on: schedule: - cron: '0 0 * * *' # 每天 GMT 午夜运行

on.workflow_dispatch.inputs

定义通过使用 eas workflow:run 命令手动触发 workflow 时可提供的输入。这使你能够创建可参数化的 workflows,每次运行时都可以接受不同的值。

on: workflow_dispatch: inputs: name: type: string required: false description: '要问候的人的名字' default: 'World' choice_example: type: choice options: - to be - not to be required: true
属性类型必填描述
typestring输入类型(stringbooleannumberchoiceenvironment)。
descriptionstring输入的描述。
requiredboolean该输入是否必填。默认为 false
defaultvaries输入的默认值。必须与输入类型匹配。
optionsstring[](针对 type: choicechoice 输入可用的选项。

提供输入

运行带输入的 workflow 时,你可以通过以下几种方式提供输入:

  1. 命令行标志:

    Terminal
    eas workflow:run .eas/workflows/deploy.yml -F environment=production -F debug=true -F version=1.2.3
  2. 通过 stdin 传入 JSON:

    Terminal
    echo '{"environment": "production", "debug": true, "version": "1.2.3"}' | eas workflow:run .eas/workflows/deploy.yml
  3. 交互式提示: 如果缺少必填输入且你没有使用 --non-interactive,CLI 将提示你输入这些值:

    Terminal
    eas workflow:run .eas/workflows/deploy.yml

用法

输入值可通过 ${{ inputs.<input_name> }} 语法在 workflow 的 jobs 中使用:

on: workflow_dispatch: inputs: name: type: string required: true description: '要问候的人的名字' jobs: deploy: steps: - name: Deploy to environment run: | echo "Hello, ${{ inputs.name }}!" # 注意:你可以使用 `||` 提供默认值 # 适用于非 eas-workflow:run-run workflows。 echo "Hello, ${{ inputs.name || 'World' }}!"

jobs

一个 workflow 运行由一个或多个 job 组成。

jobs: job_1: # ... job_2: # ...

jobs.<job_id>

每个 job 都必须有一个 ID。该 ID 在 workflow 内应唯一,并且可以包含字母数字字符和下划线。例如,下面 YAML 中的 my_job

jobs: my_job: # ...

jobs.<job_id>.name

在 workflow 详情页上显示的、便于人类理解的 job 名称。

jobs: my_job: name: Build app

jobs.<job_id>.environment

为该 job 设置 EAS 环境变量 环境。有三种可选值:

  • production(默认)
  • preview
  • development

environment 键可用于所有 job。

jobs: my_job: environment: production | preview | development

jobs.<job_id>.env

为该 job 设置环境变量。该属性可用于所有运行在 VM 上的 job(除预封装的 apple-device-registration-requestrequire-approvaldocget-buildslack jobs 外的所有 job)。

jobs: my_job: env: APP_VARIANT: staging RETRY_COUNT: 3 PREV_JOB_OUTPUT: ${{ needs.previous_job.outputs.some_output }}

jobs.<job_id>.hooks

某些预封装 job 支持 hooks,用于在主 job 动作之前或之后运行额外步骤(例如 maestro-cloudmaestrosubmit)。hook 名称因 job 而异。可用的 hook 键请参阅该 job 的文档。

jobs: maestro_test: type: maestro-cloud params: build_id: ${{ needs.build.outputs.build_id }} maestro_project_id: proj_xyz flows: ./maestro/flows hooks: before_maestro_cloud: - run: echo "Before upload" after_maestro_cloud: - run: echo "After upload"

jobs.<job_id>.defaults.run.working_directory

设置该 job 中所有步骤执行命令的目录。

jobs: my_job: defaults: run: working_directory: ./my-app steps: - name: My first step run: pwd # 输出:/home/expo/workingdir/build/my-app

defaults

用于作为 workflow 配置中所有 job 默认值的参数。

defaults.run.working_directory

运行脚本的默认工作目录。诸如 "./assets" 或 "assets" 这样的相对路径会从应用的基础目录解析。

defaults.tools

该 workflow 配置中所定义 job 应使用的工具的特定版本。可用值请参阅各工具的文档。

工具说明
node通过 nvm 安装的 Node.js 版本。
yarn通过 npm -g 安装的 Yarn 版本。
corepack如果设置为 true,则会在构建过程开始时启用 corepack。默认值为 false。
pnpm通过 npm -g 安装的 pnpm 版本。
bun通过在 Bun 安装脚本中传入 bun-v$VERSION 安装的 Bun 版本。
ndk通过 sdkmanager 安装的 Android NDK 版本。
bundler将传递给 gem install -v 的 Bundler 版本。
fastlane将传递给 gem install -v 的 fastlane 版本。
cocoapods将传递给 gem install -v 的 CocoaPods 版本。

使用 defaults.tools 的 workflow 示例:

.eas/workflows/publish-update.yml
name: 设置自定义版本 defaults: tools: node: latest yarn: '2' corepack: true pnpm: '8' bun: '1.0.0' fastlane: 2.224.0 cocoapods: 1.12.0 on: push: branches: ['*'] jobs: setup: steps: - name: 检查 Node 版本 run: node --version # 应输出一个具体版本,例如 23.9.0 - name: 检查 Yarn 版本 run: yarn --version # 应输出一个具体版本,例如 2.4.3

concurrency

并发控制配置。目前仅允许为同分支 workflow 设置 cancel_in_progress

concurrency: cancel_in_progress: true group: ${{ workflow.filename }}-${{ github.ref }}
属性类型说明
cancel_in_progresstrue如果为 true,GitHub 新启动的 workflow 运行将取消当前正在进行的同分支运行。
groupstring我们目前还不支持自定义并发组。请设置此占位值,以便当我们未来支持自定义组时,你的 workflow 仍保持兼容。

控制流

你可以使用 needsafter 关键字控制 job 何时运行。此外,你还可以使用 if 关键字根据条件控制某个 job 是否应运行。

jobs.<job_id>.needs

一个 job ID 列表,这些 job 必须先成功完成,此 job 才会运行。

jobs: test: steps: - uses: eas/checkout - uses: eas/use_npm_token - uses: eas/install_node_modules - name: tsc run: yarn tsc build: needs: [test] # 只有当 'test' job 成功时,这个 job 才会运行 type: build params: platform: ios

jobs.<job_id>.after

一个 job ID 列表,这些 job 必须先完成(无论成功与否),此 job 才会运行。

jobs: build: type: build params: platform: ios notify: after: [build] # 这个 job 会在 build 完成后运行(无论 build 成功还是失败)

jobs.<job_id>.if

if 条件用于决定某个 job 是否应运行。当满足 if 条件时,job 将运行;当条件不满足时,job 将被跳过。被跳过的 job 不会被视为成功完成,且任何将该 job 包含在 needs 列表中的下游 job 都不会运行。

jobs: my_job: if: ${{ github.ref_name == 'main' }}

插值

你可以基于 workflow 运行的上下文,自定义 workflow 的行为——包括要执行的命令、控制流、环境变量、构建配置、应用版本等。

使用 ${{ expression }} 语法访问上下文属性和函数。例如:${{ github.ref_name }}${{ needs.build_ios.outputs.build_id }}

上下文属性

以下属性可在插值上下文中使用:

after

当前 job 的 after 列表中指定的所有上游 job 的记录。每个 job 提供:

{ "status": "success" | "failure" | "skipped", "outputs": {} }

示例:

jobs: build: type: build params: platform: ios notify: after: [build] steps: - run: echo "构建状态:${{ after.build.status }}"

needs

当前 job 的 needs 列表中指定的所有上游 job 的记录。每个 job 提供:

{ "status": "success" | "failure" | "skipped", "outputs": {} }

大多数预封装 job 会暴露特定输出。你可以使用 set-output 函数在自定义 job 中设置输出

示例:

jobs: setup: outputs: date: ${{ steps.current_date.outputs.date }} steps: - id: current_date run: | DATE=$(date +"%Y.%-m.%-d") set-output date "$DATE" build_ios: needs: [setup] type: build env: # 你可以使用 process.env.VERSION_SUFFIX # 在动态 app config 中自定义应用版本。 VERSION_SUFFIX: ${{ needs.setup.outputs.date }} params: platform: ios profile: development

steps

当前 job 中所有步骤的记录。每个步骤都会提供其使用 set-output 函数设置的输出。

注意: steps 上下文仅在 job 的步骤内部可用,而不在 workflow 级别可用。要将某个步骤的输出暴露给其他 job,请使用 set-output 函数以及该 job 的 outputs 配置

示例:

jobs: my_job: outputs: value: ${{ steps.step_1.outputs.value }} steps: - id: step_1 run: set-output value "hello" - run: echo ${{ steps.step_1.outputs.value }} another_job: needs: [my_job] steps: - run: echo "Value: ${{ needs.my_job.outputs.value }}"

inputs

手动使用 workflow_dispatch 触发 workflow 时提供的输入记录。当 workflow 通过带输入参数的 eas workflow:run 命令触发时可用。

示例:

on: workflow_dispatch: inputs: name: type: string required: true jobs: greet: steps: - run: echo "Hello, ${{ inputs.name }}!"

github

为了便于从 GitHub Actions 迁移到 EAS Workflows,我们暴露了一些你可能会觉得有用的上下文字段。

type GitHubContext = { triggering_actor?: string; event_name: 'pull_request' | 'push' | 'schedule' | 'workflow_dispatch'; sha: string; ref: string; // 例如 refs/heads/main ref_name: string; // 例如 main ref_type: 'branch' | 'tag' | 'other'; commit_message?: string; // 仅适用于 push 和 schedule 事件 label?: string; repository?: string; repository_owner?: string; event?: { label?: { name: string; }; // 仅适用于 push 和 schedule 事件 head_commit?: { message: string; id: string; }; pull_request?: { number: number; title: string; body: string | null; state: 'open' | 'closed'; draft: boolean; merged: boolean | null; // ... 来自 GitHub Pull Request webhook payload 的其他字段 }; number?: number; schedule?: string; inputs?: Record<string, string | number | boolean>; }; };

信息 event 对象包含完整的 GitHub webhook payload。对于 pull_request 事件,event.pull_request 包含 GitHub Pull Request webhook payload 中的所有字段。上面展示的是常用字段,但诸如 userlabelsmilestone 等其他字段也可用。

如果 workflow 运行是通过 eas workflow:run 启动的,那么其 event_name 将是 workflow_dispatch,其余所有属性都将为空。

示例:

jobs: build_ios: type: build if: ${{ github.ref_name == 'main' }} params: platform: ios profile: production
${{ github }} 上下文

查看 ${{ github }} 定义的源代码。

workflow

有关当前 workflow 的信息。

type WorkflowContext = { id: string; name: string; filename: string; url: string; };

示例:

jobs: notify_slack: after: [...] type: slack params: message: | Workflow run completed: ${{ workflow.name }} View details: ${{ workflow.url }}

app_store_connect

有关与 workflow 运行相关联的 App Store Connect 实体的信息。此上下文仅适用于由 App Store Connect 事件触发的 workflow。参见 on.app_store_connect

type AppStoreConnectContext = { app: { id: string; }; build_upload?: { id: string; state: 'awaiting_upload' | 'processing' | 'failed' | 'complete'; }; };

仅当 workflow 由 build_upload 事件域触发时,app_store_connect.build_upload 对象才会存在。

示例:

on: app_store_connect: build_upload: states: - complete jobs: notify: type: slack params: webhook_url: ${{ env.SLACK_WEBHOOK_URL }} message: | App Store Connect 应用上传完成:${{ app_store_connect.app.id }} 上传 ID:${{ app_store_connect.build_upload.id }} 上传状态:${{ app_store_connect.build_upload.state }}

env

当前 job 上下文中可用的环境变量记录。

注意: env 上下文仅在 job 的上下文中可用,而不在 workflow 级别可用。

示例:

jobs: my_job: steps: - run: echo "API URL: ${{ env.API_URL }}"

上下文函数

以下函数可在插值上下文中使用:

success()

返回所有之前的 job 是否都已成功。

jobs: notify: if: ${{ success() }} steps: - run: echo "所有 job 都已成功"

failure()

返回之前是否有任何 job 失败。

jobs: notify: if: ${{ failure() }} steps: - run: echo "有一个 job 失败了"

fromJSON(value)

解析一个 JSON 字符串。等同于 JSON.parse()

示例:

jobs: publish_update: type: update print_debug_info: needs: [publish_update] steps: - run: | echo "第一个 update group:${{ needs.publish_update.outputs.first_update_group_id }}" echo "第二个 update group:${{ fromJSON(needs.publish_update.outputs.updates_json || '[]')[1].group }}"

toJSON(value)

将一个值转换为 JSON 字符串。等同于 JSON.stringify()

示例:

jobs: my_job: steps: - run: echo '${{ toJSON(github.event) }}'

contains(value, substring)

检查 value 是否包含 substring

示例:

jobs: my_job: if: ${{ contains(github.ref_name, 'feature') }} steps: - run: echo "Feature 分支"

startsWith(value, prefix)

检查 value 是否以 prefix 开头。

示例:

jobs: my_job: if: ${{ startsWith(github.ref_name, 'release') }} steps: - run: echo "Release 分支"

endsWith(value, suffix)

检查 value 是否以 suffix 结尾。

示例:

jobs: my_job: if: ${{ endsWith(github.ref_name, '-production') }} steps: - run: echo "Production 分支"

hashFiles(...globs)

返回与所提供 glob 模式匹配的文件的哈希值。适用于缓存键。

注意: hashFiles 函数仅在 job 的步骤内部可用,而不在 workflow 级别可用。

示例:

jobs: my_job: steps: - run: echo "依赖哈希:${{ hashFiles('package-lock.json', 'yarn.lock') }}"

replaceAll(input, stringToReplace, replacementString)

inputstringToReplace 的所有出现位置替换为 replacementString

示例:

jobs: my_job: steps: - run: echo "${{ replaceAll(github.ref_name, '/', '-') }}"

substring(input, start, end)

input 中提取子字符串,起始位置为 start,结束位置为 end。如果未提供 end,则会从 start 提取到 input 末尾。底层使用 String#substring

示例:

jobs: my_job: steps: - run: echo "${{ substring(github.ref_name, 0, 50) }}"

预置作业

jobs.<job_id>.type

指定要运行的预置作业类型。预置作业会根据工作流详情页中的作业类型生成专门的界面。

jobs: my_job: type: build

下面了解不同的预置作业。

build

使用 EAS Build 为你的项目创建 Android 或 iOS 构建。有关详细信息和示例,请参阅 Build 作业文档

jobs: my_job: type: build params: platform: ios | android # 必需 profile: string # 可选,默认值:production message: string # 可选 refresh_ad_hoc_provisioning_profile: boolean # 可选

此作业输出以下属性:

{ "build_id": string, "app_build_version": string | null, "app_identifier": string | null, "app_version": string | null, "channel": string | null, "distribution": "internal" | "store" | null, "fingerprint_hash": string | null, "git_commit_hash": string | null, "platform": "ios" | "android" | null, "profile": string | null, "runtime_version": string | null, "sdk_version": string | null, "simulator": "true" | "false" | null }

deploy

使用 EAS Hosting 部署你的应用。有关详细信息和示例,请参阅 Deploy 作业文档

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

此作业输出以下属性:

{ "deploy_json": string, // 包含部署详情的 JSON 对象(`npx eas-cli deploy --json` 的输出)。 "deploy_url": string, // 部署的 URL。如果这是生产部署,则使用生产 URL。否则,使用第一个别名 URL 或部署 URL。 "deploy_alias_url": string, // 部署的别名 URL(例如,`https://account-project--alias.expo.app`)。 "deploy_deployment_url": string, // 部署的唯一 URL(例如,`https://account-project--uniqueid.expo.app`)。 "deploy_identifier": string, // 部署标识符。 "deploy_dashboard_url": string, // 部署仪表板的 URL(例如,`https://expo.dev/projects/[project]/hosting/deployments`)。 }

fingerprint

计算你项目的指纹。有关详细信息和示例,请参阅 Fingerprint 作业文档

jobs: my_job: type: fingerprint environment: production # 应与你的构建配置文件匹配

此作业输出以下属性:

{ "android_fingerprint_hash": string, "ios_fingerprint_hash": string, }

注意: 为了准确匹配指纹,请确保 fingerprint 作业的 environment 与你的构建配置文件一致。为了在各作业之间获得更好的一致性,建议使用 EAS 环境变量 而不是 env

get-build

从 EAS 中检索与所提供参数匹配的现有构建。有关详细信息和示例,请参阅 Get Build 作业文档

jobs: my_job: 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 # 可选

此作业输出以下属性:

{ "build_id": string, "app_build_version": string | null, "app_identifier": string | null, "app_version": string | null, "channel": string | null, "distribution": "internal" | "store" | null, "fingerprint_hash": string | null, "git_commit_hash": string | null, "platform": "ios" | "android" | null, "profile": string | null, "runtime_version": string | null, "sdk_version": string | null, "simulator": "true" | "false" | null }

submit

使用 EAS Submit 将 Android 或 iOS 构建提交到应用商店。有关详细信息和示例,请参阅 Submit 作业文档

jobs: my_job: type: submit params: build_id: string # 必需 profile: string # 可选,默认值:production groups: string[] # 可选 hooks: before_submit: step[] # 可选 after_submit: step[] # 可选

此作业输出以下属性:

{ "apple_app_id": string | null, // Apple App ID。https://expo.fyi/asc-app-id "ios_bundle_identifier": string | null, // 已提交构建的 iOS bundle 标识符。https://expo.fyi/bundle-identifier "android_package_id": string | null // 已提交的 Android 包名 ID。https://expo.fyi/android-package }

testflight

将 iOS 构建分发到 TestFlight 的内部和外部测试组。有关详细信息和示例,请参阅 TestFlight 作业文档

jobs: my_job: type: testflight 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 分钟)

此作业输出以下属性:

{ "apple_app_id": string | null, // Apple App ID。https://expo.fyi/asc-app-id "ios_bundle_identifier": string | null // 已提交构建的 iOS bundle 标识符。https://expo.fyi/bundle-identifier }

update

使用 EAS Update 发布更新。有关详细信息和示例,请参阅 Update 作业文档

jobs: my_job: type: update params: message: string # 可选 platform: string # 可选 - android | ios | all,默认值为 all branch: string # 可选 channel: string # 可选 - 不能与 branch 同时使用 private_key_path: string # 可选 upload_sentry_sourcemaps: boolean # 可选 - 默认行为是“尝试上传,但如果失败则不让作业失败”

此作业输出以下属性:

{ "first_update_group_id": string, // 第一个更新组的 ID。你可以将其用于例如为开发客户端深度链接构造更新 URL。 "updates_json": string // 更新组的字符串化 JSON 数组。`eas update --json` 的输出。 }

maestro

在构建上运行 Maestro 测试。有关详细信息和示例,请参阅 Maestro 作业文档

重要: Maestro 测试处于 alpha 阶段。

jobs: my_job: type: maestro environment: production | preview | development # 可选,默认值为 preview image: string # 可选。有关可用镜像列表,请参阅 https://docs.expo.dev/eas/workflows/syntax/#jobsjob_idruns_on params: build_id: string # 必需 flow_path: string | string[] # 必需 shards: number # 可选,默认值为 1 retries: number # 可选,默认值为 0 retry_failed_only: boolean # 可选,默认值为 true。为 true 时,在适用情况下,重试只会重新运行上一次尝试中失败的流程。 record_screen: boolean # 可选,默认值为 false。为 true 时,会上传测试的录屏。 include_tags: string | string[] # 可选。要包含在测试中的标签。将作为 `--include-tags` 传递给 Maestro。 exclude_tags: string | string[] # 可选。要从测试中排除的标签。将作为 `--exclude-tags` 传递给 Maestro。 maestro_version: string # 可选。测试要使用的 Maestro 版本。如果未提供,则使用最新版本。 android_system_image_package: string # 可选。要使用的 Android Emulator 系统镜像包。 device_identifier: string | { android?: string, ios?: string } # 可选。测试要使用的设备标识符。 output_format?: string # 可选,默认值为 junit。Maestro 测试报告格式。将作为 `--format` 传递给 Maestro。可以是 `junit` 或其他受支持的格式。 hooks: before_maestro_tests: step[] # 可选 after_maestro_tests: step[] # 可选

maestro-cloud

Maestro Cloud 中的构建上运行 Maestro 测试。有关详细信息和示例,请参阅 Maestro Cloud 作业文档

重要: 在 Maestro Cloud 中运行测试需要 Maestro Cloud 账户和 Cloud Plan 订阅。前往 Maestro 文档 了解更多。

jobs: my_job: type: maestro-cloud environment: production | preview | development # 可选,默认值为 preview image: string # 可选。有关可用镜像列表,请参阅 https://docs.expo.dev/eas/workflows/syntax/#jobsjob_idruns_on 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 项目的 API 密钥。默认情况下,将使用 `MAESTRO_CLOUD_API_KEY` 环境变量。对应 `maestro cloud` 的 `--api-key` 参数。 include_tags: string | string[] # 可选。要包含在测试中的标签。将作为 `--include-tags` 传递给 Maestro。 exclude_tags: string | string[] # 可选。要从测试中排除的标签。将作为 `--exclude-tags` 传递给 Maestro。 maestro_version: string # 可选。测试要使用的 Maestro 版本。如果未提供,则使用最新版本。 maestro_config: string # 可选。测试要使用的 Maestro `config.yaml` 文件路径。将作为 `--config` 传递给 Maestro。 device_locale: string # 可选。测试要使用的设备区域设置。将作为 `--device-locale` 传递给 Maestro。 device_model: string # 可选。测试要使用的设备型号。将作为 `--device-model` 传递给 Maestro。运行 `maestro list-cloud-devices` 查看支持的值列表。 device_os: string # 可选。测试要使用的设备操作系统。将作为 `--device-os` 传递给 Maestro。运行 `maestro list-cloud-devices` 查看支持的值列表。 name: string # 可选。Maestro Cloud 上传的名称。对应 `maestro cloud` 的 `--name` 参数。 branch: string # 可选。覆盖 Maestro Cloud 上传来源的分支。默认情况下,如果工作流运行是从 GitHub 触发的,则使用工作流运行的分支。对应 `maestro cloud` 的 `--branch` 参数。 async: boolean # 可选。异步运行 Maestro Cloud 测试。如果为 true,则作业状态仅表示上传是否成功,*不*表示测试是否成功。对应 `maestro cloud` 的 `--async` 参数。 hooks: before_maestro_cloud: step[] # 可选。在上传到 Maestro Cloud 之前运行的步骤。 after_maestro_cloud: step[] # 可选。在上传到 Maestro Cloud 之后运行的步骤。

slack

使用 webhook URL 向 Slack 频道发送消息。有关详细信息和示例,请参阅 Slack 作业文档

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

github-comment

自动将你工作流中已完成的构建、更新和部署的综合报告发布到 GitHub pull request,或你提供的内容中。有关详细信息和示例,请参阅 GitHub Comment 作业文档

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

此作业输出以下属性:

{ "comment_url": string | undefined // 已发布的 GitHub 评论 URL }

apple-device-registration-request

暂停工作流,直到某个 iOS 设备为 Apple Team 注册,并且团队成员批准该注册。有关详细信息和示例,请参阅 Apple device registration request 作业文档

jobs: register_device: type: apple-device-registration-request params: apple_team_identifier: string # 可选

require-approval

在继续工作流之前,需要用户批准。用户可以批准或拒绝,这将分别转换为作业成功或失败。有关详细信息和示例,请参阅 Require Approval 作业文档

jobs: confirm: type: require-approval

doc

在工作流日志中显示一个 Markdown 区块。有关详细信息和示例,请参阅 Doc 作业文档

jobs: next_steps: type: doc params: md: string

repack

从现有构建重新打包一个应用。此作业会重新打包应用的元数据和 JavaScript bundle,而不执行完整的原生重新构建,这对于创建与特定指纹兼容的更快构建很有用。有关详细信息和示例,请参阅 Repack 作业文档

jobs: next_steps: type: repack params: build_id: string # 必需 profile: string # 可选 embed_bundle_assets: boolean # 可选 message: string # 可选 repack_version: string # 可选

自定义任务

运行自定义代码,并可使用内置 EAS 函数。不需要 type 字段。

jobs: my_job: steps: # ...

jobs.<job_id>.steps

一个任务包含一个名为 steps 的任务序列。步骤可以运行命令。steps 只能在自定义任务和 build 任务中提供。

jobs: my_job: steps: - name: My first step run: echo "Hello World"

jobs.<job_id>.outputs

由任务定义的输出列表。这些输出可供所有依赖此任务的下游任务访问。要设置输出,请在任务步骤中使用 set-output 函数。

下游任务可以在 插值上下文 中使用以下表达式访问这些输出:

  • needs.<job_id>.outputs.<output_name>
  • after.<job_id>.outputs.<output_name>

这里,<job_id> 指的是上游任务的标识符,而 <output_name> 指的是你想访问的特定输出变量。

在下面的示例中,set-output 函数在 job_1step_1 步骤中将名为 test 的输出设置为值 hello world。之后,在 job_2 中,可以在 step_2 里使用 needs.job_1.outputs.output_1 访问它。

jobs: job_1: outputs: output_1: ${{ steps.step_1.outputs.test }} steps: - id: step_1 run: set-output test "hello world" job_2: needs: [job_1] steps: - id: step_2 run: echo ${{ needs.job_1.outputs.output_1 }}

jobs.<job_id>.image

指定用于该任务的 VM 镜像。可用镜像请参见 Infrastructure

jobs: my_job: image: auto | string # optional, defaults to 'auto'

jobs.<job_id>.runs_on

指定将执行该任务的 worker。仅适用于自定义任务。

jobs: my_job: runs_on: linux-medium | linux-large | linux-medium-nested-virtualization | linux-large-nested-virtualization | macos-medium | macos-large # optional, defaults to linux-medium
工作器vCPU内存(GiB RAM)SSD(GiB)备注
linux-medium41614默认工作器。
linux-large83228
linux-medium-nested-virtualization41614允许运行 Android 模拟器。
linux-large-nested-virtualization43228允许运行 Android 模拟器。
工作器效率核心数统一内存(GiB RAM)SSD(GiB)备注
macos-medium520125运行 iOS 作业,包括模拟器。
macos-large1040125运行 iOS 作业,包括模拟器。

注意: 对于 Android Emulator 任务,必须使用 linux-*-nested-virtualization worker。对于 iOS 构建和 iOS Simulator 任务,必须使用 macos-* worker。

jobs.<job_id>.steps.<step>.id

id 属性用于在作业中引用该步骤。可用于在下游作业中使用该步骤的输出。

jobs: my_job: outputs: test: ${{ steps.step_1.outputs.test }} # 引用 step_1 的输出 steps: - id: step_1 run: set-output test "hello world"

jobs.<job_id>.steps.<step>.name

该步骤的人类可读名称,会显示在作业日志中。当步骤未提供名称时,会使用 run 命令作为步骤名称。

jobs: my_job: steps: - name: 我的第一步 run: echo "Hello World"

jobs.<job_id>.steps.<step>.run

在该步骤中运行的 shell 命令。

jobs: my_job: steps: - run: echo "Hello World"

jobs.<job_id>.steps.<step>.shell

用于运行命令的 shell。默认值为 bash

jobs: my_job: steps: - run: echo "Hello World" shell: bash

jobs.<job_id>.steps.<step>.working_directory

运行命令的目录。当在步骤级别定义时,如果作业中也定义了 jobs.<job_id>.defaults.run.working_directory 设置,则该设置会被覆盖。

jobs: my_job: steps: - uses: eas/checkout - run: pwd # 输出:/home/expo/workingdir/build/my-app working_directory: ./my-app

jobs.<job_id>.steps.<step>.uses

EAS 提供了一组内置的可复用函数,可在工作流步骤中使用。uses 关键字用于指定要使用的函数。所有内置函数都以 eas/ 前缀开头。

jobs: my_job: steps: - uses: eas/checkout - uses: eas/install_node_modules - uses: eas/prebuild - name: 列出文件 run: ls -la

以下是你可以在工作流步骤中使用的内置函数列表。

eas/checkout

检出你的项目源文件。

jobs: my_job: steps: - uses: eas/checkout
eas/checkout 源代码

在 GitHub 上查看 eas/checkout 函数的源代码。

eas/install_node_modules

使用根据你的项目检测到的包管理器(bun、npm、pnpm 或 Yarn)安装 node_modules。适用于 monorepo。

example.yml
jobs: my_job: steps: - uses: eas/checkout - uses: eas/install_node_modules
eas/install_node_modules 源代码

在 GitHub 上查看 eas/install_node_modules 函数的源代码。

eas/download_build

下载给定构建的应用归档。默认情况下,下载的产物可以是 .apk.aab.ipa.app 文件,或者是一个包含这些文件中一个或多个的 .tar.gz 归档。如果产物是 .tar.gz 归档,它将被解压,并返回匹配指定扩展名的第一个文件。如果构建未生成任何应用归档,该步骤将失败。

jobs: my_job: steps: - uses: eas/download_build with: build_id: string # 必填。要下载的构建 ID。 extensions: [apk, aab, ipa, app] # 可选。要查找的文件扩展名列表。默认为 ["apk", "aab", "ipa", "app"]。
属性类型必需默认描述
build_idstring要下载的构建 ID。必须是有效的 UUID。
extensionsstring[]["apk", "aab", "ipa", "app"]在下载的产物或归档中要查找的文件扩展名列表。

输出:

  • artifact_path:匹配的应用归档的绝对路径。此输出可作为工作流中其他步骤的输入。例如,可用于进一步上传或处理该产物。

示例用法:

jobs: build_ios: type: build params: platform: ios profile: production my_job: needs: [build_ios] steps: - uses: eas/download_build id: download_build with: build_id: ${{ needs.build_ios.outputs.build_id }} - name: 打印产物路径 run: | echo "Artifact path: ${{ steps.download_build.outputs.artifact_path }}"
eas/download_build 源代码

在 GitHub 上查看 eas/download_build 函数的源代码。

eas/prebuild

使用根据你的项目检测到的包管理器(bun、npm、pnpm 或 Yarn),并采用最适合你的构建类型和构建环境的命令来运行 expo prebuild 命令。

jobs: my_job: steps: - uses: eas/checkout - uses: eas/install_node_modules - uses: eas/prebuild
jobs: my_job: steps: - uses: eas/checkout - uses: eas/install_node_modules - uses: eas/resolve_apple_team_id_from_credentials id: resolve_apple_team_id_from_credentials - uses: eas/prebuild with: clean: false apple_team_id: ${{ steps.resolve_apple_team_id_from_credentials.outputs.apple_team_id }}
属性类型描述
cleanboolean可选属性,定义在运行命令时该函数是否应使用 --clean 标志。默认值为 false。
apple_team_idstring可选属性,定义在进行 prebuild 时应使用的 Apple team ID。使用凭据进行 iOS 构建时应指定此项。
eas/prebuild 源代码

在 GitHub 上查看 eas/prebuild 函数的源代码。

eas/restore_cache

从指定键恢复之前保存的缓存。这对于通过重用已缓存的产物(如已编译的依赖项、构建工具或其他中间构建输出)来加快构建速度很有用。

jobs: my_job: steps: - uses: eas/checkout - uses: eas/install_node_modules - uses: eas/prebuild - uses: eas/restore_cache with: key: cache-${{ hashFiles('package-lock.json') }} restore_keys: cache path: /path/to/cache
jobs: my_job: steps: - uses: eas/checkout - uses: eas/install_node_modules - uses: eas/prebuild - uses: eas/restore_cache with: key: cache-${{ hashFiles('package-lock.json') }} path: /path/to/cache
属性类型必需描述
keystring要恢复的缓存键。你可以使用诸如 ${{ hashFiles('package-lock.json') }} 之类的表达式,根据文件哈希创建动态键。
restore_keysstring如果找不到精确键时使用的回退键或前缀。如果提供,缓存系统将查找任何以该前缀开头的缓存条目。
pathstring应恢复缓存的路径。应与保存缓存时使用的路径相匹配。
eas/restore_cache 源代码

在 GitHub 上查看 eas/restore_cache 函数的源代码。

eas/save_cache

将缓存保存到指定键。这使你可以持久化构建产物、已编译的依赖项或其他中间输出,以便在后续构建中重复使用,从而加快构建过程。

jobs: my_job: steps: - uses: eas/checkout - uses: eas/install_node_modules - uses: eas/prebuild - uses: eas/restore_cache with: key: cache-${{ hashFiles('package-lock.json') }} path: /path/to/cache - name: 构建 Android 应用 run: cd android && ./gradlew assembleRelease - uses: eas/save_cache with: key: cache-${{ hashFiles('package-lock.json') }} path: /path/to/cache
属性类型必需描述
keystring要将缓存保存到其下的缓存键。你可以使用诸如 ${{ hashFiles('package-lock.json') }} 之类的表达式,根据文件哈希创建动态键。这应与恢复缓存时使用的键一致。
pathstring应缓存的目录或文件路径。这应与恢复缓存时使用的路径一致。
eas/save_cache 源代码

在 GitHub 上查看 eas/save_cache 函数的源代码。

eas/send_slack_message

向已配置的 Slack webhook URL 发送指定消息,然后它会将消息发布到相关的 Slack 频道。消息可以指定为纯文本或 Slack Block Kit 消息。

在这两种情况下,你都可以在消息中引用构建作业属性,并且可以 使用其他步骤的输出 进行动态求值。例如,Build URL: https://expo.dev/builds/${{ needs.build_ios.outputs.build_id }}Build finished with status: ${{ after.build_android.status }}

必须指定 messagepayload 其中之一,但不能同时指定两者。

jobs: my_job: steps: - uses: eas/send_slack_message with: message: '这是发送到普通输入 URL 的消息' slack_hook_url: 'https://hooks.slack.com/services/[rest_of_hook_url]'
属性类型描述
messagestring你想发送的消息文本。例如,'This is the content of the message'

注意: 必须提供 messagepayload 其中之一,但不能同时提供两者。
payloadjson你想发送的消息内容,使用 Slack Block Kit 布局定义。

注意: 必须提供 messagepayload 其中之一,但不能同时提供两者。
slack_hook_urlstring之前配置好的 Slack webhook URL,它会将你的消息发布到指定频道。你可以提供类似 slack_hook_url: 'https://hooks.slack.com/services/[rest_of_hook_url]' 的普通 URL,使用 EAS 环境变量 例如 slack_hook_url: ${{ env.ANOTHER_SLACK_HOOK_URL }},或者设置 SLACK_HOOK_URL 环境变量,它将作为默认 webhook URL(在后一种情况下,无需提供 slack_hook_url 属性)。
eas/send_slack_message 源代码

在 GitHub 上查看 eas/send_slack_message 函数的源代码。

eas/use_npm_token

配置 Node 包管理器(bun、npm、pnpm 或 Yarn)以便与私有包一起使用,这些包可以发布到 npm 或私有注册表。

在项目的 secrets 中设置 NPM_TOKEN,该函数将通过使用该令牌创建 .npmrc 来配置构建环境。

example.yml
jobs: my_job: name: 安装私有 npm 模块 steps: - uses: eas/checkout - uses: eas/use_npm_token - name: 安装依赖 run: npm install # <---- 现在可以安装私有包了
eas/use_npm_token 源代码

在 GitHub 上查看 eas/use_npm_token 函数的源代码。

eas/download_artifact

根据工件的 ID 或名称从 EAS 下载一个工件。适用于将前面作业中的工件发送到其他服务。

jobs: my_job: steps: - uses: eas/download_artifact with: name: string # 如果未提供 artifact_id,则为必填。要下载的工件名称。 artifact_id: string # 如果未提供 artifact_name,则为必填。要下载的工件 ID。
属性
属性类型必需描述
namestring要下载的工件名称。如果未提供 artifact_id,则为必填。
artifact_idstring要下载的工件 ID。如果未提供 name,则为必填。
输出
属性类型描述
artifact_pathstring已下载工件的路径。此输出可作为工作流中其他步骤的输入。例如,可用于发送或处理该工件。
示例
jobs: maestro_tests: type: maestro params: build_id: '123-abc' flow_path: 'path/to/flow.yaml' my_job: needs: [maestro_tests] steps: - uses: eas/download_artifact id: download_artifact with: name: 'iOS Maestro Test Report (junit)' - name: 打印 Maestro 输出 run: echo ${{ steps.download_artifact.outputs.artifact_path }}
eas/download_artifact 源代码

在 GitHub 上查看 eas/download_artifact 函数的源代码。

内置 shell 函数

EAS Workflows 提供了以下 shell 函数,你可以在工作流步骤中使用它们来设置变量输出。

set-output

设置一个输出变量,其他步骤或工作流中的其他任务可以访问它。

set-output <name> <value>

用于与另一个步骤共享变量的示例:

jobs: my_job: steps: - id: step_1 run: set-output variable_1 "变量 1" - id: step_2 run: echo ${{ steps.step_1.outputs.variable_1 }} # 输出:变量 1

用于与另一个任务共享变量的示例:

jobs: job_1: outputs: variable_1: ${{ steps.step_1.outputs.variable_1 }} steps: - id: step_1 run: set-output variable_1 "变量 1" job_2: needs: [job_1] steps: - run: echo ${{ needs.job_1.outputs.variable_1 }} # 输出:变量 1

set-env

设置一个环境变量,该变量可供同一任务中的后续步骤使用。在一个步骤的命令中使用 export 导出的环境变量不会自动暴露给其他步骤。若要与其他步骤共享环境变量,请使用 set-env 可执行文件。

set-env <name> <value>

set-env 需要传入两个参数:环境变量的名称和值。例如,set-env NPM_TOKEN "abcdef" 会将 $NPM_TOKEN 变量及其值 abcdef 暴露给后续步骤。

注意: 使用 set-env 共享的变量不会自动在本地导出。如果你想在当前步骤中使用该变量,需要自行调用 export

用于与另一个步骤共享环境变量的示例:

jobs: my_job: steps: - name: 设置环境变量 run: | # 仅使用 export 只会让它在当前步骤中可用 export LOCAL_VAR="仅在此步骤中" # 使用 set-env 会让它在后续步骤中可用 set-env SHARED_VAR "在后续步骤中可用" # SHARED_VAR 目前在当前步骤的环境中还不可用 echo "LOCAL_VAR: $LOCAL_VAR" # 输出:仅在此步骤中 echo "SHARED_VAR: $SHARED_VAR" # 输出:(空) - name: 使用共享变量 run: | # SHARED_VAR 现在可用了 # @info # echo "SHARED_VAR: $SHARED_VAR" # 输出:在后续步骤中可用 # @end #

在任务之间共享环境变量

set-env 函数只会在同一任务内与其他步骤共享环境变量。若要在不同任务之间共享值,请使用任务的 outputs 配合 set-output,并通过接收任务上的 env 属性传递它们:

jobs: job_1: outputs: my_value: ${{ steps.step_1.outputs.my_value }} steps: - id: step_1 run: set-output my_value "来自 job_1 的值" job_2: needs: [job_1] env: MY_VALUE: ${{ needs.job_1.outputs.my_value }} steps: - run: echo "MY_VALUE: $MY_VALUE" # 输出:来自 job_1 的值