GitHub Actions
GitHub Actions is one way to run mobile tests automatically from CI. For Expo apps, we recommend using Expo EAS instead.
You only need to provide an iOS Simulator build or Android APK and your TesterArmy credentials. TesterArmy handles the cloud simulator/emulator setup, app installation, test execution, and run orchestration for you, so you do not need to manage devices in your CI pipeline.
For Expo EAS workflows, see Expo EAS.
Before you set it up, make sure you have already:
- built and uploaded a mobile app artifact,
- created at least one mobile test in TesterArmy,
- run that test manually once,
- added the test to a group.
If you want a working reference, see the mobile GitHub Action and the mobile example app.
What you need
Add these GitHub secrets to your repository:
You can copy the group ID from the test group menu in the dashboard.
Recommended workflow
The most reliable setup is:
- Build the app artifact in a dedicated job.
- Upload the
.appbundle or.apkas a GitHub artifact. - Download that artifact on Linux.
- Run
tester-army/mobile-github-actionwith the matchingplatformto upload the app, run the group, wait for results, and clean up.
iOS
Android
No manual upload step in CI
The GitHub Action accepts either a .app directory, an archived iOS app file,
or an Android .apk. If you pass a .app directory, the action zips and
uploads it for you.
What the action does
By default (mode: all) tester-army/mobile-github-action handles the full CI flow for you in a single job:
- Uploads the app to TesterArmy.
- Provisions the cloud simulator or emulator environment and installs the app for the run.
- Starts your mobile test group and orchestrates the run lifecycle.
- Polls until the runs finish.
- Deletes the uploaded app after the run if cleanup is enabled.
Results are written to the GitHub step summary so you can quickly see pass/fail status, duration, issues, and screenshots.
Action modes
The mode input selects what a single invocation does, so you can keep the simple one-job setup or split the work across jobs:
Run defined tests and the dynamic PR agent in parallel
The dynamic PR agent explores what a pull request changes instead of running a fixed group. To run it alongside your defined tests, split the flow into separate jobs: upload the app once, then run the test and dynamic_agent jobs in parallel against the uploaded app_id. Composite actions cannot create jobs, so the split lives in your workflow.
This example covers one platform. To test both iOS and Android, duplicate the upload, defined_tests, and dynamic_agent jobs for the second platform, point the upload job at the Android artifact, and set platform: android in its test and dynamic agent jobs.
The upload job sets remove_after so TesterArmy removes the shared app on its own once both jobs are done.
The dynamic_agent job only runs on pull requests, so gate it with if: ${{ github.event_name == 'pull_request' }}. To add an on/off switch, you can also check a repository variable such as vars.TESTERARMY_DYNAMIC_AGENT_ENABLED == 'true'.
Direct CLI usage
For CI providers such as Expo EAS, Fastlane, Buildkite, or GitLab CI, upload the
app with testerarmy upload-app, then use the returned app ID in the
provider-agnostic CLI flow:
Use --platform android for Android app runs. ci calls
POST /api/v1/groups/{groupId}/runs, waits for every returned run to finish,
and deletes only the explicit --app-id when cleanup is enabled and the run did
not time out.
Dynamic PR agent
The dynamic PR agent explores what a pull request changes against a mobile build instead of running a predefined test group. In the GitHub Action, run it with mode: dynamic_agent (see Run defined tests and the dynamic PR agent in parallel). On other CI providers, call the CLI directly with testerarmy pr run-dynamic:
Use --platform ios with an iOS Simulator .app build or --platform android with an Android .apk. You can use --app-id, --bundle-id, or --artifact-url with --artifact-filename, and pass optional PR context with --pr-description, --base-branch, and --head-branch. The command waits for the run to finish and uses the same result output as group CI runs.
If your project has a supported GitHub connection, TesterArmy looks at what a pull request actually changes before running. If nothing in the change is relevant to the selected platform, TesterArmy can skip the run instead of spinning up a simulator or emulator. A skipped run is neutral — it’s reported as cancelled with a short reason explaining why, not as a failed test — so it never blocks your PR. When a change can’t be clearly assessed, TesterArmy runs the tests rather than skipping.
If you do not want to use the CLI, call the pull request run API directly with platform: "ios" or "android" and a mobile app selector:
The endpoint does not require changed files; if a supported GitHub connection exists, TesterArmy enriches the plan server-side and may skip execution for irrelevant changes as described above.
Important options
Outputs
The action exposes these outputs:
app_id— the uploaded or supplied TesterArmy app IDoverall_status—passed,failed, ortimed_outdynamic_agent_status—passed,failed,timed_out, orskipped
You can use overall_status or dynamic_agent_status in later workflow steps if you want custom reporting or notifications.
Troubleshooting
The app upload fails immediately
Make sure you are passing an iOS Simulator .app / .app.zip or an Android .apk. An .ipa, .aab, or .xapk will not work.
The action cannot find your build
Double-check the app path inside the build job. The most common iOS output path is:
For Android release .apk files, the output is usually under:
The workflow starts but no tests run
Make sure your TESTERARMY_GROUP_ID points to a group that already contains mobile tests.
