---
modificationDate: July 19, 2026
title: Environment variables in EAS Workflows
description: Reference for the environment variables available inside EAS Workflows jobs, including the env context and additional worker variables.
---

<AgentInstructions>

## Submitting Feedback

If this page contains errors, outdated information, or gaps that blocked you from completing a task, report it so the docs can be improved:

curl -X POST https://api.expo.dev/v2/feedback/docs-send -H 'Content-Type: application/json' -d '{"url":"/eas/workflows/environment/","feedback":"🤖 Agent feedback for docs: <specific, actionable description> (<model>, <harness>)"}'

Only submit when you have something specific and actionable to report. Replace <model> with the model you are running as and <harness> with the tool you are running in (for example, Claude Code, Cursor, Codex CLI).

## Navigation

When answering a related or follow-up question, fetch the relevant page below as Markdown (.md) instead of guessing; use llms.txt for the full map.

You are here: EAS > EAS Workflows
Pages in this section:
- [Introduction](https://docs.expo.dev/eas/workflows/introduction.md)
- [Get started](https://docs.expo.dev/eas/workflows/get-started.md)
- [Pre-packaged jobs](https://docs.expo.dev/eas/workflows/pre-packaged-jobs.md)
- [Syntax](https://docs.expo.dev/eas/workflows/syntax.md)
- [Environment variables](https://docs.expo.dev/eas/workflows/environment.md) (this page)
- [Automating EAS CLI commands](https://docs.expo.dev/eas/workflows/automating-eas-cli.md)
- [REST API](https://docs.expo.dev/eas/workflows/rest-api.md)
- [Troubleshooting](https://docs.expo.dev/eas/workflows/troubleshooting.md)
- [Limitations](https://docs.expo.dev/eas/workflows/limitations.md)
Full documentation tree: [llms.txt](https://docs.expo.dev/llms.txt)

</AgentInstructions>

This documentation is available as Markdown for AI agents and LLMs. See the [full Markdown index](/llms.txt) or append .md to any documentation URL.

# Environment variables in EAS Workflows

Reference for the environment variables available inside EAS Workflows jobs, including the env context and additional worker variables.

Every workflow job runs on a worker that has a set of environment variables available to it. You can read these variables in two ways:

-   With the [`${{ env.NAME }}`](/eas/workflows/syntax.md#env) interpolation syntax, anywhere a job interpolates values (for example, in `params`, `if`, `env`, and `run`).
-   As standard shell variables (`$NAME`) or through `process.env.NAME` from inside a [`run`](/eas/workflows/syntax.md#jobsjob_idstepssteprun) step.

```yaml
name: Print environment

jobs:
  print:
    steps:
      # Interpolated before the command runs.
      - run: echo "Project: ${{ env.EAS_BUILD_PROJECT_ID }}"
      # Read from the shell environment at runtime.
      - run: echo "Project: $EAS_BUILD_PROJECT_ID"
```

## Precedence

The variables available in a job are merged from three sources. When the same name is defined in more than one source, the one higher in this list wins:

| Source | Description |
| --- | --- |
| [Job `env`](/eas/workflows/syntax.md#jobsjob_idenv) | Variables you set on the job with the `env` key. These are plain text and defined directly in your workflow file. |
| [**eas.json** build profile `env`](/build/eas-json.md#environment-variables) | For [`build`](/eas/workflows/pre-packaged-jobs.md#build) jobs, the `env` from the profile selected by `params.profile` in **eas.json**. |
| [EAS environment variables](/eas/environment-variables.md) | Variable names and values stored on EAS for the job's [environment](/eas/workflows/environment.md#the-job-environment) (`production`, `preview`, or `development`). |

On top of these, the worker sets a number of [additional variables](/eas/workflows/environment.md#additional-environment-variables) such as `EAS_BUILD_ID` and `CI`. Avoid naming your own variables with the `EAS_` prefix so these don't shadow them.

## The job environment

Which EAS environment variables a job can read depends on its [environment](/eas/workflows/syntax.md#jobsjob_idenvironment): `production` (the default), `preview`, or `development`. Only variables assigned to that environment are exposed to the job.

Each job resolves its environment differently:

-   [`build`](/eas/workflows/pre-packaged-jobs.md#build) jobs infer it from the build profile's `environment` in **eas.json**.
-   [`submit`](/eas/workflows/pre-packaged-jobs.md#submit) jobs inherit it from the submitted build.
-   [`maestro`](/eas/workflows/pre-packaged-jobs.md#maestro) and [`maestro-cloud`](/eas/workflows/pre-packaged-jobs.md#maestro-cloud) jobs default to `preview`.
-   Other jobs default to `production`.

Set [`jobs.<job_id>.environment`](/eas/workflows/syntax.md#jobsjob_idenvironment) explicitly to override the default and keep a job in sync with the build profile it pairs with. For more details on selecting an environment for a job, see [Using environment variables in EAS Workflows](/eas/environment-variables/usage.md#using-environment-variables-in-eas-workflows).

## The `${{ env }}` context

The [`${{ env }}` context](/eas/workflows/syntax.md#env) is a record of environment variables keyed by name. It is available within a job's context, not at the top level of the workflow. For example, you can use it in a job's `params`, `if`, `env`, `outputs`, and `run`, but not in the top-level `on` triggers.

```yaml
jobs:
  notify:
    type: slack
    params:
      # Reads the SLACK_WEBHOOK_URL EAS environment variable.
      webhook_url: ${{ env.SLACK_WEBHOOK_URL }}
      message: 'Deploy finished'
```

Interpolation happens in two places, which changes what `${{ env.NAME }}` can resolve:

-   **Job configuration** (`params`, `if`, `outputs`, and the value of `env` itself) is interpolated before the job is dispatched to a worker. At this point, `env` contains your [EAS environment variables](/eas/environment-variables.md) for the resolved [environment](/eas/workflows/environment.md#the-job-environment). The additional worker variables and the job's own `env` values are not yet available here.
-   **`run` commands** are interpolated on the worker, where `env` reflects the full runtime environment: EAS environment variables, the job's `env`, and the [additional variables](/eas/workflows/environment.md#additional-environment-variables).

Because of this, read variables like `EAS_BUILD_ID` inside a `run` step rather than in a job's `params`. Inside a `run` step, `${{ env.EAS_BUILD_ID }}` and `$EAS_BUILD_ID` are equivalent.

> Values interpolated from EAS environment variables of type secret or sensitive are redacted in workflow logs.

## Context variables

Environment variables are not the only thing a job can interpolate. The same `${{ ... }}` syntax exposes several context objects that describe the workflow run. The `env` context covered above is one of them. The others are documented below. For the interpolation syntax and the available [context functions](/eas/workflows/syntax.md#context-functions) such as `toJSON`, `fromJSON`, and `success()`, see [Syntax](/eas/workflows/syntax.md#interpolation).

> To see the full contents of any context at runtime, print it with `toJSON`. For example, `run: echo '${{ toJSON(github) }}'`.

### `github`

Fields from the GitHub event that triggered the workflow. When you start a run with `eas workflow:run`, `event_name` is `workflow_dispatch` and the other fields are empty.

```js
github {
  triggering_actor,   // User who triggered the run, e.g. jonexpo
  event_name,         // 'pull_request', 'push', 'schedule', or 'workflow_dispatch'
  sha,                // Commit SHA
  ref,                // Full ref, e.g. refs/heads/main
  ref_name,           // Short ref, e.g. main
  ref_type,           // 'branch', 'tag', or 'other'
  commit_message,     // Only for push and schedule events
  label,              // Label name, for pull_request_labeled events
  repository,         // e.g. expo/expo
  repository_owner,   // e.g. expo
  event {             // Full GitHub webhook payload
    action,
    head_commit { message, id },   // Only for push and schedule events
    pull_request {
      number,
      title,
      body,
      state,          // 'open' or 'closed'
      draft,
      merged,
      html_url,
      user { login },
      labels,         // Array of { name }
      head { ref, sha },   // Source branch
      base { ref, sha },   // Target branch
      created_at,
      updated_at,
      merged_at,
      // ... and other fields from the GitHub Pull Request webhook payload
    },
    inputs,           // workflow_dispatch inputs
    schedule,         // Cron expression, for scheduled runs
    number,
  }
}
```

The `event` object contains the full [GitHub webhook payload](https://docs.github.com/en/webhooks/webhook-events-and-payloads). For a detailed field reference and examples, see [`github`](/eas/workflows/syntax.md#github) in the Syntax guide.

### `inputs`

A record of the inputs provided when you start the workflow manually with [`workflow_dispatch`](/eas/workflows/syntax.md#onworkflow_dispatchinputs). Empty when the workflow is triggered another way.

```yaml
jobs:
  greet:
    steps:
      - run: echo "Hello, ${{ inputs.name }}!"
```

### `needs`

A record of the upstream jobs listed in the current job's [`needs`](/eas/workflows/syntax.md#jobsjob_idneeds). Each entry provides the job's `status` (`success`, `failure`, or `skipped`) and its `outputs`.

```yaml
jobs:
  notify:
    needs: [build]
    steps:
      - run: echo "Build status: ${{ needs.build.status }}"
```

### `after`

A record of the upstream jobs listed in the current job's [`after`](/eas/workflows/syntax.md#jobsjob_idafter), whether or not they succeeded. Each entry provides the same `status` and `outputs` shape as [`needs`](/eas/workflows/environment.md#needs).

```yaml
jobs:
  notify:
    after: [build]
    steps:
      - run: echo "Build status: ${{ after.build.status }}"
```

### `steps`

A record of the steps in the current job, keyed by step `id`. Each entry exposes the `outputs` set with the [`set-output`](/eas/workflows/syntax.md#set-output) function. This context is only available within a job's steps.

```yaml
jobs:
  my_job:
    steps:
      - id: step_1
        run: set-output my_greeting "hello"
      - run: echo "${{ steps.step_1.outputs.my_greeting }}"
```

### `metadata`

Metadata about the build associated with the job. It is populated for [`build`](/eas/workflows/pre-packaged-jobs.md#build) jobs and is an empty object (`{}`) for job types without build metadata, such as custom jobs.

```js
metadata {
  buildProfile,     // Build profile from eas.json, e.g. production
  appVersion,       // App version, e.g. 1.0.0
  appBuildVersion,  // Build number (iOS) or version code (Android)
  sdkVersion,       // Expo SDK version, e.g. 54.0.0
  runtimeVersion,   // Runtime version for EAS Update
  gitCommitHash,    // Git commit the build ran against
  distribution,     // 'store' or 'internal'
}
```

### `workflow`

Information about the current workflow run.

```js
workflow {
  id,        // ID of the workflow run
  name,      // Name of the workflow
  filename,  // Name of the workflow file, e.g. deploy.yml
  url,       // URL of the run on the EAS dashboard
}
```

```yaml
jobs:
  notify:
    type: slack
    params:
      message: |
        Workflow run completed: ${{ workflow.name }}
        View details: ${{ workflow.url }}
```

### `app_store_connect`

Information about the App Store Connect entities associated with the run. This context is present only for workflows triggered by an [App Store Connect event](/eas/workflows/syntax.md#onapp_store_connect).

```js
app_store_connect {
  app { id },
  build_upload {
    id,
    state,             // 'awaiting_upload', 'processing', 'failed', or 'complete'
    cf_bundle_version,
    build { id },
  },
  app_version { id, state },
  external_beta { id, state },
  beta_feedback {
    id,
    type,              // 'crash' or 'screenshot'
    url,
  },
}
```

```yaml
on:
  app_store_connect:
    build_upload:
      states:
        - complete

jobs:
  notify:
    type: slack
    params:
      webhook_url: ${{ env.SLACK_WEBHOOK_URL }}
      message: |
        Upload complete for app: ${{ app_store_connect.app.id }}
        Upload state: ${{ app_store_connect.build_upload.state }}
```

For the event domains that populate each field and full examples, see [`app_store_connect`](/eas/workflows/syntax.md#app_store_connect) in the Syntax guide.

## Additional environment variables

In addition to the variables you set, the worker provides a number of variables on every job that runs on a virtual machine (VM), such as `EAS_BUILD_ID`, `EAS_BUILD_PROJECT_ID`, and `CI`. They are read at runtime, so reference them from within a `run` step. For the full list, see [Built-in environment variables](/eas/environment-variables/usage.md#built-in-environment-variables).

Workers also expose standard toolchain variables such as `HOME`, `PATH`, `LANG`, `ANDROID_HOME`, `ANDROID_SDK_ROOT`, and `JAVA_HOME`. Their exact values depend on the worker [image](/eas/workflows/syntax.md#jobsjob_idimage) and are subject to change.

## Setting environment variables in a job

To define your own variables, use the [`env` key](/eas/workflows/syntax.md#jobsjob_idenv) on a job. Values can reference other context properties.

```yaml
jobs:
  my_job:
    env:
      APP_VARIANT: staging
      COMMIT: ${{ github.sha }}
    steps:
      - run: echo "Building $APP_VARIANT at $COMMIT"
```

### Share a value with later steps in the same job

Use the [`set-env`](/eas/workflows/syntax.md#set-env) command to compute a value in one step and read it in later steps of the same job. The command is available on the worker's `PATH`. It's the environment-variable counterpart to [`set-output`](/eas/workflows/syntax.md#set-output): `set-output` exposes a named job output, while `set-env` exposes an environment variable to the job's subsequent steps.

```yaml
jobs:
  my_job:
    steps:
      - run: set-env GENERATED_TAG "v$(date +%Y%m%d)"
      # `set-env` only affects later steps, so the value is available here.
      - run: echo "Tag is $GENERATED_TAG"
```

[EAS environment variables](/eas/environment-variables.md) — Create and manage environment variables and secrets for your project's environments.

[Syntax for EAS Workflows](/eas/workflows/syntax.md#interpolation) — Reference for the full set of interpolation contexts and functions available in workflows.
