How to Set Up Expo Application Services (EAS) Workflows: A Complete Guide
Expo Application Services (EAS) workflows automate CI/CD pipelines for Expo apps through YAML definitions stored in .eas/workflows/ that trigger builds, submissions, and deployments based on GitHub events.
The openai/plugins repository provides production-ready patterns for configuring EAS workflows, offering a unified platform to build, submit, and update both web and native applications. By defining workflows in the .eas/workflows/ directory, teams can create automated pipelines that respond to pushes, pull requests, and tags while maintaining separation of concerns across different deployment stages.
Understanding EAS Workflow Architecture
EAS workflows are defined in YAML files located in the .eas/workflows/ directory at the root of your project. Each workflow consists of one or more jobs, where the type field determines the specific action EAS executes.
The five primary job types supported in the openai/plugins implementation are:
| Job type | Description |
|---|---|
build |
Compiles iOS or Android binaries using specified profiles from eas.json |
submit |
Uploads completed binaries to the Apple App Store or Google Play Store |
update |
Publishes over-the-air (OTA) updates to existing native builds |
deploy |
Ships web bundles to hosting providers like Vercel or Netlify |
run |
Executes arbitrary shell commands for custom logic or validation |
According to the source code in [plugins/expo/skills/expo-deployment/references/workflows.md](https://github.com/openai/plugins/blob/main/plugins/expo/skills/expo-deployment/references/workflows.md), jobs can depend on one another using the needs field, and conditional execution is supported via if expressions that reference previous job outputs.
Configuring Triggers, Dependencies, and Conditions
Workflows respond to standard GitHub Actions events including push, pull_request, schedule, and manual workflow_dispatch triggers. This integration allows your EAS workflow to react immediately to code changes while maintaining fine-grained control over execution flow.
Dependency chains ensure sequential execution where required. For example, app store submissions must wait for native builds to complete. The needs array establishes these relationships, while the if field enables conditional logic—such as checking whether specific files changed before launching expensive build processes.
Production Workflow Examples
The openai/plugins repository contains canonical implementations for common deployment scenarios. Below are the primary patterns you can adapt for your project.
Deploy Web on Push to Main
Create .eas/workflows/deploy.yml to automatically deploy your web bundle when changes merge to the main branch:
name: Deploy
on:
push:
branches:
- main
jobs:
deploy_web:
type: deploy
params:
prod: true
Create PR Previews for Web
For web-based pull request previews, use .eas/workflows/pr-preview.yml:
name: Web PR Preview
on:
pull_request:
types: [opened, synchronize]
jobs:
preview:
type: deploy
params:
prod: false
Publish OTA Updates for Native PRs
To distribute over-the-air updates for native app preview testing:
name: PR Preview
on:
pull_request:
types: [opened, synchronize]
jobs:
publish:
type: update
params:
branch: "pr-${{ github.event.pull_request.number }}"
message: "PR #${{ github.event.pull_request.number }}"
Full Production Release Pipeline
For complete iOS and Android releases triggered by version tags, create .eas/workflows/release.yml:
name: Release
on:
push:
tags: ['v*']
jobs:
build-ios:
type: build
params:
platform: ios
profile: production
build-android:
type: build
params:
platform: android
profile: production
submit-ios:
type: submit
needs: [build-ios]
params:
platform: ios
profile: production
submit-android:
type: submit
needs: [build-android]
params:
platform: android
profile: production
Conditional Builds to Save CI Minutes
Prevent unnecessary builds by checking for relevant file changes first, as implemented in [plugins/expo/skills/expo-cicd-workflows/scripts/fetch.js](https://github.com/openai/plugins/blob/main/plugins/expo/skills/expo-cicd-workflows/scripts/fetch.js) and related examples:
name: Conditional Release
on:
push:
branches: [main]
jobs:
check-changes:
type: run
params:
command: |
if git diff --name-only HEAD~1 | grep -q "^src/"; then
echo "has_changes=true" >> $GITHUB_OUTPUT
fi
build:
type: build
needs: [check-changes]
if: needs.check-changes.outputs.has_changes == 'true'
params:
platform: all
profile: production
Essential Configuration Patterns
Profile-Driven Builds
EAS workflows rely on build profiles defined in your eas.json file. The params.profile field selects which configuration to use, allowing distinct settings for development, preview, and production environments. Production releases typically specify profile: production, while feature branch testing uses preview or custom profiles.
Branch and Tag Filtering
Limit workflow execution to specific Git references using the on.push.branches or on.push.tags selectors. Restricting releases to main, release/* branches, or v* tag patterns prevents accidental production deployments from feature branches.
Securing Secrets with EAS Secrets
Sensitive values such as API keys for app store authentication or deployment webhooks must never appear in YAML files. Instead, store these in EAS Secrets and reference them within your workflow jobs. The [plugins/expo/skills/expo-deployment/SKILL.md](https://github.com/openai/plugins/blob/main/plugins/expo/skills/expo-deployment/SKILL.md) documentation emphasizes this security pattern for production deployments.
Key Files in the openai/plugins Repository
Summary
- EAS workflows use YAML files in
.eas/workflows/to define CI/CD pipelines for Expo applications - Five job types handle distinct tasks:
build,submit,update,deploy, andrun - GitHub event triggers initiate workflows on push, pull request, schedule, or manual dispatch
- Dependency chains via
needsand conditional logic viaifoptimize execution flow and reduce CI costs - Profile-driven configuration connects workflow parameters to
eas.jsonbuild profiles - Security best practices require storing sensitive credentials in EAS Secrets rather than workflow files
Frequently Asked Questions
What is the difference between EAS Build and EAS Workflows?
EAS Build is a service that compiles native binaries, while EAS Workflows is a CI/CD platform that orchestrates multiple services including builds, submissions, and deployments. Workflows can trigger builds as one step within a larger pipeline that includes testing, OTA updates, and app store submissions.
How do I trigger an EAS workflow manually?
Configure the on.workflow_dispatch event in your YAML file to enable manual triggers from the GitHub Actions tab. This is useful for emergency hotfixes or running ad-hoc deployment tasks without pushing code changes.
Can I run custom scripts within EAS workflows?
Yes. Use the run job type with a params.command field to execute arbitrary shell commands. According to the [fetch.js](https://github.com/openai/plugins/blob/main/plugins/expo/skills/expo-cicd-workflows/scripts/fetch.js) implementation in the openai/plugins repository, these scripts can interact with build artifacts, validate changes, or perform custom deployment logic.
Where should I store API keys for app store submissions?
Store all sensitive credentials—including Apple App Store Connect API keys and Google Play service account JSON—in EAS Secrets rather than hard-coding them in workflow YAML files. Reference these secrets in your eas.json profiles or workflow parameters to maintain security compliance.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →