update-rollout pre-packaged job type
The update-rollout job increases rollout percentage of in-progress EAS Update rollout. Parameters: update_group_id (string, required), rollout_percentage (number, optional, 0-100, defaults to 100). Outputs: update_group_id, rollout_percentage, updates_json.
branch-delete pre-packaged job type
The branch-delete job deletes an EAS Update branch and all updates. Parameters: branch_name (string, required), fail_on_missing (boolean, optional, default: false). Outputs: branch_id, branch_name.
maestro pre-packaged job type
The maestro job runs Maestro tests on a build. Parameters: build_id (string, required), flow_path (string | string[], required), shards (number, optional, defaults to 1), retries (number, optional, defaults to 0), retry_failed_only (boolean, optional, defaults to true), record_screen (boolean, optional, defaults to false), include_tags (string | string[], optional), exclude_tags (string | string[], optional), maestro_version (string, optional), android_system_image_package (string, optional), device_identifier (string | object, optional), output_format (string, optional, defaults to junit), skip_build_check (boolean, optional, defaults to false). Maestro tests are in alpha.
maestro-cloud pre-packaged job type
The maestro-cloud job runs Maestro tests in Maestro Cloud. Parameters: build_id (string, required), maestro_project_id (string, required), flows (string, required), maestro_api_key (string, optional), include_tags (string | string[], optional), exclude_tags (string | string[], optional), maestro_version (string, optional), maestro_config (string, optional), device_locale (string, optional), device_model (string, optional), device_os (string, optional), skip_build_check (boolean, optional, defaults to false), name (string, optional), branch (string, optional), async (boolean, optional). Requires Maestro Cloud account and subscription.
slack pre-packaged job type
The slack job sends messages to a Slack channel. Parameters: webhook_url (string, required), message (string, required if payload not provided), payload (object, required if message not provided).
github-comment pre-packaged job type
The github-comment job posts reports of workflow's builds, updates, and deployments to GitHub pull requests. Parameters: message (string, optional), build_ids (string[], optional, defaults to all related), update_group_ids (string[], optional, defaults to all related), deployment_ids (string[], optional, defaults to all related), payload (string, optional for custom comment). Outputs: comment_url.
apple-device-registration-request job type
The apple-device-registration-request job pauses workflow until iOS device enrolls for Apple team and team member approves. Parameter: apple_team_identifier (string, optional).
require-approval pre-packaged job type
The require-approval job requires approval from a user before continuing. User can approve (success) or reject (failure).
doc pre-packaged job type
The doc job displays a Markdown section in workflow logs. Parameter: md (string, required).
repack pre-packaged job type
The repack job repackages app from existing build without full native rebuild. Parameters: build_id (string, required), profile (string, optional), embed_bundle_assets (boolean, optional), js_bundle_only (boolean, optional), ios_signing_use_source_app_entitlements (boolean, optional), ios_signing_app_entitlements_path (string, optional), message (string, optional), repack_version (string, optional), repack_package (string, optional).
Custom jobs in workflows
Custom jobs run custom code using built-in EAS functions and do not require a type field. They contain steps for sequential tasks.
jobs.<job_id>.steps structure
A job contains a sequence of tasks called steps. Steps can run commands. The steps field may only be provided in custom jobs and build jobs.
jobs.<job_id>.outputs configuration
A list of outputs defined by the job accessible to downstream jobs that depend on this job. Set outputs using the set-output function within a step. Downstream jobs access using: needs.<job_id>.outputs.<output_name> or after.<job_id>.outputs.<output_name>.
jobs.<job_id>.image VM selection
Specifies the VM image to use for the job. Possible values: auto or string (image name). Defaults to auto. See Infrastructure documentation for available images.
jobs.<job_id>.runs_on worker selection
Specifies the worker that executes the job. Available on custom jobs and build, maestro, maestro-cloud, and repack jobs. Possible values: linux-medium (default, 4 vCPU, 16 GiB RAM, 14 GiB SSD), linux-large (8 vCPU, 32 GiB RAM, 28 GiB SSD), linux-medium-nested-virtualization (4 vCPU, 16 GiB RAM, 14 GiB SSD, Android Emulator), linux-large-nested-virtualization (4 vCPU, 32 GiB RAM, 28 GiB SSD, Android Emulator), macos-medium (5 efficiency cores, 20 GiB RAM, 125 GiB SSD, iOS), macos-large (10 efficiency cores, 40 GiB RAM, 125 GiB SSD, iOS).
Worker requirements for emulators and builds
Android Emulator jobs must use a linux-*-nested-virtualization worker. iOS builds and iOS Simulator jobs must use a macos-* worker.
jobs.<job_id>.steps.<step>.id property
The id property identifies a step for reference. Useful for using the step's output in downstream jobs or other steps.
jobs.<job_id>.steps.<step>.name property
The name property provides a human-friendly name displayed in the job's logs. When not provided, the run command is used as the step name.
jobs.<job_id>.steps.<step>.run property
The run property contains the shell command to execute in the step.
jobs.<job_id>.steps.<step>.shell property
The shell property specifies the shell to use for running the command. Defaults to bash.
working_directory step override for run commands
The working_directory property can be defined at the step level to override the jobs.<job_id>.defaults.run.working_directory setting. When set, the run command executes in the specified directory.
Built-in EAS Workflow functions with eas/ prefix
EAS Workflows provides built-in reusable functions that start with the eas/ prefix: eas/checkout, eas/install_node_modules, eas/prebuild, eas/download_build, eas/restore_cache, eas/save_cache, eas/send_slack_message, eas/use_npm_token, eas/upload_artifact, eas/download_artifact, eas/posthog_capture_event, eas/posthog_flag_rollout, eas/posthog_wait_for_metric, eas/posthog_wait_for_query, eas/posthog_annotation, and eas/posthog_upload_sourcemaps.
eas/checkout ref parameter options
The eas/checkout function accepts a ref parameter to check out a different branch, tag, or commit. The ref parameter accepts: a branch name such as 'feature/add-icon' or qualified ref such as 'refs/heads/feature/add-icon', a tag as a qualified ref such as 'refs/tags/v1.2.3', or a full commit SHA. The repository ends up on a detached HEAD for tags and commits. The ref must be reachable from the repository's origin via shallow fetch. The ref parameter only works when project sources come from a Git repository (not local builds or uploaded tarballs).
eas/checkout ref parameter restrictions
The ref parameter must be set on the job's first eas/checkout step. Setting it on a later step fails because the project is already checked out.
eas/install_node_modules package manager detection
The eas/install_node_modules function installs node_modules using the package manager detected based on the project (bun, npm, pnpm, or Yarn). It works with monorepos.
eas/download_build artifact types and behavior
The eas/download_build function downloads an application archive with optional extensions parameter (defaults to [apk, aab, ipa, app]). By default, the artifact can be .apk, .aab, .ipa, .app file, or .tar.gz archive containing one or more of these. If the artifact is a .tar.gz archive, it will be extracted and the first file matching specified extensions will be returned. If the build produced no application archive, the step fails.
eas/download_build parameters and outputs
eas/download_build parameters: build_id (string, required) - ID of the build to download; extensions (array, optional) - list of file extensions to look for, defaults to [apk, aab, ipa, app]. Output: artifact_path - path to the downloaded artifact.
eas/prebuild with clean and apple_team_id options
The eas/prebuild function runs the expo prebuild command with detected package manager. Optional parameters include: clean (boolean) - whether to perform a clean prebuild; apple_team_id (string) - the Apple team ID to use for iOS builds.
eas/restore_cache and eas/save_cache parameters
eas/restore_cache parameters: key (string, required) - the cache key to restore; restore_keys (string, optional) - alternative keys to try if exact key not found; path (string, required) - directory path to cache. eas/save_cache parameters: key (string, required) - the cache key to save under; path (string, required) - directory path to cache.
eas/send_slack_message parameters
eas/send_slack_message requires either message or payload (but not both). Parameters include: message (string) - plaintext message to send; payload (object) - Slack Block Kit formatted message; slack_hook_url (string) - the Slack webhook URL. You can reference build job properties and step outputs in messages using dynamic evaluation syntax like ${{ needs.build_ios.outputs.build_id }}.
eas/use_npm_token configuration
The eas/use_npm_token function configures Node package managers (bun, npm, pnpm, or Yarn) for use with private packages by creating .npmrc with the token. Set NPM_TOKEN in your project's secrets and this function will configure the build environment.
eas/upload_artifact type restriction in non-build jobs
In a custom (non-build) job, set type: other to upload a generic artifact. The application-archive and build-artifact types are reserved for build jobs — using them in a custom job fails with an error.
eas/upload_artifact always() condition for failed steps
Use if: ${{ always() }} with eas/upload_artifact to upload results even when a previous step failed.
eas/download_artifact parameters
eas/download_artifact parameters: name (string, required if artifact_id not provided) - name of artifact to download; artifact_id (string, required if name not provided) - ID of artifact to download.
eas/posthog_capture_event parameters
eas/posthog_capture_event sends an analytics event to PostHog. Parameters include: event (string) - event name; properties (object, optional) - event properties; distinct_id (optional) - when not provided, event is sent anonymously without creating a PostHog person profile.
eas/posthog_flag_rollout parameters
eas/posthog_flag_rollout enables, disables, or rolls out a PostHog feature flag. Parameters: flag (string) - the feature flag key; active (boolean, optional) - enable/disable flag; rollout_percentage (number, optional) - percentage to roll out; payload (object, optional) - flag payload. Provide at least one of active, rollout_percentage, or payload.
eas/posthog_wait_for_metric parameters
eas/posthog_wait_for_metric pauses workflow until a HogQL query satisfies a comparison. Parameters: query (string) - HogQL query; operator (string) - comparison operator (e.g., lt, gt, eq); threshold (number) - comparison threshold; interval_seconds (number, optional) - how often to run query; timeout_seconds (number, optional) - max wait time. Runs query every interval_seconds until comparison is true or timeout elapses. This step has no ignore_error input; timeout or unreadable query always fails the step.
eas/posthog_wait_for_query parameters
eas/posthog_wait_for_query pauses workflow until a HogQL query returns true. Parameter: query (string) - HogQL query. Step clears when first column of first row is true or nonzero number. Write query to select single boolean (e.g., SELECT count() > 100 FROM events). This step has no ignore_error input; timeout or unreadable query always fails the step.
eas/posthog_annotation creates timeline annotation
The eas/posthog_annotation function creates a PostHog annotation on the project timeline. Annotations show up on PostHog charts and are useful for marking builds, releases, and other milestones next to metrics they affect. Parameter: content (string) - annotation text.
eas/posthog_upload_sourcemaps source map handling
eas/posthog_upload_sourcemaps uploads JavaScript source maps to PostHog so PostHog can symbolicate stack traces in error tracking. Run it after the step that produces the bundle. Export source maps with npx expo export --source-maps and configure PostHog Metro config so bundles carry chunk IDs matching source maps. Parameter: directory (string) - directory containing source maps.
eas/posthog_upload_sourcemaps CLI error handling warning
The eas/posthog_upload_sourcemaps step runs the PostHog CLI, which cannot distinguish permissions errors from other failures. Setting ignore_error: true hides authentication and scope errors, unlike other PostHog functions.
Custom function definition file requirements
Each custom function must be stored in a directory containing a function.yml or function.yaml file. The YAML file supports top-level properties: name, description, inputs, outputs, and runs. EAS Workflows rejects unknown top-level properties.
Custom function uses path rules
Custom functions are called through uses with a relative path starting with ./ or ../. The path must be a static, literal string and cannot contain ${{ }} interpolation or backslashes.
Custom function working_directory restriction
Do not set working_directory on custom function call steps. Set it on the function's inner steps instead.
Custom function call step properties
Custom function calls accept the same fields as built-in function calls: id, name, with, if, and env.
Custom function inputs shorthand form
Custom function inputs can use shorthand form as a list of names. Each input becomes an optional string input with no default value. Example: inputs: [who]
Custom function inputs full form properties
Custom function inputs full form uses list of objects with properties: name (string, required) - input name used as ${{ inputs.<name> }}; type (string, optional) - input type: string, boolean, number, or json, defaults to string; default_value (optional) - value when not provided, must match type; allowed_values (array, optional) - allowed values for input; required (boolean, optional) - whether input must be provided, defaults to false.
Custom function outputs declaration
Custom function outputs are declared as map keyed by output name with properties: value (required) - expression resolving to output value such as ${{ steps.<id>.outputs.<name> }}; description (optional) - description of output. EAS Workflows exposes outputs as strings, read as ${{ steps.<call_id>.outputs.<name> }} using the id from the call step, not internal function step identifiers.
Custom function runs.steps requirements
runs.steps is required in custom functions and must contain at least one step. Steps use same format as custom job steps including id, run, uses, if, and working_directory. Currently, custom functions cannot call eas/build or eas/maestro_test.
set-output shell function syntax
The set-output shell function sets an output variable accessible by other steps or jobs: set-output <name> <value>. Example: set-output variable_1 "Variable 1" sets an output named variable_1 with value "Variable 1" accessible as ${{ steps.step_1.outputs.variable_1 }}.
set-output for sharing between jobs
To share set-output values between jobs, define outputs in the source job as ${{ steps.<id>.outputs.<name> }} and use needs.<job_id>.outputs.<name> in the receiving job.
set-env shell function syntax
The set-env shell function sets an environment variable available to subsequent steps in the same job: set-env <name> <value>. Example: set-env SHARED_VAR "available in next steps". Variables shared with set-env are not automatically exported locally; call export yourself if needed in current step.
set-env availability scope limitation
The set-env function only shares environment variables with other steps within the same job. Variables exported using export in one step are not automatically exposed to other steps.
inputs context in workflows
The inputs context is a record of inputs provided when manually triggering a workflow with workflow_dispatch via eas workflow:run command with input parameters.
Sharing environment variables between jobs pattern
To share values between different jobs, use the source job's outputs with set-output and pass them via the env property on the receiving job using ${{ needs.<job_id>.outputs.<name> }}.
Workflow files location and naming requirements
Workflow files use YAML syntax with either a .yml or .yaml file extension and must be 16 KiB or smaller. Workflow files are located in the .eas/workflows directory in your project. The .eas directory should be at the same level as your eas.json file.
Workflow name property
The name field defines a human-friendly name for the workflow. This name is displayed on the EAS dashboard on the workflows list page and is the title of the workflow's detail page.
Workflow on trigger key
The on key defines which GitHub events trigger the workflow. Supported trigger types include: push, pull_request, pull_request_labeled, ref_delete, app_store_connect, schedule, and workflow_dispatch. Any workflow can be triggered with the eas workflow:run command regardless of the on key.
Skip workflow runs with commit messages
You can skip push and pull_request triggered workflow runs by including [eas skip], [skip eas], or [no eas] in the commit message.
on.push trigger configuration
The on.push trigger runs when you push a commit to matching branches and/or tags. It supports: branches list (trigger on specified branches, supports globs and ! prefix for negation), tags list (trigger on specified tags, supports globs and ! prefix for negation), and paths list (trigger only when changes are made to files matching specified paths, supports globs). When neither branches nor tags are provided, branches defaults to ['*'] and tags defaults to [], meaning the workflow triggers on pushes to all branches but not tag pushes.