Maestro Deck
Guides

GitHub Action

Run your Maestro flows on MaestroDeck Cloud from CI with a single GitHub Actions step. Setup, inputs, outputs and full workflow examples.

The official BlueShork/maestro-action lets you run your Maestro flows on MaestroDeck Cloud straight from GitHub Actions. One step uploads your app and flows, runs them on a real simulator or emulator, waits for the result, and fails the build if the tests fail. No runner to provision, no simulator to boot in CI.

- uses: BlueShork/maestro-action@v1
  with:
    api_key: ${{ secrets.MAESTRO_API_KEY }}
    platform: android
    app: build/app-release.apk
    flow: .maestro/

How it works

The action uploads your build and flow files to MaestroDeck Cloud, runs them on the cloud device pool, polls for the result, and exits 0 (passed) or 1 (failed or error) so your pipeline goes green or red accordingly. Android jobs dispatch instantly; iOS jobs run on the macOS worker pool. It's the same pipeline as the web dashboard, triggered from CI.

Because the run happens on MaestroDeck Cloud, your CI runner stays a plain ubuntu-latest box. You don't need macOS minutes or an Android emulator in the workflow.

Setup

1. Generate an API key

Open your MaestroDeck dashboard profile page, find the API keys section, and click Generate key. Copy it right away. it's shown only once and looks like mk_live_....

2. Add it as a repository secret

In your GitHub repo, go to Settings → Secrets and variables → Actions → New repository secret. Name it MAESTRO_API_KEY and paste the key. Never hard-code the key in your workflow file.

3. Add the step to a workflow

Create (or edit) a workflow under .github/workflows/, build your app artifact, then add the maestro-action step pointing at that artifact and your flows. See the examples below.

Inputs

InputRequiredDefaultDescription
api_keyyesYour MaestroDeck API key (mk_live_...). Always pass it via a secret.
platformyesios or android.
appyesPath to the .apk (Android) or .app.zip (iOS).
flowyesPath or glob to your Maestro .yaml flow files, or a directory of them.
emailnoaccount emailSend the report to a specific address instead of your account email.
timeoutno1800Max seconds to wait for the result before giving up. Does not change the run's own server-side timeout.

Outputs

OutputDescription
job_idThe created job id.
statusFinal status: passed, failed, or error.
report_urlLink to the full report in the dashboard.

Examples

Android

Build your APK in an earlier step, then hand its path to the action:

name: E2E
on: [push]
jobs:
  e2e:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      # ... build your APK into build/app-release.apk ...
      - uses: BlueShork/maestro-action@v1
        with:
          api_key: ${{ secrets.MAESTRO_API_KEY }}
          platform: android
          app: build/app-release.apk
          flow: .maestro/

iOS

Point app at a zipped .app bundle and platform at ios:

- uses: BlueShork/maestro-action@v1
  with:
    api_key: ${{ secrets.MAESTRO_API_KEY }}
    platform: ios
    app: build/MyApp.app.zip
    flow: .maestro/login.yaml

Using the outputs

Read report_url, status or job_id in later steps. Use if: always() so the link is printed even when the run fails:

- uses: BlueShork/maestro-action@v1
  id: maestro
  with:
    api_key: ${{ secrets.MAESTRO_API_KEY }}
    platform: android
    app: build/app-release.apk
    flow: .maestro/
- if: always()
  run: echo "Report: ${{ steps.maestro.outputs.report_url }}"

Notes

  • flow accepts a single file (.maestro/login.yaml), a glob (.maestro/*.yaml), or a directory (.maestro/, which picks up every .yaml / .yml inside).
  • Each step invocation consumes one run from your MaestroDeck quota.
  • The action needs curl and jq, both preinstalled on GitHub-hosted runners.
  • Pin to a major tag (@v1) for stable behaviour, or pin a full SHA if you want byte-for-byte reproducibility.
Share:LinkedInX / Twitter

On this page