Docs Autonomy
Intégrations

Bitrise

Déclenchez Autonomy depuis Bitrise et conditionnez le workflow au résultat pour le web, iOS Simulator ou Android.

Utilisez un Step Script de Bitrise pour téléverser un build mobile ou tester une prévisualisation web déployée, puis maintenez le workflow ouvert jusqu’au verdict d’Autonomy.

Placement du workflow

Ajoutez le Step Autonomy après les étapes existantes de build et de déploiement. Pour le web, exposez l’URL publique finale sous PREVIEW_URL depuis l’étape de déploiement avec envman add --key PREVIEW_URL --value "$PREVIEW_URL" ; les étapes suivantes pourront la lire. Pour le mobile, gardez le build et le téléversement dans le même workflow afin de conserver l’artefact dans le répertoire de travail.

Les configurations complètes ci-dessous sont des alternatives pour bitrise.yml. Copiez celle de votre plateforme ou intégrez ses Steps à votre workflow existant. Configurez Bitrise pour lire bitrise.yml depuis le dépôt et ajoutez .ci/autonomy.sh au dépôt. Le workflow web peut également s’exécuter localement dans un dépôt déjà cloné.

Secrets requis

Avant la première exécution

  • Créez une clé API d’organisation Autonomy commençant par aut_ dans Settings → API Keys, dans l’organisation contenant votre plan.
  • Créez un plan de test dans Test Plans contenant au moins un cas de test exécutable pour la plateforme choisie, puis copiez son ID.
  • Utilisez des cas de test sans référence aux variables d’environnement d’exécution pour cette recette à cibles explicites.
  • Disposez d’un runner Autonomy pour la plateforme et d’une URL de prévisualisation accessible depuis ce runner.

Dans Workflows → Secrets, ajoutez AUTONOMY_API_KEY. Laissez Expose for pull requests et Replace variables in inputs désactivés. Les Secrets deviennent automatiquement des variables d’environnement du shell ; ne placez pas la clé dans bitrise.yml.

Dans Workflows → Env Vars, définissez ces valeurs pour le workflow choisi :

VariableValeur
AUTONOMY_API_URLL’URL HTTP de base de votre déploiement, par exemple https://your-deployment.convex.site, sans /api. N’utilisez pas .convex.cloud.
AUTONOMY_TEST_PLAN_IDL’ID copié depuis Test Plans, contenant les cas à exécuter, et non l’ID d’un cas de test individuel. Utilisez un plan distinct par plateforme.
PREVIEW_URLWeb uniquement : l’URL finale déployée, sans page de connexion ni protection de prévisualisation. L’étape de déploiement peut aussi la fournir.
APP_IDENTIFIERMobile uniquement : l’identifiant de bundle iOS ou d’application Android correspondant à l’artefact.
AUTONOMY_WAIT_SECONDSFacultatif : délai d’attente maximal en secondes, 1200 par défaut.

URL de prévisualisation web

Créez un répertoire .ci dans le dépôt et enregistrez ce script entier dans .ci/autonomy.sh. Il nécessite Bash, curl 7.76 ou plus récent, et jq ; les stacks hébergées sélectionnées les fournissent. Installez ces outils pour une exécution locale avec la CLI. Conservez ce fichier à l’identique pour chaque plateforme.

.ci/autonomy.sh
#!/usr/bin/env bash
set -euo pipefail
set +x
: "${AUTONOMY_API_URL:?Set the API base URL, without /api}"
: "${AUTONOMY_API_KEY:?Set an aut_ organization API key}"
: "${AUTONOMY_TEST_PLAN_ID:?Set the Test Plans ID for this platform}"
: "${AUTONOMY_REQUEST_ID:?Set a unique CI job/attempt ID}"
platform="${1:-web}"
api="${AUTONOMY_API_URL%/}"
work=$(mktemp -d)
trap 'rm -rf "$work"' EXIT

post() {
  curl --fail-with-body --silent --show-error \
    --connect-timeout 15 --max-time 90 \
    -X POST "$api$1" \
    -H "Authorization: Bearer $AUTONOMY_API_KEY" \
    -H 'Content-Type: application/json' --data-binary "$2"
}

case "$platform" in
  web)
    : "${PREVIEW_URL:?Set the reachable preview URL after deployment}"
    targets=$(jq -n --arg url "$PREVIEW_URL" '{web:{baseUrl:$url}}')
    ;;
  ios|android)
    : "${ARTIFACT_PATH:?Set the path to the app archive or APK}"
    : "${APP_IDENTIFIER:?Set the bundle ID or Android package name}"
    test -s "$ARTIFACT_PATH"
    file=$(basename "$ARTIFACT_PATH")
    bytes=$(wc -c < "$ARTIFACT_PATH" | tr -d '[:space:]')
    content_type=application/zip
    if [ "$platform" = android ]; then
      content_type=application/vnd.android.package-archive
    fi
    upload=$(post /api/artifacts/upload-url "$(jq -n \
      --arg platform "$platform" --arg fileName "$file" \
      --arg contentType "$content_type" --argjson declaredBytes "$bytes" \
      '{platform:$platform,fileName:$fileName,contentType:$contentType,declaredBytes:$declaredBytes}')")
    url=$(jq -er '.uploadUrl | strings | select(length > 0)' <<< "$upload")
    storage=$(jq -er '.storageId | strings | select(length > 0)' <<< "$upload")
    intent=$(jq -er '.intentId | strings | select(length > 0)' <<< "$upload")
    jq -e '.method == "PUT"' <<< "$upload" > /dev/null
    curl --fail-with-body --silent --show-error \
      --connect-timeout 15 --max-time 600 -X PUT "$url" \
      -H "Content-Type: $content_type" --data-binary "@$ARTIFACT_PATH"
    scan=$(post /api/artifacts/scan "$(jq -n \
      --arg storageId "$storage" --arg intentId "$intent" \
      '{storageId:$storageId,intentId:$intentId}')")
    if ! jq -e '.status == "clean"' <<< "$scan" > /dev/null; then
      echo 'Artifact scan did not pass; refusing to trigger.' >&2
      exit 1
    fi
    targets=$(jq -n --arg platform "$platform" --arg storageId "$storage" \
      --arg fileName "$file" --arg identifier "$APP_IDENTIFIER" \
      '{($platform):({storageId:$storageId,sourceMode:"upload",fileName:$fileName} +
        (if $platform == "ios" then {bundleId:$identifier} else {packageName:$identifier} end))}')
    ;;
  *) echo 'Usage: bash .ci/autonomy.sh web|ios|android' >&2; exit 2 ;;
esac

body=$(jq -n --arg testPlanId "$AUTONOMY_TEST_PLAN_ID" \
  --arg platform "$platform" --argjson targets "$targets" \
  --arg branch "${AUTONOMY_BRANCH:-manual}" \
  --arg commitSha "${AUTONOMY_COMMIT_SHA:-}" \
  --arg key "$AUTONOMY_REQUEST_ID:$platform" \
  '{testPlanId:$testPlanId,platforms:[$platform],targets:$targets,
    branch:$branch,deployment:{branch:$branch,commitSha:$commitSha},idempotencyKey:$key}')
post /api/v1/run.trigger "$body" > "$work/trigger.json"
jq -e '.runIds | type == "array" and length > 0' "$work/trigger.json" > /dev/null
jq -er '.runIds[] | strings | select(length > 0)' "$work/trigger.json" > "$work/run-ids"
printf 'Queued Autonomy runs:\n'
cat "$work/run-ids"

deadline=$((SECONDS + ${AUTONOMY_WAIT_SECONDS:-1200}))
while IFS= read -r run_id; do
  while :; do
    if (( SECONDS >= deadline )); then
      echo "Timed out waiting for $run_id; failing the CI job." >&2
      exit 1
    fi
    result=$(post /api/v1/run.get "$(jq -n --arg runId "$run_id" '{runId:$runId}')")
    status=$(jq -er '.status' <<< "$result")
    case "$status" in
      queued|running|retrying) sleep 10 ;;
      passing|failed|unverified|invalid|canceled)
        printf '%s: %s\n' "$run_id" "$status"
        if ! jq -e '.verdict == "passed" and .validity == "valid"' <<< "$result" > /dev/null; then
          echo "Autonomy gate failed for $run_id." >&2
          exit 1
        fi
        break ;;
      *) echo "Unexpected run status: $status" >&2; exit 1 ;;
    esac
  done
done < "$work/run-ids"
echo 'Every Autonomy run passed.'

Enregistrez cette configuration dans bitrise.yml. Définissez les variables du workflow ci-dessus, puis choisissez Start build → web après avoir déployé la prévisualisation. Le Step de clonage s’exécute sur Bitrise ; la CLI locale utilise le dépôt déjà cloné.

bitrise.yml
format_version: '13'
default_step_lib_source: https://github.com/bitrise-io/bitrise-steplib.git
workflows:
  web:
    meta:
      bitrise.io:
        stack: linux-docker-android-22.04
        machine_type_id: standard
    steps:
      - activate-ssh-key@4:
          run_if: '{{getenv "SSH_RSA_PRIVATE_KEY" | ne ""}}'
      - git-clone@8:
          run_if: '{{getenv "BITRISE_IO" | eq "true"}}'
      - script@1:
          title: Autonomy
          inputs:
          - content: |-
              #!/usr/bin/env bash
              set -euo pipefail
              set +x
              : "${PREVIEW_URL:?Set the deployed preview URL}"
              curl --fail --silent --show-error --retry 12 \
                --retry-delay 5 --retry-connrefused --max-time 20 \
                "$PREVIEW_URL" > /dev/null
              attempt="$(cat /proc/sys/kernel/random/uuid 2>/dev/null || uuidgen)"
              export AUTONOMY_REQUEST_ID="bitrise:${BITRISE_BUILD_SLUG:-local}:${BITRISE_TRIGGERED_WORKFLOW_ID}:$attempt"
              export AUTONOMY_BRANCH="${BITRISE_GIT_BRANCH:-$(git branch --show-current)}"
              export AUTONOMY_COMMIT_SHA="$(git rev-parse HEAD)"
              bash .ci/autonomy.sh web

Pour utiliser le runner local, installez la CLI Bitrise, puis enregistrez ceci dans .bitrise.secrets.yml à côté de bitrise.yml. Remplacez les quatre exemples par votre clé API, l’URL du déploiement, l’ID du plan et une URL de prévisualisation accessible :

.bitrise.secrets.yml
envs:
- AUTONOMY_API_KEY: 'aut_REPLACE_WITH_ORG_KEY'
  opts:
    is_expand: false
- AUTONOMY_API_URL: 'https://your-deployment.convex.site'
  opts:
    is_expand: false
- AUTONOMY_TEST_PLAN_ID: 'REPLACE_WITH_TEST_PLANS_ID'
  opts:
    is_expand: false
- PREVIEW_URL: 'https://your-preview.example.com'
  opts:
    is_expand: false

Exécutez ces commandes depuis la racine du dépôt. Excluez le fichier de secrets du contrôle de version. La CLI locale s’exécute sur votre machine ; la sélection de stack dans meta ne concerne que les builds hébergés.

printf '\n.bitrise*\n' >> .gitignore
chmod 600 .bitrise.secrets.yml
bitrise setup
bitrise run web

Transfert d’artefact mobile

Utilisez le même .ci/autonomy.sh ci-dessus. Il demande une URL de téléversement, envoie le binaire avec PUT, exige une analyse sans menace et déclenche l’exécution avec l’ID de stockage reçu. Le build et le téléversement partagent le même répertoire de travail ; aucun transfert d’artefact entre workflows n’est nécessaire.

iOS

Cette alternative complète pour bitrise.yml utilise une stack Xcode sur macOS. Définissez AUTONOMY_TEST_PLAN_ID avec votre plan iOS et APP_IDENTIFIER avec son identifiant de bundle. Remplacez ios/MyApp.xcodeproj, MyApp et le nom du .app produit par votre projet, schéma partagé et nom de produit. Si votre application utilise un workspace, remplacez -project ios/MyApp.xcodeproj par -workspace ios/MyApp.xcworkspace. Gardez les étapes existantes d’installation des dépendances avant xcodebuild.

Construisez un .app pour Simulator, puis compressez-le en ZIP ; un .ipa destiné aux appareils ne convient pas ici. Le téléversement et l’attente du verdict s’exécutent aussi sur macOS et consomment du temps de build.

bitrise.yml
format_version: '13'
default_step_lib_source: https://github.com/bitrise-io/bitrise-steplib.git
workflows:
  ios:
    meta:
      bitrise.io:
        stack: osx-xcode-26.4.x
        machine_type_id: g2.mac.medium
    steps:
      - activate-ssh-key@4:
          run_if: '{{getenv "SSH_RSA_PRIVATE_KEY" | ne ""}}'
      - git-clone@8:
          run_if: '{{getenv "BITRISE_IO" | eq "true"}}'
      - script@1:
          title: Autonomy
          inputs:
          - content: |-
              #!/usr/bin/env bash
              set -euo pipefail
              set +x
              xcodebuild -project ios/MyApp.xcodeproj -scheme MyApp \
                -configuration Release -sdk iphonesimulator \
                -destination 'generic/platform=iOS Simulator' \
                -derivedDataPath .build/ios CODE_SIGNING_ALLOWED=NO build
              mkdir -p .build/artifacts
              ditto -c -k --sequesterRsrc --keepParent \
                .build/ios/Build/Products/Release-iphonesimulator/MyApp.app \
                .build/artifacts/MyApp.app.zip
              export ARTIFACT_PATH="$PWD/.build/artifacts/MyApp.app.zip"
              attempt="$(cat /proc/sys/kernel/random/uuid 2>/dev/null || uuidgen)"
              export AUTONOMY_REQUEST_ID="bitrise:${BITRISE_BUILD_SLUG:-local}:${BITRISE_TRIGGERED_WORKFLOW_ID}:$attempt"
              export AUTONOMY_BRANCH="${BITRISE_GIT_BRANCH:-$(git branch --show-current)}"
              export AUTONOMY_COMMIT_SHA="$(git rev-parse HEAD)"
              bash .ci/autonomy.sh ios

Android

Cette alternative complète pour bitrise.yml utilise la stack Android sur Linux. Définissez AUTONOMY_TEST_PLAN_ID avec votre plan Android et APP_IDENTIFIER avec son identifiant d’application. Elle suppose un projet Android dans android/, un wrapper Gradle dans le dépôt et le module app. Adaptez ensemble le répertoire, la tâche et le chemin de l’APK si votre projet utilise un autre module ou une autre variante. Conservez les versions du JDK et du SDK Android requises par votre build existant.

bitrise.yml
format_version: '13'
default_step_lib_source: https://github.com/bitrise-io/bitrise-steplib.git
workflows:
  android:
    meta:
      bitrise.io:
        stack: linux-docker-android-22.04
        machine_type_id: standard
    steps:
      - activate-ssh-key@4:
          run_if: '{{getenv "SSH_RSA_PRIVATE_KEY" | ne ""}}'
      - git-clone@8:
          run_if: '{{getenv "BITRISE_IO" | eq "true"}}'
      - script@1:
          title: Autonomy
          inputs:
          - content: |-
              #!/usr/bin/env bash
              set -euo pipefail
              set +x
              (cd android && bash ./gradlew --no-daemon assembleDebug)
              export ARTIFACT_PATH="$PWD/android/app/build/outputs/apk/debug/app-debug.apk"
              attempt="$(cat /proc/sys/kernel/random/uuid 2>/dev/null || uuidgen)"
              export AUTONOMY_REQUEST_ID="bitrise:${BITRISE_BUILD_SLUG:-local}:${BITRISE_TRIGGERED_WORKFLOW_ID}:$attempt"
              export AUTONOMY_BRANCH="${BITRISE_GIT_BRANCH:-$(git branch --show-current)}"
              export AUTONOMY_COMMIT_SHA="$(git rev-parse HEAD)"
              bash .ci/autonomy.sh android

Bitrise propose actuellement macOS Medium et Linux Medium avec son offre gratuite Hobby, comprenant 300 crédits par mois et une limite de 90 minutes par build. Les exemples sélectionnent respectivement g2.mac.medium et standard. Un bitrise run ios local nécessite toujours votre propre Mac avec Xcode ; sélectionner une stack macOS en YAML ne crée pas de Mac distant. Vérifiez vos crédits restants avant les builds mobiles hébergés. Consultez les tarifs Bitrise.

Conditionner le pipeline au verdict

Le script affiche chaque ID d’exécution en file d’attente et interroge POST /api/v1/run.get. Une réponse en file d’attente confirme seulement l’envoi. Le workflow ne réussit que lorsque toutes les exécutions ont verdict: "passed" et validity: "valid". Un résultat en échec, non vérifié, invalide, annulé, inconnu, hors délai ou une erreur HTTP fait échouer le Step Script et arrête les Steps normaux suivants. N’ajoutez pas is_skippable: true à ce Step.

L’attente par défaut est de 20 minutes ; augmentez AUTONOMY_WAIT_SECONDS dans la limite de Bitrise si votre plan en a besoin. L’expiration du délai n’annule pas l’exécution Autonomy. Ouvrez l’exécution dans Runs avec l’ID affiché pour consulter ses preuves. Chaque invocation crée un nouvel UUID associé au slug du build et à l’ID du workflow, afin qu’un nouvel essai ou une invocation locale crée une nouvelle exécution.

Stratégie de branche et d’événement

Les exemples sont des workflows manuels sans déclencheur automatique, afin de ne pas exposer de clé API à du code non fiable lors de la configuration. Commencez par un petit plan de smoke test, puis configurez un déclencheur de push pour une branche de préproduction ou de version de confiance dans Bitrise. Ajoutez le Step Autonomy après le déploiement dans ce workflow, en conservant ses filtres de branche. Réservez les plans plus longs aux exécutions planifiées ou manuelles.

Laissez les Secrets indisponibles pour les builds de pull requests, y compris celles issues de forks. Exécutez le QA sur du code relu après son arrivée sur une branche de confiance, ou lancez manuellement le build d’un commit relu. N’activez pas l’exposition des secrets aux pull requests pour faire fonctionner une recette en échec. Les métadonnées de branche et de commit sont transmises à Autonomy ; cette recette ne crée pas de commentaire de pull request.

Références du fournisseur

On this page