Mobile Builds
Build, archive, and upload an iOS Simulator app or Android APK so Autonomy can run mobile journeys against it.
Autonomy mobile runs need a build of your app. Upload that build once and reuse it across manual runs, pull request runs, and scheduled runs until the next version ships.
What to upload
| Variable | Required | Description |
|---|---|---|
| iOS .app (.zip, .tgz, .tar.gz) | No | Simulator-target .app bundle archived with the app at the archive root. Accepted by the dashboard and artifact API. |
| Android .apk | No | Standard Android package. Accepted by the dashboard and artifact API. |
| Android .aab | No | Android App Bundle. Accepted by the dashboard and artifact API. |
For iOS, Autonomy needs a Simulator build because runs execute on cloud simulators. A signed .ipa built for iphoneos will be rejected by the runner. For Android, both .apk and .aab are accepted; runs install the artifact on a cloud emulator and launch it by package name.
Build for iOS Simulator
For a stock Xcode project, build with xcodebuild:
xcodebuild -workspace ios/MyApp.xcworkspace \
-scheme MyApp \
-configuration Release \
-sdk iphonesimulator \
-destination 'generic/platform=iOS Simulator' \
-derivedDataPath ios/build \
buildThe bundle lands at ios/build/Build/Products/Release-iphonesimulator/MyApp.app. For Expo or React Native projects, run npx expo prebuild --platform ios first, then the same xcodebuild command against the generated workspace.
For dashboard and direct API uploads, archive the bundle before sending it. Keep the .app bundle at the archive root so Autonomy can unpack it without guessing.
cd ios/build/Build/Products/Release-iphonesimulator
zip -r MyApp.app.zip MyApp.appBuild for Android
For a stock Android project, build a debug APK from the project root. Debug APKs install on emulators without signing.
./gradlew assembleDebugThe APK lands at android/app/build/outputs/apk/debug/app-debug.apk. For Expo or React Native projects, run npx expo prebuild --platform android first, then the same Gradle command against the generated project.
For App Bundle builds, use ./gradlew bundleDebug and pick up the .aab from android/app/build/outputs/bundle/debug/. Either format works.
Upload from the dashboard
- Open the project and switch to the Mobile tab.
- Click Browse files and select the
.app.zip/.app.tar.gz(iOS) or.apk/.aab(Android). - Wait for the build to finish processing.
- Open the test and pick the uploaded build under App Upload.
- For Android tests, confirm the package name matches the APK. Autonomy reads it from the manifest but you can override it on the test.
- Run the test manually once to confirm the build boots and the journey reaches the first checkpoint.
Upload with the artifact API
Use the artifact API from CI or an agent runtime when the build is not already stored in a saved Autonomy environment. The upload flow returns a storage id, scans the artifact, then passes that storage id to a run.
For the endpoint schema and response shapes, see Artifacts in the API Reference.
UPLOAD_URL=$(curl -fsS -X POST "$AUTONOMY_API_URL/api/artifacts/upload-url" \
-H "Authorization: Bearer $AUTONOMY_API_KEY" \
-H "Content-Type: application/json" | jq -r '.uploadUrl')
STORAGE_ID=$(curl -fsS -X POST "$UPLOAD_URL" \
-H "Content-Type: application/zip" \
--data-binary "@ios/build/Build/Products/Release-iphonesimulator/MyApp.app.zip" | jq -r '.storageId')
SCAN_BODY=$(jq -n \
--arg storageId "$STORAGE_ID" \
--arg fileName "MyApp.app.zip" \
'{ storageId: $storageId, platform: "ios", fileName: $fileName, contentType: "application/zip" }')
curl -fsS -X POST "$AUTONOMY_API_URL/api/artifacts/scan" \
-H "Authorization: Bearer $AUTONOMY_API_KEY" \
-H "Content-Type: application/json" \
-d "$SCAN_BODY"TRIGGER_BODY=$(jq -n \
--arg testPlanId "$AUTONOMY_TEST_PLAN_ID" \
--arg storageId "$STORAGE_ID" \
--arg bundleId "com.example.MyApp" \
--arg commitSha "$GITHUB_SHA" \
'{
testPlanId: $testPlanId,
platforms: ["ios"],
branch: env.GITHUB_REF_NAME,
targets: {
ios: {
storageId: $storageId,
sourceMode: "upload",
bundleId: $bundleId,
fileName: "MyApp.app.zip"
}
},
deployment: {
provider: "github-actions",
commitSha: $commitSha
}
}')
curl -fsS -X POST "$AUTONOMY_API_URL/api/trigger" \
-H "Authorization: Bearer $AUTONOMY_API_KEY" \
-H "Content-Type: application/json" \
-d "$TRIGGER_BODY"For Android, upload the .apk or .aab the same way and trigger with platforms: ["android"], targets.android.storageId, and targets.android.packageName.
If your CI provider already gives you a short-lived HTTPS artifact URL, you can skip the upload step and trigger with artifactUrl plus sourceMode: "url". Use saved environments for stable staging builds and explicit targets for one-off preview artifacts.
Limitations
- iOS runs on cloud Simulators only. Camera, biometric prompts (Face ID, Touch ID), and any flow that requires a signed device build will not work.
- Android runs on cloud emulators. Hardware-only features (NFC, fingerprint, true camera) are not simulated.
Troubleshooting
The iOS upload is rejected as a device build
Confirm the build was produced with -sdk iphonesimulator and a Simulator destination. A bundle produced for iphoneos is a device build and Autonomy will reject it on upload.
The Android upload is rejected as the wrong format
Autonomy accepts .apk and .aab only. Anything else is rejected at upload time.
The test cannot find the uploaded build
The build was uploaded but never attached to the test. Open the test and pick the uploaded build under App Upload before running it.
CI fills up uploads
Use saved environments for builds that should be reused, and use explicit run targets for one-off CI artifacts. Reserve dashboard uploads for builds a release manager picks for production runs.