自定义构建配置架构

使用 EAS Build 进行自定义构建的配置选项参考。


为 EAS Build 创建自定义版本有助于自定义项目的构建过程。

¥Creating custom builds for EAS Build helps customize the build process for your project.

自定义构建的 YAML 语法

¥YAML syntax for custom builds

自定义构建配置文件存储在 .eas/build 目录路径内。它们使用 YAML 语法,并且必须具有 .yml.yaml 文件扩展名。如果你不熟悉 YAML 或者想了解有关语法的更多信息,请参阅 在 Y 分钟内学习 YAML

¥Custom build config files are stored inside the .eas/build directory path. They use YAML syntax and must have a .yml or .yaml file extension. If you are new to YAML or want to learn more about the syntax, see Learn YAML in Y minutes.

build

定义以描述自定义构建配置。创建自定义构建的所有配置选项都在其下指定。

¥Defined to describe a custom build configuration. All config options to create a custom build are specified under it.

name

用于在构建日志中识别自定义构建的名称。EAS Build 使用此属性在仪表板中显示构建的名称。

¥The name of your custom build that is used to identify it in the build logs. EAS Build uses this property to display the name of your build in the dashboard.

例如,构建名称为 Run tests

¥For example, the build name is Run tests:

build:
  name: Run tests
  steps:
    - eas/checkout
    - run:
        name: Install dependencies
        command: npm install

steps

步骤用于描述操作列表,可以是命令或函数调用的形式。当自定义构建在 EAS Build 上运行时,将执行这些操作。你可以在构建配置中定义单个或多个步骤。但是,每个构建至少需要定义一个步骤。

¥Steps are used to describe a list of actions, either in the form of commands or function calls. These actions are executed when a custom build runs on EAS Build. You can define single or multiple steps in a build config. However, it is required to define at least one step per build.

每个步骤都配置有以下属性:

¥Each step is configured with the following properties:

steps[].run

run 键用于触发一组指令。例如,run 密钥用于使用 npm install 命令安装依赖:

¥The run key is used to trigger a set of instructions. For example, a run key is used to install dependencies using the npm install command:

build:
  name: Install npm dependencies
  steps:
    - eas/checkout
    - run:
        name: Install dependencies
        command: npm install

你还可以使用 steps[].run 执行单行或多行 shell 命令:

¥You can also use steps[].run to execute single or multiline shell commands:

build:
  name: Run inline shell commands
  steps:
    - run: echo "Hello world"
    - run: |
        echo "Multiline"
        echo "bash commands"

使用单步

¥Use a single step

例如,具有以下 steps 的构建配置将打印 "你好世界":

¥For example, a build config with the following steps will print "Hello world":

build:
  name: Greeting
  steps:
    - run: echo "Hello world"

注意:run 之前的 - 算作缩进。

¥Note: - before run counts as indentation.

使用多个步骤

¥Use multiple steps

当定义多个 steps 时,它们是顺序执行的。例如,具有以下 steps 的构建配置将首先检出项目,安装 npm 依赖,然后运行命令来运行测试:

¥When multiple steps are defined, they are executed sequentially. For example, a build config with the following steps will first check out the project, install npm dependencies, and then run a command to run tests:

build:
  name: Run tests
  steps:
    - eas/checkout
    - run:
        name: Install dependencies
        command: npm install
    - run:
        name: Run tests
        command: |
          echo "Running tests..."
          npm test

与其他步骤共享环境变量

¥Sharing environment variables with other steps

在一个步骤的 command 中导出(使用 export)的环境变量不会自动暴露给其他步骤。要与其他步骤共享环境变量,请使用 set-env 可执行文件。

¥Environment variables exported (using export) in one step's command are not automatically exposed to other steps. To share an environment variable with other steps, use the set-env executable.

set-env 期望使用两个参数进行调用:环境变量的名称和值。例如,set-env NPM_TOKEN "abcdef" 将向其他步骤公开值为 abcdef$NPM_TOKEN 变量。

¥set-env expects to be called with two arguments: environment variable's name and value. For example, set-env NPM_TOKEN "abcdef" will expose $NPM_TOKEN variable with value abcdef to other steps.

注意:与 set-env 共享的变量不会自动导出到本地。你需要自己调用 export

¥Note: Variables shared with set-env are not automatically exported locally. You need to call export yourself.

build:
  name: Shared environment variable example
  steps:
    - run:
        name: Set environment variables
        command: |
          set -x

          # Set variable
          ENV_TEST_LOCAL="present-only-in-current-shell-context"
          # Set and export variable
          export ENV_TEST_LOCAL_EXPORT="present-in-current-step"
          # Set shared variable
          set-env ENV_TEST_SET_ENV "present-in-following-steps"

          # Will print "ENV_TEST_LOCAL: present-only-in-current-shell-context"
          # because current shell has access to this local variable.
          echo "ENV_TEST_LOCAL: $ENV_TEST_LOCAL"

          # Will print "ENV_TEST_LOCAL_EXPORT: present-in-current-step"
          # because export also sets the local variable value.
          echo "ENV_TEST_LOCAL_EXPORT: $ENV_TEST_LOCAL_EXPORT"

          # Will "ENV_TEST_SET_ENV: "
          # because set-env does not set or export variables.
          echo "ENV_TEST_SET_ENV: $ENV_TEST_SET_ENV"

          # Will only print LOCALLY_EXPORTED_ENV,
          # because it is the only export-ed variable.
          env | grep ENV_TEST_
    - run:
        name: Check variables values in next step
        command: |
          set -x

          # Will print "ENV_TEST_LOCAL: ", because ENV_TEST_LOCAL
          # is only a local variable in previous step.
          echo "ENV_TEST_LOCAL: $ENV_TEST_LOCAL"

          # Will print "ENV_TEST_LOCAL_EXPORT: "
          # because export does not share a variable to other steps.
          echo "ENV_TEST_LOCAL_EXPORT: $ENV_TEST_LOCAL_EXPORT"

          # Will print "ENV_TEST_SET_ENV: present-in-following-steps"
          # because set-env "exported" variable to other steps.
          echo "ENV_TEST_SET_ENV: $ENV_TEST_SET_ENV"

          # Will only print ENV_TEST_SET_ENV,
          # because set-env "exported" it to other steps.
          env | grep ENV_TEST_

steps[].run.name

构建日志中用于显示步骤名称的名称。

¥The name used in build logs to display the name of the step.

steps[].run.command

command 定义了在执行步骤时运行的自定义 shell 命令。需要为每个步骤定义一个命令。它可以是多行 shell 命令:

¥The command defines a custom shell command to run when a step is executed. It is required to define a command for each step. It can be a multiline shell command:

build:
  name: Run tests
  steps:
    - eas/checkout
    - run:
        name: Run tests
        command: |
          echo "Running tests..."
          npm test

steps[].run.working_directory

working_directory 用于定义项目根目录中的现有目录。在步骤中定义现有路径后,使用它会更改该步骤的当前目录。例如,创建一个步骤来列出资源目录(Expo 项目中的目录)内的所有资源。working_directory 设置为 assets

¥The working_directory is used to define an existing directory from the project's root directory. After an existing path is defined in a step, using it changes the current directory for that step. For example, a step is created to list all the assets inside the assets directory, which is a directory in your Expo project. The working_directory is set to assets:

build:
  name: Demo
  steps:
    - eas/checkout
    - run:
        name: List assets
        working_directory: assets
        command: ls -la

steps[].run.shell

用于定义步骤的默认可执行 shell。例如,该步骤的 shell 设置为 /bin/sh

¥Used to define the default executable shell for a step. For example, the step's shell is set to /bin/sh:

build:
  name: Demo
  steps:
    - run:
        shell: /bin/sh
        command: |
          echo "Steps can use another shell"
          ps -p $$

steps[].run.inputs

输入值被提供给步骤。例如,你可以使用 input 来提供值:

¥Input values are provided to a step. For example, you can use input to provide a value:

build:
  name: Demo
  steps:
    - run:
        name: Say Hi
        inputs:
          name: Expo
        command: echo "Hi, ${ inputs.name }!"

steps[].run.outputs

在一个步骤中预计会有一个输出值。例如,某个步骤的输出值为 Hello world

¥An output value is expected during a step. For example, a step has an output value of Hello world:

build:
  name: Demo
  steps:
    - run:
        name: Produce output
        outputs: [value]
        command: |
          echo "Producing output for another step"
          set-output value "Output from another step..."

steps[].run.outputs.required

输出值可以使用布尔值来指示是否需要输出值。例如,函数没有所需的输出值:

¥An output value can use a boolean to indicate if the output value is required or not. For example, a function does not have a required output value:

build:
  name: Demo
  steps:
    - run:
        name: Produce another output
        id: id456
        outputs:
          - required_param
          - name: optional_param
            required: false
        command: |
          echo "Producing more output"
          set-output required_param "abc 123 456"

steps[].run.id

为步骤定义 id 允许:

¥Defining an id for a step allows:

  • 多次调用产生一个或多个输出的同一函数

    ¥Calling the same function that produces one or more outputs multiple times

  • 使用从一个步骤到另一步骤的输出

    ¥Using the output from one step to another

调用同一个函数一次或多次

¥Call the same function one or more times

例如,以下函数生成一个随机数:

¥For example, the following function generates a random number:

functions:
  random:
    name: Generate random number
    outputs: [value]
    command: set-output value `random_number`

在构建配置中,让我们使用 random 函数生成两个随机数并打印它们:

¥In a build config, let's use the random function to generate two random numbers and print them:

build:
  name: Functions Demo
  steps:
    - random:
        id: random_1
    - random:
        id: random_2
    - run:
        name: Print random numbers
        inputs:
          random_1: ${ steps.random_1.value }
          random_2: ${ steps.random_2.value }
        command: |
          echo "${ inputs.random_1 }"
          echo "${ inputs.random_2 }"

使用从一个步骤到另一步骤的输出

¥Use output from one step to another

例如,以下构建配置演示了如何使用从一个步骤到另一个步骤的输出:

¥For example, the following build config demonstrates how to use output from one step to another:

build:
  name: Outputs demo
  steps:
    - run:
        name: Produce output
        id: id123 # <---- !!!
        outputs: [foo]
        command: |
          echo "Producing output for another step"
          set-output foo bar
    - run:
        name: Use output from another step
        inputs:
          foo: ${ steps.id123.foo }
        command: |
          echo "foo = \"${ inputs.foo }\""

functions

定义以描述可在构建配置中使用的可重用函数。创建函数的所有配置选项均使用以下属性指定:

¥Defined to describe a reusable function that can be used in a build config. All config options to create a function are specified with the following properties:

functions.[function_name]

[function_name] 是你定义的函数名称,用于在 build.steps 中标识它。例如,你可以定义一个名为 greetings 的函数:

¥The [function_name] is the name of a function that you define to identify it in the build.steps. For example, you can define a function with the name greetings:

functions:
  greetings:
    name: Say Hi!

functions.[function_name].name

在构建日志中用于显示函数名称的名称。例如,显示名称为 Say Hi! 的函数:

¥The name that is used in build logs to display the name of the function. For example, a function with the display name Say Hi!:

functions:
  greetings:
    name: Say Hi!

functions.[function_name].inputs

输入值被提供给函数。

¥Input values are provided to a function.

inputs[].name

输入值的名称。它用作访问输入值的标识符,例如在 bash 命令插值中。

¥The name of the input value. It is used as an identifier to access the input value such as in bash command interpolation.

functions:
  greetings:
    name: Say Hi!
    inputs:
      - name: name
        default_value: Hello world
    command: echo "${ inputs.name }!"

inputs[].required

布尔值指示是否需要输入值。例如,一个函数没有所需的值:

¥Boolean to indicate if the input value is required or not. For example, a function does not have a required value:

functions:
  greetings:
    name: Say Hi!
    inputs:
      - name: name
        required: false

inputs[].type

输入值的类型。它可以是 stringnumjson

¥The type of the input value. It can be either string, num or json.

函数调用中设置的输入值以及函数的 default_valueallowed_values 将根据类型进行验证。

¥Input values set in the function call as well as default_value and allowed_values for the function are validated against the type.

默认输入 typestring

¥The default input type is string.

例如,函数具有 string 类型的输入值:

¥For example, a function has an input value of type string:

functions:
  greetings:
    name: Say Hi!
    inputs:
      - name: name
        type: string
      - name: age
        type: num
      - name: other_data
        type: json

inputs[].default_value

你可以使用 default_value 提供一个默认输入。例如,函数的默认值为 Hello world

¥You can use default_value to provide one default input. For example, a function has a default value of Hello world:

functions:
  greetings:
    name: Say Hi!
    inputs:
      - name: name
        default_value: Hello world

inputs[].allowed_values

你可以使用 allowed_values 在数组中提供多个值。例如,一个函数有多个允许值:

¥You can use allowed_values to provide multiple values in an array. For example, a function has multiple allowed values:

functions:
  greetings:
    name: Say Hi!
    inputs:
      - name: name
        default_value: Hello world
        allowed_values: [Hi, Hello, Hey]
        type: string

多个输入值

¥Multiple input values

可以向函数提供多个输入值。

¥Multiple input values can be provided to a function.

functions:
  greetings:
    name: Say Hi!
    inputs:
      - name: name
        default_value: Expo
      - name: greeting
        default_value: Hi
        allowed_values: [Hi, Hello]
    command: echo "${ inputs.greeting }, ${ inputs.name }!"

functions.[function_name].outputs

函数期望输出值。例如,函数的输出值为 Hello world

¥An output value is expected from a function. For example, a function has an output value of Hello world:

functions:
  greetings:
    name: Say Hi!
    outputs: [value]
    command: set-output value "Hello world"

outputs[].name

输出值的名称。它用作访问另一个步骤中的输出值的标识符:

¥The name of the output value. It is used as an identifier to access the output value in another step:

functions:
  greetings:
    name: Say Hi!
    outputs:
      - name: name

outputs[].required

布尔值,指示是否需要输出值。例如,函数没有所需的输出值:

¥Boolean to indicate if the output value is required or not. For example, a function does not have a required output value:

functions:
  greetings:
    name: Say Hi!
    outputs:
      - name: value
        required: false

functions.[function_name].command

如果你希望函数是一个简单的 shell 脚本,则用于定义执行函数时要运行的命令。每个函数都需要为实现该函数的 JS/TS 模块定义 commandpath。例如,命令 echo "Hello world" 用于打印一条消息:

¥Used to define the command to run when a function is executed, if you wish the function to be a simple shell script. Each function is required to define either a command or a path to JS/TS module implementing the function. For example, the command echo "Hello world" is used to print a message:

functions:
  greetings:
    name: Say Hi!
    command: echo "Hi!"

functions.[function_name].path

用于定义实现该功能的 JavaScript/TypeScript 模块的路径。每个函数都需要定义 commandpath 属性。例如,路径 ./greetings 用于执行 greetings 模块中声明的 greetings 函数:

¥Used to define the path to a JavaScript/TypeScript module implementing the function. Each function is required to define either a command or a path property. For example, the path ./greetings is used to execute a greetings function declared in the greetings module:

functions:
  greetings:
    name: Say Hi!
    path: ./greetings

functions.[function_name].shell

用于定义执行函数的步骤的默认可执行 shell。例如,该步骤的 shell 设置为 /bin/sh

¥Used to define the default executable shell for a step where a function is executed. For example, the step's shell is set to /bin/sh:

functions:
  greetings:
    name: Say Hi!
    shell: /bin/sh
    command: echo "Hi!"

functions.[function_name].supported_platforms

用于定义函数支持的平台。默认为所有平台。允许的平台:darwinlinux

¥Used to define the supported platforms for a function. Defaults to all platforms. Allowed platforms: darwin, linux.

例如,该函数支持的平台是 darwin(macOS):

¥For example, the function's supported platform is darwin (macOS):

functions:
  greetings:
    name: Say Hi!
    supported_platforms: [darwin]
    command: echo "Hi!"

import

用于从其他配置文件导入函数的配置文件路径列表。导入的文件不能有 build 部分。

¥A config file path list used to import functions from other config files. Imported files cannot have the build section.

例如,以下构建配置导入两个文件并调用两个导入的函数 - say_hisay_bye

¥For example, the following build config imports two files and calls two imported functions - say_hi and say_bye.

build-and-test.yml
import:
  - common-functions.yml
  - another-file.yml

build:
  steps:
    - say_hi
    - say_bye
common-functions.yml
functions:
  say_hi:
    name: Say Hi!
    command: echo "Hi!"
another-file.yml
functions:
  say_bye:
    name: Say bye :(
    command: echo "Bye!"

函数

¥Functions

内置 EAS 功能

¥Built-in EAS functions

EAS 提供了一组内置可重用函数,你可以在构建配置中使用这些函数,而无需定义函数定义。

¥EAS provides a set of built-in reusable functions that you can use in a build config without defining the function definition.

提示:EAS 内置并提供的任何功能都必须以 eas/ 前缀开头。

eas/build

封装了整个 EAS Build 构建过程的一体化功能。它根据你的 eas.json 中的构建配置文件设置解析最佳构建配置。

¥The all-in-one function that encapsulates the entire EAS Build build process. It resolves the best build configuration based on your build profile's settings from eas.json.

它非常适合那些希望完成构建而不必担心手动更改和配置构建过程的人。如果你有兴趣在构建过程之前或之后使用其他自定义步骤并且不想更改构建过程本身,那么它可能是自定义构建配置的一个很好的起点。

¥It's ideal for people who want to have the build done without worrying about altering and configuring the build process manually. It can be a great starting point for your custom build configuration if you are interested in using other custom steps before or after the build process and you don't want to change the build process itself.

example.yml
build:
  name: Run a build using a single command
  steps:
    - eas/build

要更好地控制构建过程并根据你的要求对其进行自定义,请参阅 eas/build 在后台运行的以下自定义函数和步骤。它们根据你的构建配置文件的配置作为构建过程执行。

¥To have more control over the build process and customize it as per your requirements, see the following custom functions and steps that run in the background by eas/build. They are executed as a build process based on your build profile's configuration.

安卓

¥Android

当构建配置使用 withoutCredentials 时:

¥When a build configuration is using withoutCredentials:

当构建配置使用凭据时(对于 internalstore distribution 构建):

¥When a build configuration uses credentials (for both internal and store distribution builds):

iOS 系统

¥iOS

当构建配置使用 withoutCredentialssimulator 时:

¥When a build configuration is using withoutCredentials or simulator:

当构建配置使用凭据时(对于 internalstore distribution 构建):

¥When a build configuration uses credentials (for both internal and store distribution builds):

你可以通过在 YAML 配置文件中使用以下步骤来替换 eas/build 命令调用:

¥You can replace the eas/build command call by using these steps in your YAML configuration file:

ios-simulator-build.yml

查看示例存储库中 iOS 模拟器构建的 `eas/build` 函数在幕后执行的步骤。

ios-credentials-build.yml

使用我们的示例存储库中的凭据查看 iOS 构建的 `eas/build` 函数在幕后执行的步骤。

android-build-without-credentials.yml

在我们的示例存储库中查看 `eas/build` 函数在没有凭据的情况下针对 Android 构建在幕后执行的步骤。

android-build-with-credentials.yml

使用示例存储库中的凭据查看 Android 构建的 `eas/build` 函数在幕后执行的步骤。

已知的限制

¥Known limitations

  • 它不接受任何输入,并且已解析的构建过程将根据 eas.json 中的构建配置文件进行配置。

    ¥It doesn't accept any inputs, and the resolved build process will be configured based on your build profile from eas.json.

  • eas/build 生成的构建过程不可配置,你也无法自定义它。如果你需要自定义构建过程,请使用此函数在后台执行的函数和步骤的子集,并在 YAML 配置文件中手动配置它们,如上面的示例所示。

    ¥The build process produced by eas/build is not configurable and you can't customize it. If you need to customize the build process, use the subset of functions and steps that are executed behind the scenes by this function and configure them manually in the YAML configuration file, as shown in the examples above.

eas/maestro_test

安装 Maestro、准备测试环境(Android 模拟器或 iOS 模拟器)并测试应用的一体化功能。

¥All-in-one function that installs Maestro, prepares a testing environment (Android Emulator or iOS Simulator), and tests the app.

你的项目必须配置为使用旧的 Build Infrastructure 来启动 Android 模拟器。转到 项目设置 进行配置。请参阅 此更改日志帖子 了解更多信息。
输入类型描述
flow_pathstring运行 大师流 的路径(或多个路径,每个路径占一行)。
app_pathstring应测试的模拟器/模拟器应用的路径(或正则表达式模式)。如果未提供,则默认为 Android 的 android/app/build/outputs/**/*.apk 和 iOS 的 ios/build/Build/Products/simulator/.app。
build-and-test.yml
build:
  name: Build and test
  steps:
    - eas/build
    - eas/maestro_test:
        inputs:
          flow_path: |
            maestro/sign_in.yml
            maestro/create_post.yml
            maestro/sign_out.yml
test-ios-simulator-app.yml
build:
  name: Build and test iOS simulator app
  steps:
    - eas/checkout
    - eas/maestro_test:
        app_path: ./fixtures/my_app.app
        inputs:
          flow_path: |
            maestro/sign_in.yml
            maestro/create_post.yml
            maestro/sign_out.yml
test-android-emulator-app.yml
build:
  name: Build and test Android emulator app
  steps:
    - eas/checkout
    - eas/maestro_test:
        app_path: ./fixtures/my_app.apk
        inputs:
          flow_path: |
            maestro/sign_in.yml
            maestro/create_post.yml
            maestro/sign_out.yml

在幕后,它使用:

¥Behind the scenes, it uses:

警告 我们观察到,如果在使用 Xcode 15.0 或 15.2 的图片上运行,Maestro 测试经常会超时。使用 latest 图片避免任何问题。

¥We have observed that Maestro tests often time out if run on images with Xcode 15.0 or 15.2. Use the latest image to avoid any issues.

如果你需要自定义 Maestro 版本、运行特定的 Android 模拟器或 iOS 模拟器,或上传多个构建工件,你将需要自己编写这一系列步骤。

¥If you need to customize the Maestro version, run a specific Android Emulator or iOS Simulator, or upload multiple build artifacts you will need to write this series of steps yourself.

An example Android build config with eas/maestro_test expanded
build-and-test-android-expanded.yml
build:
  name: Build and test (Android, expanded)
  steps:
    - eas/build
    - eas/install_maestro
    - eas/start_android_emulator:
        inputs:
          system_package_name: system-images;android-34;default;x86_64
    - run:
        command: |
          # shopt -s globstar is necessary to add /**/ support
          shopt -s globstar
          # shopt -s nullglob is necessary not to try to install
          # SEARCH_PATH literally if there are no matching files.
          shopt -s nullglob

          SEARCH_PATH="android/app/build/outputs/**/*.apk"
          FILES_FOUND=false

          for APP_PATH in $SEARCH_PATH; do
            FILES_FOUND=true
            echo "Installing \\"$APP_PATH\\""
            adb install "$APP_PATH"
          done

          if ! $FILES_FOUND; then
            echo "No files found matching \\"$SEARCH_PATH\\". Are you sure you've built an Emulator app?"
            exit 1
          fi
    - run:
        command: |
          maestro test maestro/flow.yml
    - eas/upload_artifact:
        name: Upload test artifact
        if: ${ always() }
        inputs:
          type: build-artifact
          path: ${ eas.env.HOME }/.maestro/tests
An example iOS build config with eas/maestro_test expanded
build-and-test-ios-expanded.yml
build:
name: Build and test (iOS, expanded)
steps:
  - eas/build
  - eas/install_maestro
  - eas/start_ios_simulator
  - run:
      command: |
        # shopt -s nullglob is necessary not to try to install
        # SEARCH_PATH literally if there are no matching files.
        shopt -s nullglob

        SEARCH_PATH="ios/build/Build/Products/*simulator/*.app"
        FILES_FOUND=false

        for APP_PATH in $SEARCH_PATH; do
          FILES_FOUND=true
          echo "Installing \\"$APP_PATH\\""
          xcrun simctl install booted "$APP_PATH"
        done

        if ! $FILES_FOUND; then
          echo "No files found matching \\"$SEARCH_PATH\\". Are you sure you've built a Simulator app?"
          exit 1
        fi
  - run:
      command: |
        maestro test maestro/flow.yml
  - eas/upload_artifact:
      name: Upload test artifact
      if: ${ always() }
      inputs:
        type: build-artifact
        path: ${ eas.env.HOME }/.maestro/tests
eas/maestro_test 源代码

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

eas/checkout

Checks out your project source files.

For example, a build config with the following steps will check out the project and list the files in the assets directory:

upload.yml
build:
  name: List files
  steps:
    - eas/checkout
    - run:
        name: List assets
        run: ls assets
eas/结帐源代码

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

eas/use_npm_token

Configures node package managers (npm, pnpm, or Yarn) for use with private packages, published either to npm or a private registry. Set NPM_TOKEN in your project's secrets, and this function will configure the build environment by creating .npmrc with the token.

example.yml
build:
  name: Install private npm modules
  steps:
    - eas/checkout
    - eas/use_npm_token
    - run:
        name: Install dependencies
        run: npm install # <---- Can now install private packages
eas/use_npm_token 源代码

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

eas/install_node_modules

Installs node modules using the package manager (npm, pnpm, or Yarn) detected based on your project. Works with monorepos.

example.yml
build:
  name: Install node modules
  steps:
    - eas/checkout
    - eas/install_node_modules
eas/install_node_modules 源代码

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

eas/resolve_build_config

Resolves and prints the build configuration. If the build has been triggered by the GitHub integration, it will update the current job and metadata context values. It should be called after installing the dependencies because the config may be influenced by config plugins.

This function is automatically executed by the eas/build function group.

eas/resolve_build_config 源代码

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

eas/get_credentials_for_build_triggered_by_github_integration

Deprecated: Replace this step with eas/resolve_build_config.

eas/resolve_apple_team_id_from_credentials

This function is only available for iOS builds.

Resolves the Apple team ID value based on build credentials provided in the inputs.credentials. The resolved Apple team ID is stored in the outputs.apple_team_id output value.

example.yml
build:
  name: Run prebuild script
  steps:
    - eas/checkout
    - eas/install_node_modules
    - eas/resolve_apple_team_id_from_credentials:
        id: resolve_apple_team_id_from_credentials
    - eas/prebuild:
        inputs:
          apple_team_id: ${ steps.resolve_apple_team_id_from_credentials.apple_team_id }
PropertyTypeDescription
namestringThe name of the step in the reusable function that shows in the build logs. Defaults to Resolve Apple team ID from credentials.
inputs.credentialsjsonOptional input defining the app credentials for your iOS build. Defaults to ${ eas.job.secrets.buildCredentials }. Needs to comply to ${ eas.job.secrets.buildCredentials } schema for iOS.
eas/resolve_apple_team_id_from_credentials 源代码

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

eas/prebuild

Runs the expo prebuild command using the package manager (npm, pnpm, or Yarn) detected based on your project with the command best suited for your build type and build environment.

example.yml
build:
  name: Run prebuild script
  steps:
    - eas/checkout
    - eas/install_node_modules
    - eas/resolve_apple_team_id_from_credentials:
        id: resolve_apple_team_id_from_credentials
    - eas/prebuild:
        inputs:
          clean: false
          apple_team_id: ${ steps.resolve_apple_team_id_from_credentials.apple_team_id }
example.yml
build:
  name: Run prebuild script
  steps:
    - eas/checkout
    - eas/install_node_modules
    - eas/prebuild
PropertyTypeDescription
name-The name of the step in the reusable function that shows in the build logs. Defaults to Prebuild.
inputs.cleanbooleanOptional input defining whether the function should use --clean flag when running the command. Defaults to false
inputs.apple_team_idbooleanOptional input defining Apple team ID which should be used when doing prebuild. It should be specified for iOS builds using credentials.
eas/预构建源代码

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

eas/configure_eas_update

To use this function you need to have EAS Update configured for your project.

Configures runtime version and release channel for your build.

example.yml
build:
  name: Configure EAS Update
  steps:
    - eas/checkout
    - eas/install_node_modules
    - eas/prebuild
    - eas/configure_eas_update
example.yml
build:
  name: Configure EAS Update
  steps:
    - eas/checkout
    - eas/install_node_modules
    - eas/prebuild
    - eas/configure_eas_update:
        inputs:
          runtime_version: 1.0.0
          channel: mychannel
PropertyTypeDescription
name-The name of the step in the reusable function that shows in the build logs. Defaults to Configure EAS Update.
inputs.runtime_versionstringOptional input defining runtime version which should be configured for the build. Defaults to ${ eas.job.version.runtimeVersion } or natively defined runtime version.
inputs.channelstringOptional input defining channel which should be configured for the build. Defaults to ${ eas.job.updates.channel }.
eas/configure_eas_update 源代码

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

eas/inject_android_credentials

This function is only available for Android builds.

Configures Android keystore with credentials on the builder and injects app signing config using these credentials into gradle config.

example.yml
build:
  name: Android credentials
  steps:
    - eas/checkout
    - eas/install_node_modules
    - eas/prebuild
    - eas/inject_android_credentials
PropertyTypeDescription
name-The name of the step in the reusable function that shows in the build logs. Defaults to Inject Android credentials.
inputs.credentialsjsonOptional input defining the app credentials for your Android build. Defaults to ${ eas.job.secrets.buildCredentials }. Needs to comply to ${ eas.job.secrets.buildCredentials } schema for Android.
eas/inject_android_credentials 源代码

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

eas/configure_ios_credentials

This function is only available for iOS builds.

Configures iOS credentials on the builder. Modifies the configuration of the Xcode project by assigning provisioning profiles to the targets.

example.yml
build:
  name: iOS credentials
  steps:
    - eas/checkout
    - eas/install_node_modules
    - eas/resolve_apple_team_id_from_credentials:
        id: resolve_apple_team_id_from_credentials
    - eas/prebuild:
        inputs:
          clean: false
          apple_team_id: ${ steps.resolve_apple_team_id_from_credentials.apple_team_id }
    - eas/configure_ios_credentials
PropertyTypeDescription
name-The name of the step in the reusable function that shows in the build logs. Defaults to Configure iOS credentials.
inputs.build_configurationstringOptional input defining the Xcode project's Build Configuration. Defaults to ${ eas.job.buildConfiguration } or if not specified is resolved to Debug for development client or Release for other builds.
inputs.credentialsjsonOptional input defining the app credentials for your iOS build. Defaults to ${ eas.job.secrets.buildCredentials }. Needs to comply to ${ eas.job.secrets.buildCredentials } schema for iOS.
eas/configure_ios_credentials 源代码

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

eas/configure_android_version

This function is only available for Android builds.

Configures the version of your Android app. It's used to set a version when using remote app version management.

It's not mandatory to use this function, if it's not used the version from native code generated during the prebuild phase will be used.

example.yml
build:
  name: Configure Android version
  steps:
    - eas/checkout
    - eas/install_node_modules
    - eas/prebuild
    - eas/configure_eas_update
    - eas/inject_android_credentials
    - eas/configure_android_version
example.yml
build:
  name: Configure Android version
  steps:
    - eas/checkout
    - eas/install_node_modules
    - eas/prebuild
    - eas/configure_eas_update
    - eas/inject_android_credentials
    - eas/configure_android_version:
        inputs:
          version_code: '123'
          version_name: '1.0.0'
PropertyTypeDescription
name-The name of the step in the reusable function that shows in the build logs. Defaults to Configure Android version.
inputs.version_codestringOptional input defining versionCode of your Android build. Defaults to ${ eas.job.version.versionCode }
inputs.version_namestringOptional input defining versionName of your Android build. Defaults to ${ eas.job.version.versionName }.
eas/configure_android_version 源代码

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

eas/configure_ios_version

This function is only available for iOS builds.

Configures the version of your iOS app. It's used to set a version when using remote app version management.

It's not mandatory to use this function, if it's not used the version from native code generated during the prebuild phase will be used.

example.yml
build:
  name: Configure iOS version
  steps:
    - eas/checkout
    - eas/install_node_modules
    - eas/resolve_apple_team_id_from_credentials:
        id: resolve_apple_team_id_from_credentials
    - eas/prebuild:
        inputs:
          clean: false
          apple_team_id: ${ steps.resolve_apple_team_id_from_credentials.apple_team_id }
    - eas/configure_eas_update
    - eas/configure_ios_credentials
    - eas/configure_ios_version
example.yml
build:
  name: Configure iOS version
  steps:
    - eas/checkout
    - eas/install_node_modules
    - eas/resolve_apple_team_id_from_credentials:
        id: resolve_apple_team_id_from_credentials
    - eas/prebuild:
        inputs:
          clean: false
          apple_team_id: ${ steps.resolve_apple_team_id_from_credentials.apple_team_id }
    - eas/configure_eas_update
    - eas/configure_ios_credentials
    - eas/configure_ios_version:
        inputs:
          build_number: '123'
          app_version: '1.0.0'
PropertyTypeDescription
name-The name of the step in the reusable function that shows in the build logs. Defaults to Configure iOS version.
inputs.build_numberstringOptional input defining the build number (CFBundleVersion) of your iOS build. Defaults to ${ eas.job.version.buildNumber }
inputs.app_versionstringOptional input defining the app version (CFBundleShortVersionString) of your iOS build. Defaults to ${ eas.job.version.appVersion }.
inputs.build_configurationstringOptional input defining the Xcode project's Build Configuration. Defaults to ${ eas.job.buildConfiguration } or if not specified is resolved to Debug for development client or Release for other builds.
inputs.credentialsjsonOptional input defining the app credentials for your iOS build. Defaults to ${ eas.job.secrets.buildCredentials }. Needs to comply to ${ eas.job.secrets.buildCredentials } schema for iOS.
eas/configure_ios_version 源代码

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

eas/run_gradle

This function is only available for Android builds.

Runs a Gradle command to build an Android app.

example.yml
build:
  name: Build Android app
  steps:
    - eas/checkout
    - eas/install_node_modules
    - eas/prebuild
    - eas/configure_eas_update
    - eas/inject_android_credentials
    - eas/run_gradle
example.yml
build:
  name: Build Android app
  steps:
    - eas/checkout
    - eas/install_node_modules
    - eas/prebuild
    - eas/configure_eas_update
    - eas/inject_android_credentials
    - eas/run_gradle:
        inputs:
          command: :app:bundleRelease
PropertyTypeDescription
name-The name of the step in the reusable function that shows in the build logs. Defaults to Run gradle.
inputs.commandstringOptional input defining the Gradle command to run to build the Android app. If not specified it is resolved based on the build configuration and contents of the ${ eas.job } object.
eas/run_gradle 源代码

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

eas/generate_gymfile_from_template

This function is only available for iOS builds.

Generates a Gymfile used to build the iOS app using Fastlane from a template.

Default template used when credentials are passed:

Gymfile
suppress_xcode_output(true)
clean(<%- CLEAN %>)

scheme("<%- SCHEME %>")
<% if (BUILD_CONFIGURATION) { %>
configuration("<%- BUILD_CONFIGURATION %>")
<% } %>

export_options({
method: "<%- EXPORT_METHOD %>",
provisioningProfiles: {<% _.forEach(PROFILES, function(profile) { %>
    "<%- profile.BUNDLE_ID %>" => "<%- profile.UUID %>",<% }); %>
}<% if (ICLOUD_CONTAINER_ENVIRONMENT) { %>,
iCloudContainerEnvironment: "<%- ICLOUD_CONTAINER_ENVIRONMENT %>"
<% } %>
})

export_xcargs "OTHER_CODE_SIGN_FLAGS=\\"--keychain <%- KEYCHAIN_PATH %>\\""

disable_xcpretty(true)
buildlog_path("<%- LOGS_DIRECTORY %>")

output_directory("<%- OUTPUT_DIRECTORY %>")

Default template used when credentials are not passed (simulator build):

Gymfile
suppress_xcode_output(true)
clean(<%- CLEAN %>)

scheme("<%- SCHEME %>")
<% if (BUILD_CONFIGURATION) { %>
configuration("<%- BUILD_CONFIGURATION %>")
<% } %>

derived_data_path("<%- DERIVED_DATA_PATH %>")
skip_package_ipa(true)
skip_archive(true)
destination("<%- SCHEME_SIMULATOR_DESTINATION %>")

disable_xcpretty(true)
buildlog_path("<%- LOGS_DIRECTORY %>")

CLEAN, SCHEME, BUILD_CONFIGURATION, EXPORT_METHOD, PROFILES, ICLOUD_CONTAINER_ENVIRONMENT, KEYCHAIN_PATH, LOGS_DIRECTORY, OUTPUT_DIRECTORY, DERIVED_DATA_PATHand SCHEME_SIMULATOR_DESTINATION values are provided to the template based on the inputs and default internal configuration of EAS Build.

example.yml
build:
  name: Generate Gymfile template
  steps:
    - eas/checkout
    - eas/install_node_modules
    - eas/resolve_apple_team_id_from_credentials:
        id: resolve_apple_team_id_from_credentials
    - eas/prebuild:
        inputs:
          clean: false
          apple_team_id: ${ steps.resolve_apple_team_id_from_credentials.apple_team_id }
    - eas/configure_eas_update
    - eas/configure_ios_credentials
    - eas/generate_gymfile_from_template:
        inputs:
          credentials: ${ eas.job.secrets.buildCredentials }
example.yml
build:
  name: Generate Gymfile template
  steps:
    - eas/checkout
    - eas/install_node_modules
    - eas/prebuild
    - eas/generate_gymfile_from_template

However, you can also use other custom properties in the template, by specifying your custom template in inputs.template and providing the values for the custom properties in the inputs.extra object.

example.yml
build:
  name: Generate Gymfile template
  steps:
    - eas/checkout
    - eas/install_node_modules
    - eas/resolve_apple_team_id_from_credentials:
        id: resolve_apple_team_id_from_credentials
    - eas/prebuild:
        inputs:
          clean: false
          apple_team_id: ${ steps.resolve_apple_team_id_from_credentials.apple_team_id }
    - eas/configure_eas_update
    - eas/configure_ios_credentials
    - eas/generate_gymfile_from_template:
        inputs:
          credentials: ${ eas.job.secrets.buildCredentials }
          extra:
            MY_VALUE: my value
          template: |
            suppress_xcode_output(true)
            clean(<%- CLEAN %>)

            scheme("<%- SCHEME %>")
            <% if (BUILD_CONFIGURATION) { %>
            configuration("<%- BUILD_CONFIGURATION %>")
            <% } %>

            export_options({
            method: "<%- EXPORT_METHOD %>",
            provisioningProfiles: {<% _.forEach(PROFILES, function(profile) { %>
                "<%- profile.BUNDLE_ID %>" => "<%- profile.UUID %>",<% }); %>
            }<% if (ICLOUD_CONTAINER_ENVIRONMENT) { %>,
            iCloudContainerEnvironment: "<%- ICLOUD_CONTAINER_ENVIRONMENT %>"
            <% } %>
            })

            export_xcargs "OTHER_CODE_SIGN_FLAGS=\"--keychain <%- KEYCHAIN_PATH %>\""

            disable_xcpretty(true)
            buildlog_path("<%- LOGS_DIRECTORY %>")

            output_directory("<%- OUTPUT_DIRECTORY %>")

            sth_else("<%- MY_VALUE %>")
PropertyTypeDescription
name-The name of the step in the reusable function that shows in the build logs. Defaults to Generate Gymfile from template.
inputs.templatestringOptional input defining the Gymfile template which should be used. If not specified one out of two default templates will be used depending on whether the inputs.credentials value is specified.
inputs.credentialsjsonOptional input defining the app credentials for your iOS build. If specified KEYCHAIN_PATH, EXPORT_METHOD, and PROFILES values will be provided to the template.
inputs.build_configurationstringOptional input defining the Xcode project's Build Configuration. Defaults to ${ eas.job.buildConfiguration } or if not specified is resolved to Debug for development client or Release for other builds. Corresponds to the BUILD_CONFIGURATION template value.
inputs.schemestringOptional input defining the Xcode project's scheme which should be used for the build. Defaults to ${ eas.job.scheme } or if not specified is resolved to the first scheme found in the Xcode project. Corresponds to the SCHEME template value.
inputs.cleanbooleanOptional input defining whether the Xcode project should be cleaned before the build. Defaults to true. Corresponds to CLEAN template variable.
inputs.extrajsonOptional input defining extra values which should be provided to the template.
eas/generate_gymfile_from_template 源代码

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

eas/run_fastlane

This function is only available for iOS builds.

Runs fastlane gym command against the Gymfile located in the ios project directory to build the iOS app.

example.yml
build:
  name: Build iOS app
  steps:
    - eas/checkout
    - eas/install_node_modules
    - eas/resolve_apple_team_id_from_credentials:
        id: resolve_apple_team_id_from_credentials
    - eas/prebuild:
        inputs:
          clean: false
          apple_team_id: ${ steps.resolve_apple_team_id_from_credentials.apple_team_id }
    - eas/configure_eas_update
    - eas/configure_ios_credentials
    - eas/generate_gymfile_from_template:
        inputs:
          credentials: ${ eas.job.secrets.buildCredentials }
    - eas/run_fastlane
example.yml
build:
  name: Build iOS app
  steps:
    - eas/checkout
    - eas/install_node_modules
    - eas/prebuild
    - eas/configure_eas_update
    - eas/generate_gymfile_from_template
    - eas/run_fastlane
eas/run_fastlane 源代码

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

eas/find_and_upload_build_artifacts

You can currently upload each artifact type only once per build job.
If you use eas/find_and_upload_build_artifacts while having buildArtifactPaths configured in your build profile and the step finds and uploads some build artifacts, any following eas/upload_artifact step will fail.
To solve this, for now, we recommend removing buildArtifactPaths from custom build's profiles and uploading artifacts manually with eas/upload_artifact in the YAML if you need to call it there.

Automatically finds and uploads application archive, additional build artifacts, and Xcode logs from the default locations and using the buildArtifactPaths configuration. Uploads found artifacts to the EAS servers.

example.yml
build:
  name: Build iOS app
  steps:
    - eas/checkout
    - eas/install_node_modules
    - eas/resolve_apple_team_id_from_credentials:
        id: resolve_apple_team_id_from_credentials
    - eas/prebuild:
        inputs:
          clean: false
          apple_team_id: ${ steps.resolve_apple_team_id_from_credentials.apple_team_id }
    - eas/configure_eas_update
    - eas/configure_ios_credentials
    - eas/generate_gymfile_from_template:
        inputs:
          credentials: ${ eas.job.secrets.buildCredentials }
    - eas/run_fastlane
    - eas/find_and_upload_build_artifacts
example.yml
build:
  name: Build iOS app
  steps:
    - eas/checkout
    - eas/install_node_modules
    - eas/prebuild
    - eas/configure_eas_update
    - eas/generate_gymfile_from_template
    - eas/run_fastlane
    - eas/find_and_upload_build_artifacts
example.yml
build:
  name: Build Android app
  steps:
    - eas/checkout
    - eas/install_node_modules
    - eas/prebuild
    - eas/configure_eas_update
    - eas/inject_android_credentials
    - eas/run_gradle
    - eas/find_and_upload_build_artifacts
eas/find_and_upload_build_artifacts 源代码

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

eas/upload_artifact

Uploads build artifacts from provided paths.

You can currently upload each artifact type only once per build job.
If you use eas/find_and_upload_build_artifacts while having buildArtifactPaths configured in your build profile and the step finds and uploads some build artifacts, any following eas/upload_artifact step will fail.
To solve this, for now, we recommend removing buildArtifactPaths from custom build's profiles and uploading artifacts manually with eas/upload_artifact in the YAML if you need to call it there.

For example, a build config with the following steps will upload an artifact to the EAS servers:

upload.yml
build:
  name: Upload artifacts
  steps:
    - eas/checkout
    # - ...
    - eas/upload_artifact:
        name: Upload application archive
        inputs:
          path: fixtures/app-debug.apk
    - eas/upload_artifact:
        name: Upload artifacts
        inputs:
          type: build-artifact
          path: |
            assets/*.jpg
            assets/*.png
InputTypeDescription
pathstringRequired. Path or newline-delimited list of paths to the artifacts to upload to EAS servers. You can use * wildcard and other glob patterns that fast-glob supports.
typestringThe type of artifact that is uploaded to the EAS servers. Allowed values are application-archive and build-artifact. Defaults to application-archive.
eas/upload_artifact 源代码

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

eas/install_maestro

Makes sure Maestro, the mobile UI testing framework, is installed along with all its dependencies.

build-and-test.yml
build:
  name: Build and test
  steps:
    - eas/build
    # ... simulator/emulator setup
    - eas/install_maestro:
        inputs:
          maestro_version: 1.35.0
    - run:
        command: maestro test flows/signin.yml
    - eas/upload_artifact:
        name: Upload Maestro artifacts
        inputs:
          type: build-artifact
          path: ${ eas.env.HOME }/.maestro/tests
InputTypeDescription
maestro_versionstringMaestro version to install (for example, 1.35.0). If not provided, install_maestro will install the latest version.
eas/install_maestro 源代码

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

eas/start_android_emulator

Starts an Android Emulator you can use to test your apps on. Only available when running a build for Android.

Your project must be configured to use the old Build Infrastructure to start Android Emulator. Go to Project settings to configure. See this changelog post for more information.
build-and-test.yml
build:
  name: Build and test
  steps:
    - eas/build
    - eas/start_android_emulator:
        inputs:
          system_image_package: system-images;android-30;default;x86_64
    # ... Maestro setup and tests
InputTypeDescription
device_namestringName for the created device. You can customize it if starting multiple emulators.
system_image_packagestringAndroid package path to use for the emulator. For example, system-images;android-30;default;x86_64.
To get a list of available system images, run sdkmanager --list on a local computer. VMs run on x86_64 architecture, so always choose x86_64 package variants. The sdkmanager tool comes from Android SDK command-line tools.
eas/start_android_emulator 源代码

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

eas/start_ios_simulator

Starts an iOS Simulator you can use to test your apps on. Only available when running a build for iOS.

build-and-test.yml
build:
  name: Build and test
  steps:
    - eas/build
    - eas/start_ios_simulator
    # ... Maestro setup and tests
InputTypeDescription
device_identifierstringName or UDID of the Simulator you want to start. Examples include iPhone [XY] Pro, AEF997BB-222C-4379-89BA-D21070B1D787.
Note: Available Simulators are different for every image. If you change the image, the Simulator for a given name may become unavailable. For instance, an Xcode 14 image will have iPhone 14 Simulators, while an Xcode 15 image will have iPhone 15 simulators. In general, we encourage not providing this input. See runner images for more information.
eas/start_ios_simulator 源代码

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

eas/send_slack_message

Sends a specified message to a configured Slack webhook URL, which then posts it in the related Slack channel. The message can be specified as plain text or as a Slack Block Kit message. With both cases, you can reference build job properties and use other steps outputs in the message for dynamic evaluation. For example, 'Build URL: ${ eas.job.expoBuildUrl }', Build finished with status: ${ steps.run_fastlane.status_text }, Build failed with error: ${ steps.run_gradle.error_text }. Either "message" or "payload" has to be specified, but not both.

send-slack-message.yml
build:
  name: Slack your team from custom build
  steps:
    - eas/send_slack_message:
        name: Send Slack message to a given webhook URL
        inputs:
          message: 'This is a message to plain input URL'
          slack_hook_url: 'https://hooks.slack.com/services/[rest_of_hook_url]'
    - eas/send_slack_message:
        name: Send Slack message to a default webhook URL from SLACK_HOOK_URL secret
        inputs:
          message: 'This is a test message to default URL from SLACK_HOOK_URL secret'
    - eas/send_slack_message:
        name: Send Slack message to a webhook URL from specified secret
        inputs:
          message: 'This is a test message to a URL from specified secret'
          slack_hook_url: ${ eas.env.ANOTHER_SLACK_HOOK_URL }

    - eas/build
    - eas/send_slack_message:
        if: ${ always() }
        name: Send Slack message when the build finishes (Android)
        inputs:
          message: |
            This is a test message when Android build finishes
            Status: `${ steps.run_gradle.status_text }`
            Link: `${ eas.job.expoBuildUrl }`
    - eas/send_slack_message:
        if: ${ always() }
        name: Send Slack message when the build finishes (iOS)
        inputs:
          message: |
            This is a test message when iOS build finishes
            Status: `${ steps.run_fastlane.status_text }`
            Link: `${ eas.job.expoBuildUrl }`
    - eas/send_slack_message:
        if: ${ failure() }
        name: Send Slack message when the build fails (Android)
        inputs:
          message: |
            This is a test message when Android build fails
            Error: `${ steps.run_gradle.error_text }`
    - eas/send_slack_message:
        if: ${ failure() }
        name: Send Slack message when the build fails (iOS)
        inputs:
          message: |
            This is a test message when iOS build fails
            Error: `${ steps.run_fastlane.error_text }`
    - eas/send_slack_message:
        if: ${ success() }
        name: Send Slack message when the build succeeds
        inputs:
          message: |
            This is a test message when build succeeds
    - eas/send_slack_message:
        if: ${ always() }
        name: Send Slack message with Slack Block Kit layout
        inputs:
          payload:
            blocks:
              - type: section
                text:
                  type: mrkdwn
                  text: |-
                    Hello, Sir Developer

                     *Your build has finished!*
              - type: divider
              - type: section
                text:
                  type: mrkdwn
                  text: |-
                    *${ eas.env.EAS_BUILD_ID }*
                    *Status:* `${ steps.run_gradle.status_text }`
                    *Link:* `${ eas.job.expoBuildUrl }`
                accessory:
                  type: image
                  image_url: [your_image_url]
                  alt_text: alt text for image
              - type: divider
              - type: actions
                elements:
                  - type: button
                    text:
                      type: plain_text
                      text: 'Do a thing :rocket:'
                      emoji: true
                    value: a_thing
                  - type: button
                    text:
                      type: plain_text
                      text: 'Do another thing :x:'
                      emoji: true
                    value: another_thing
InputTypeDescription
messagestringThe text of the message you want to send. For example, 'This is the content of the message'.

Note: Either message or payload needs to be provided, but not both.
payloadstringThe contents of the message you want to send defined using Slack Block Kit layout.

Note: Either message or payload needs to be provided, but not both.
slack_hook_urlstringThe URL of the previously configured Slack webhook URL, which will post your message to the specified channel. You can provide the plain URL like slack_hook_url: 'https://hooks.slack.com/services/[rest_of_hook_url]', use EAS secrets like slack_hook_url: ${ eas.env.ANOTHER_SLACK_HOOK_URL }, or set the SLACK_HOOK_URL secret, which will serve as a default webhook URL (in this last case, there is no need to provide slack_hook_url input).
eas/send_slack_message 源代码

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

Using built-in EAS functions to build an app

Using the built-in EAS functions you can recreate the default EAS Build process for different build types.

For example, to trigger a build that creates internal distribution build for Android and a simulator build for iOS you can use the following configuration:

eas.json
{
  %%placeholder-start%%... %%placeholder-end%%
  "build": {
    %%placeholder-start%%... %%placeholder-end%%
    "developmentBuild": {
      "distribution": "internal",
      "android": {
        "config": "development-build-android.yml"
      },
      "ios": {
        "simulator": true,
        "config": "development-build-ios.yml"
      }
    }
    %%placeholder-start%%... %%placeholder-end%%
  }
  %%placeholder-start%%... %%placeholder-end%%
}
.eas/build/development-build-android.yml
build:
  name: Simple internal distribution Android build
  steps:
    - eas/checkout

    - eas/install_node_modules

    - eas/prebuild

    - eas/inject_android_credentials

    - eas/run_gradle

    - eas/find_and_upload_build_artifacts
.eas/build/development-build-ios.yml
build:
  name: Simple simulator iOS build
  steps:
    - eas/checkout

    - eas/install_node_modules

    - eas/prebuild

    - run:
        name: Install pods
        working_directory: ./ios
        command: pod install

    - eas/generate_gymfile_from_template

    - eas/run_fastlane

    - eas/find_and_upload_build_artifacts

To create a Google Play Store build for Android and an Apple App Store build for iOS you can use the following configuration:

eas.json
{
  %%placeholder-start%%... %%placeholder-end%%
  "build": {
    %%placeholder-start%%... %%placeholder-end%%
    "productionBuild": {
      "android": {
        "config": "production-build-android.yml"
      },
      "ios": {
        "config": "production-build-ios.yml"
      }
    }
    %%placeholder-start%%... %%placeholder-end%%
  }
  %%placeholder-start%%... %%placeholder-end%%
}
.eas/build/production-build-android.yml
build:
  name: Customized Android Play Store build example
  steps:
    - eas/checkout

    - eas/install_node_modules

    - eas/prebuild

    - eas/inject_android_credentials

    - eas/run_gradle

    - eas/find_and_upload_build_artifacts
.eas/build/production-build-ios.yml
build:
  name: Customized iOS App Store build example
  steps:
    - eas/checkout

    - eas/install_node_modules

    - eas/resolve_apple_team_id_from_credentials:
        id: resolve_apple_team_id_from_credentials

    - eas/prebuild:
        inputs:
          apple_team_id: ${ steps.resolve_apple_team_id_from_credentials.apple_team_id }

    - run:
        name: Install pods
        working_directory: ./ios
        command: pod install

    - eas/configure_ios_credentials

    - eas/generate_gymfile_from_template:
        inputs:
          credentials: ${ eas.job.secrets.buildCredentials }

    - eas/run_fastlane

    - eas/find_and_upload_build_artifacts

Check out the example repository for more detailed examples:

自定义构建示例存储库

自定义 EAS 构建示例,其中包括自定义构建的示例,例如设置函数、使用环境变量、上传工件等。

Use a reusable function in a build

For example, a custom build config with the following reusable function contains a single command to print a message that is echoed.

functions:
  greetings:
    - name: name
      default_value: Hello world
    inputs: [value]
    command: echo "${ inputs.name }, { inputs.value }"

The above function can be used in a build as follows:

build:
  name: Functions Demo
  steps:
    - greetings:
        inputs:
          value: Expo

info 提示:build.steps 可以顺序执行多个可复用的 functions

¥info Tip: build.steps can execute multiple reusable functions sequentially.

覆盖 build 中的值

¥Override values in a build

你可以覆盖以下属性的值:

¥You can override values for the following properties:

  • working_directory

  • name

  • shell

例如,一个名为 list_files 的可重用函数:

¥For example, a reusable function called list_files:

functions:
  list_files:
    name: List files
    command: ls -la

当在构建配置中调用 list_files 时,它会列出项目根目录中的所有文件:

¥When list_files is called in a build config, it lists all files in the root directory of a project:

build:
  name: List files
  steps:
    - eas/checkout
    - list_files

你可以使用 working_directory 属性覆盖函数调用中的行为,通过指定该目录的路径来列出不同目录中的文件:

¥You can use the working_directory property to override the behavior in the function call to list the files in a different directory by specifying the path to that directory:

build:
  name: List files
    steps:
      - eas/checkout
      - list_files:
          working_directory: /a/b/c