Expo EAS
Construye artefactos para Simulador de iOS y APK de Android en Expo EAS, transfiérelos a Autonomy y ejecuta recorridos móviles en cada cambio.
Expo EAS es dueño del pipeline de build para los proyectos de Expo. Usa esta integración cuando quieras que EAS produzca el .app para Simulador de iOS o el .apk de Android y que Autonomy ejecute recorridos móviles contra él en push, pull request o disparo manual.
Requisitos previos
Antes de activar las ejecuciones de EAS
- Un proyecto de Expo con EAS ya configurado para iOS.
- Un proyecto de Autonomy vinculado al repositorio.
- Al menos un test móvil que pasa contra una subida manual.
- Un id de plan de test de Autonomy para cada plataforma que el flujo de EAS deba disparar.
Secretos requeridos
Guárdalos como variables de entorno de EAS o secretos sensibles. No los hagas commit, y no los expongas mediante una variable EXPO_PUBLIC_* — Expo incrusta esas en el bundle del cliente.
| Variable | Required | Description |
|---|---|---|
| AUTONOMY_API_KEY | Yes | Clave de API de Autonomy con permiso para subir builds y disparar ejecuciones. |
| AUTONOMY_API_URL | Yes | Origen de la API de Autonomy, por ejemplo https://api.autonomyqa.com o la URL de tu sitio Convex. |
| AUTONOMY_IOS_TEST_PLAN_ID | No | Plan de test a ejecutar contra la build de iOS subida. Requerido si el flujo ejecuta iOS. |
| AUTONOMY_ANDROID_TEST_PLAN_ID | No | Plan de test a ejecutar contra la build de Android subida. Requerido si el flujo ejecuta Android. |
| AUTONOMY_IOS_BUNDLE_ID | No | Bundle identifier de iOS para el target de la app de Simulador. |
| AUTONOMY_ANDROID_PACKAGE_NAME | No | Nombre de paquete Android para el target APK o AAB. |
Puedes encontrarlos en el panel de Autonomy:
- Clave de API: Perfil → Claves de API
- URL de API: configuración del proyecto o del despliegue
- IDs de planes de test: pestaña Tests → menú del plan → Copiar ID. Usa un plan separado por plataforma para que los fallos apunten a la superficie correcta.
Perfiles de build
Añade o reutiliza perfiles de build en eas.json. Para iOS, Autonomy necesita una build .app de Simulador, no un .ipa firmado. El perfil debe establecer ios.simulator en true. Para Android, usa un perfil de desarrollo o de distribución interna que emita un APK.
1{2 "build": {3 "autonomy-ios-simulator": {4 "distribution": "internal",5 "ios": {6 "simulator": true7 }8 },9 "autonomy-android-apk": {10 "distribution": "internal",11 "android": {12 "buildType": "apk"13 }14 }15 }16}Flujo
Añade .eas/workflows/autonomy-mobile-tests.yml. El flujo construye cada plataforma que te interesa, descarga el artefacto, lo sube mediante la API de artefactos, lo escanea y dispara el plan de test de Autonomy correspondiente.
El ejemplo de abajo ejecuta ambas plataformas. Elimina el job que no necesites si solo publicas una plataforma.
name: Autonomy Mobile Tests
on:
push:
branches: [main]
pull_request:
branches: [main]
workflow_dispatch:
jobs:
ios:
name: Build and test iOS with Autonomy
type: build
params:
platform: ios
profile: autonomy-ios-simulator
steps:
- eas/checkout
- eas/install_node_modules
- eas/prebuild
- eas/build
- eas/download_build:
id: download
path: ./build
- name: Upload to Autonomy and trigger plan
env:
AUTONOMY_API_KEY: ${{ secrets.AUTONOMY_API_KEY }}
AUTONOMY_API_URL: ${{ secrets.AUTONOMY_API_URL }}
AUTONOMY_TEST_PLAN_ID: ${{ secrets.AUTONOMY_IOS_TEST_PLAN_ID }}
AUTONOMY_IOS_BUNDLE_ID: ${{ secrets.AUTONOMY_IOS_BUNDLE_ID }}
run: |
set -euo pipefail
COMMIT_SHA="${EAS_BUILD_GIT_COMMIT_HASH:-}"
APP_PATH=$(find ./build -name "*.app" -type d | head -n 1)
test -n "$APP_PATH"
APP_DIR=$(dirname "$APP_PATH")
APP_NAME=$(basename "$APP_PATH")
(cd "$APP_DIR" && zip -qr app.zip "$APP_NAME")
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 "@$APP_DIR/app.zip" | jq -r '.storageId')
curl -fsS -X POST "$AUTONOMY_API_URL/api/artifacts/scan" \
-H "Authorization: Bearer $AUTONOMY_API_KEY" \
-H "Content-Type: application/json" \
-d "$(jq -n --arg storageId "$STORAGE_ID" '{ storageId: $storageId, platform: "ios", fileName: "app.zip", contentType: "application/zip" }')"
curl -fsS -X POST "$AUTONOMY_API_URL/api/trigger" \
-H "Authorization: Bearer $AUTONOMY_API_KEY" \
-H "Content-Type: application/json" \
-d "$(jq -n \
--arg testPlanId "$AUTONOMY_TEST_PLAN_ID" \
--arg storageId "$STORAGE_ID" \
--arg bundleId "$AUTONOMY_IOS_BUNDLE_ID" \
--arg commitSha "$COMMIT_SHA" \
'{ testPlanId: $testPlanId, platforms: ["ios"], targets: { ios: { storageId: $storageId, sourceMode: "upload", bundleId: $bundleId, fileName: "app.zip" } }, deployment: { provider: "expo-eas", commitSha: $commitSha } }')"
android:
name: Build and test Android with Autonomy
type: build
params:
platform: android
profile: autonomy-android-apk
steps:
- eas/checkout
- eas/install_node_modules
- eas/prebuild
- eas/build
- eas/download_build:
id: download
path: ./build
- name: Upload to Autonomy and trigger plan
env:
AUTONOMY_API_KEY: ${{ secrets.AUTONOMY_API_KEY }}
AUTONOMY_API_URL: ${{ secrets.AUTONOMY_API_URL }}
AUTONOMY_TEST_PLAN_ID: ${{ secrets.AUTONOMY_ANDROID_TEST_PLAN_ID }}
AUTONOMY_ANDROID_PACKAGE_NAME: ${{ secrets.AUTONOMY_ANDROID_PACKAGE_NAME }}
run: |
set -euo pipefail
COMMIT_SHA="${EAS_BUILD_GIT_COMMIT_HASH:-}"
APK_PATH=$(find ./build ( -name "*.apk" -o -name "*.aab" ) | head -n 1)
test -n "$APK_PATH"
FILE_NAME=$(basename "$APK_PATH")
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/octet-stream" \
--data-binary "@$APK_PATH" | jq -r '.storageId')
curl -fsS -X POST "$AUTONOMY_API_URL/api/artifacts/scan" \
-H "Authorization: Bearer $AUTONOMY_API_KEY" \
-H "Content-Type: application/json" \
-d "$(jq -n --arg storageId "$STORAGE_ID" --arg fileName "$FILE_NAME" '{ storageId: $storageId, platform: "android", fileName: $fileName, contentType: "application/octet-stream" }')"
curl -fsS -X POST "$AUTONOMY_API_URL/api/trigger" \
-H "Authorization: Bearer $AUTONOMY_API_KEY" \
-H "Content-Type: application/json" \
-d "$(jq -n \
--arg testPlanId "$AUTONOMY_TEST_PLAN_ID" \
--arg storageId "$STORAGE_ID" \
--arg packageName "$AUTONOMY_ANDROID_PACKAGE_NAME" \
--arg fileName "$FILE_NAME" \
--arg commitSha "$COMMIT_SHA" \
'{ testPlanId: $testPlanId, platforms: ["android"], targets: { android: { storageId: $storageId, sourceMode: "upload", packageName: $packageName, fileName: $fileName } }, deployment: { provider: "expo-eas", commitSha: $commitSha } }')"Comentarios y checks de GitHub
Pasa el SHA del commit siempre que el contexto de EAS o GitHub proporcione uno, para que Autonomy pueda publicar un check run en el commit. Pasa el número de PR solo cuando el flujo se ejecuta para una pull request. El flujo de arriba protege ambos para que siga siendo válido en push, PR y disparo manual.
Solución de problemas
Autonomy rechaza la build de iOS como build de dispositivo
El perfil de EAS está produciendo un .ipa firmado en lugar de un .app de Simulador. Confirma que ios.simulator es true en el perfil que ejecuta el flujo.
EAS emite un AAB en lugar de un APK
Para el camino de instalación más simple, el perfil de Android debe establecer android.buildType en apk. Autonomy también acepta .aab, pero el APK es más rápido de instalar en el emulador y evita sorpresas de firma. Si debes publicar AAB, asegúrate de que el paso de subida seleccione el archivo .aab.
Autonomy no puede publicar un comentario de PR
La app de GitHub de Autonomy debe estar instalada en el repositorio y el flujo debe pasar el SHA del commit. Sin eso, Autonomy no tiene un anclaje para el comentario.
Las subidas se acumulan en el panel
Usa targets explícitos para artefactos temporales de EAS y entornos guardados para builds que deban reutilizarse. Reserva las subidas del panel para la build que un responsable de versión elige para las ejecuciones de producción.