•
1 September 2025
•
2 mins
build-and-maestro-test
profileNote: I handled the responsibility of creating our mobile app CI pipeline.
I implemented both EAS‑based and Maestro Cloud pipelines and validated they work
We run on EAS Build because it’s significantly cheaper. As of Aug 24, 2025: EAS Starter Plan starts at $19/month; Maestro Cloud is about $212.50/month
Here is our build-and-maestro-test
configuration (eas.json):
"build-and-maestro-test": {
"withoutCredentials": true,
"config": "build-and-maestro-test.yml",
"android": {
"buildType": "apk",
"image": "latest"
},
"ios": {
"simulator": true,
"image": "latest"
},
"channel": "build-and-maestro-test"
}
Here is the corresponding Github Actions workflow file:
name: EAS Build & Maestro Tests
on:
push:
branches:
- "main"
pull_request:
branches:
- "main"
jobs:
build_and_test:
runs-on: ubuntu-latest
timeout-minutes: 120
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Install Bun
uses: oven-sh/setup-bun@v1
with:
bun-version: latest
- name: Install dependencies
run: bun install
- name: Install EAS CLI
run: npm install -g eas-cli
- name: Run EAS Build with Maestro Tests
run: EXPO_TOKEN=${{ secrets.EXPO_TOKEN }} eas build --platform android --profile build-and-maestro-test --non-interactive
Here is the Github Actions workflow file for this:
name: EAS Build & Maestro Tests
on:
push:
branches:
- "**"
jobs:
build_and_test:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Install Bun
uses: oven-sh/setup-bun@v1
with:
bun-version: latest
- name: Install dependencies
run: bun install
- name: Install EAS CLI
run: npm install -g eas-cli
- name: Fetch Latest EAS Build Artifact
run: |
# Export Expo token for authentication
export EXPO_TOKEN=${{ secrets.EXPO_TOKEN }}
# Get latest build URL
BUILDS_JSON=$(eas build:list --platform android --profile production --status finished --json --non-interactive)
# Validate JSON response
if [[ -z "$BUILDS_JSON" || "$BUILDS_JSON" == "[]" ]]; then
echo "No completed builds found!"
exit 1
fi
# Extract the build URL
BUILD_URL=$(echo "$BUILDS_JSON" | jq -r '.[0].artifacts.buildUrl')
# Ensure a valid URL was extracted
if [[ -z "$BUILD_URL" || "$BUILD_URL" == "null" ]]; then
echo "No valid build URL found!"
exit 1
fi
echo "Downloading APK from $BUILD_URL"
# Download the APK using Expo authentication
curl -L -o app-release.apk $BUILD_URL
echo "APK downloaded to app-release.apk"
ls -la
- name: Install Maestro CLI
run: |
curl -Ls "https://get.maestro.mobile.dev" | bash
echo "$HOME/.maestro/bin" >> $GITHUB_PATH
- name: Run Maestro Cloud Tests on APK
uses: mobile-dev-inc/action-maestro-cloud@v1.9.6
with:
api-key: ${{ secrets.MAESTRO_API_KEY }}
project-id: ${{ secrets.PROJECT_ID }}
app-file: app-release.apk
workspace: maestro
android-api-level: 33
env: |
MAESTRO_TEST_EMAIL=${{ secrets.MAESTRO_TEST_EMAIL }}
MAESTRO_TEST_PASSWORD=${{ secrets.MAESTRO_TEST_PASSWORD }}
These tests can be flaky:
Like it? Share it!