Autonomy dokumentatsioon
Integratsioonid

Jenkins

Käivita Autonomy Jenkinsist eelvaate-URL-i või mobiiliartefaktiga ja märgi build ebaõnnestunuks, kui käivitus ei läbi testi.

Lisa Autonomy Jenkinsi Pipeline'i pärast eelvaate juurutust või mobiilibuild'i. See leht sisaldab API abiskripti ja kolme täielikku Jenkinsfile'i; vali oma platvormile sobiv.

Töövoo paigutus

Kasuta Pipeline-tööd valikuga Pipeline script from SCM, mis osutab usaldatud harule ja hoidlas olevale Jenkinsfile-ile. Lisa samasse commit'i .ci/autonomy.sh, loo allpool kirjeldatud mandaadid ja vali Build Now. Veebihaak ega Multibranch Pipeline pole vajalik.

Olemasolevas konveieris paiguta Autonomy etapp pärast juurutuse lõppu, kui eelvaade on kättesaadav. Eraldiseisev veebinäide kasutab juba juurutatud URL-i. Dünaamilise eelvaate korral eemalda autonomy-preview-url sidumine ja määra enne seda etappi env.PREVIEW_URL väärtuseks juurutusetapi väljund.

Paigalda pluginad Pipeline, Pipeline: Declarative, Git ja Credentials Binding koos nende sõltuvustega. Valmista ette Linuxi agent sildiga linux, millel on Bash, Git, jq ning curl 7.76 või uuem. Sildid valivad sinu agendid; Jenkins ei paku hostitud Linuxi ega macOS-i runnereid.

Vajalikud saladused

Lisa jaotises Manage Jenkins → Credentials selle töö jaoks kättesaadavad Secret text tüüpi mandaadid. Hoia ID-d täpselt näidatud kujul. Loo ainult valitud platvormile vajalikud kirjed.

Mandaadi IDVäärtus
autonomy-api-keyOrganisatsiooni aut_ API-võti juurutusest, mida hakkad kutsuma.
autonomy-api-urlAPI baas-URL, näiteks https://YOUR_DEPLOYMENT.convex.site, ilma /api-ta.
autonomy-web-plan-idSinu veebiplaani ID jaotisest Test Plans.
autonomy-preview-urlLõplik ja kättesaadav HTTPS-i eelvaate-URL veebinäite jaoks.
autonomy-ios-plan-idSinu iOS-i plaani ID jaotisest Test Plans.
autonomy-ios-bundle-idEhitatud rakenduse bundle ID, näiteks com.example.app.
autonomy-android-plan-idSinu Androidi plaani ID jaotisest Test Plans.
autonomy-android-package-nameEhitatud APK application ID, näiteks com.example.app.
  • Loo testiplaan, milles on vähemalt üks valitud platvormi testjuhtum. Kasuta selle Test Plans ID-d, mitte üksiku Test Cases testjuhtumi ID-d.
  • Hoia ühilduv Autonomy runner kättesaadavana. Järjekorras käivitused ei anna konveierile edukat tulemust enne lõpetamist.
  • Kasuta juhtumeid, mis ei vaja salvestatud Environmenti käitusaegseid väärtusi. Need näited saadavad otsesed sihtmärgid ega vali Environmenti.
  • Muuda eelvaade Autonomy runnerile kättesaadavaks. Ainult Jenkinsile ligipääsetav URL ei tööta.

withCredentials lisab väärtused ainult API-kutse ajaks. Groovy ülakomadega shelliplokid jätavad muutujate laiendamise Bashile; säilita set +x ja ära kunagi väljasta võtit.

Veebi eelvaate-URL

Salvesta see jagatud abiskript faili .ci/autonomy.sh. Kõik kolm allolevat Jenkinsfile'i kasutavad täpselt seda faili. See edastab sihtmärgi, väljastab kõigi järjekorda lisatud käivituste ID-d ja ootab kõiki otsuseid.

.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.'

Salvesta see veebitöö jaoks failina Jenkinsfile. Neli ülaltoodud veebimandaati võimaldavad esimese käsitsi build'i käivitada ilma töö parameetriteta.

Jenkinsfile
pipeline {
  agent { label 'linux' }
  options {
    skipDefaultCheckout(true)
    timeout(time: 30, unit: 'MINUTES')
  }
  stages {
    stage('Checkout') {
      steps { checkout scm }
    }
    stage('Autonomy web') {
      steps {
        withCredentials([
          string(credentialsId: 'autonomy-api-key', variable: 'AUTONOMY_API_KEY'),
          string(credentialsId: 'autonomy-api-url', variable: 'AUTONOMY_API_URL'),
          string(credentialsId: 'autonomy-web-plan-id', variable: 'AUTONOMY_TEST_PLAN_ID'),
          string(credentialsId: 'autonomy-preview-url', variable: 'PREVIEW_URL')
        ]) {
          sh '''#!/usr/bin/env bash
set -euo pipefail
set +x
export AUTONOMY_REQUEST_ID="jenkins:${JOB_NAME}:${BUILD_NUMBER}"
export AUTONOMY_BRANCH="${BRANCH_NAME:-${GIT_BRANCH:-manual}}"
export AUTONOMY_COMMIT_SHA="$(git rev-parse HEAD)"
bash .ci/autonomy.sh web
'''
        }
      }
    }
  }
}

Mobiiliartefakti üleandmine

Kasuta iga platvormi jaoks eraldi testiplaani. Säilita veebijaotise .ci/autonomy.sh ja asenda Jenkinsfile vastava näitega. Abiskript küsib üleslaadimise URL-i, laadib arhiivi üles, nõuab artefakti puhast skannimistulemust ja käivitab seejärel plaani.

iOS

Valmista ette päris macOS-i agent sildiga macos, millel on Xcode, selle Simulator SDK, Git ja zip. Jenkinsil ei ole tasuta hostitud macOS-i paketti. Kasuta olemasolevat Maci; tasulise mahu hankimine on eraldi otsus. Lahenda projekti sõltuvused enne xcodebuild-i ning asenda MyApp, workspace'i tee ja väljundi nimi oma projekti väärtustega.

Ehita simulaatori .app, mitte seadme .ipa. zip -y säilitab sümboolsed lingid ning arhiiv säilitab käivitusõigused. stash edastab arhiivi Linuxi etapile; Linux laadib selle üles lahti pakkimata. Suurte rakenduste puhul seadista Jenkinsi kaug-artefaktihaldur, et salvestamine ei koormaks kontrollerit.

Jenkinsfile
pipeline {
  agent none
  options { skipDefaultCheckout(true) }
  stages {
    stage('Build iOS Simulator app') {
      agent { label 'macos' }
      options { timeout(time: 60, unit: 'MINUTES') }
      steps {
        checkout scm
        sh '''#!/usr/bin/env bash
set -euo pipefail
xcodebuild \
  -workspace ios/MyApp.xcworkspace \
  -scheme MyApp \
  -configuration Release \
  -sdk iphonesimulator \
  -destination 'generic/platform=iOS Simulator' \
  -derivedDataPath ios/build \
  CODE_SIGNING_ALLOWED=NO build
mkdir -p .build
rm -f .build/MyApp.app.zip
(cd ios/build/Build/Products/Release-iphonesimulator && \
  zip -qry "$WORKSPACE/.build/MyApp.app.zip" MyApp.app)
'''
        stash name: 'ios-simulator', includes: '.build/MyApp.app.zip'
      }
    }
    stage('Autonomy iOS') {
      agent { label 'linux' }
      options { timeout(time: 35, unit: 'MINUTES') }
      steps {
        checkout scm
        unstash 'ios-simulator'
        withCredentials([
          string(credentialsId: 'autonomy-api-key', variable: 'AUTONOMY_API_KEY'),
          string(credentialsId: 'autonomy-api-url', variable: 'AUTONOMY_API_URL'),
          string(credentialsId: 'autonomy-ios-plan-id', variable: 'AUTONOMY_TEST_PLAN_ID'),
          string(credentialsId: 'autonomy-ios-bundle-id', variable: 'APP_IDENTIFIER')
        ]) {
          sh '''#!/usr/bin/env bash
set -euo pipefail
set +x
export ARTIFACT_PATH='.build/MyApp.app.zip'
export AUTONOMY_REQUEST_ID="jenkins:${JOB_NAME}:${BUILD_NUMBER}"
export AUTONOMY_BRANCH="${BRANCH_NAME:-${GIT_BRANCH:-manual}}"
export AUTONOMY_COMMIT_SHA="$(git rev-parse HEAD)"
bash .ci/autonomy.sh ios
'''
        }
      }
    }
  }
}

Android

Valmista ette agent sildiga linux-android, millel on Bash, Git, jq, curl 7.76 või uuem, sinu Gradle'i versiooniga ühilduv JDK ja projektile vajalikud Androidi SDK paketid. Määra agendil JAVA_HOME ning ANDROID_HOME ja nõustu SDK litsentsidega. Näide eeldab käivitatavat Gradle'i wrapper'it asukohas android/gradlew; kohanda kataloogi ja APK teed oma projektile. Build ja üleslaadimine kasutavad sama workspace'i.

Jenkinsfile
pipeline {
  agent { label 'linux-android' }
  options {
    skipDefaultCheckout(true)
    timeout(time: 60, unit: 'MINUTES')
  }
  stages {
    stage('Build Android APK') {
      steps {
        checkout scm
        sh '''#!/usr/bin/env bash
set -euo pipefail
cd android
./gradlew --no-daemon assembleDebug
'''
      }
    }
    stage('Autonomy Android') {
      steps {
        withCredentials([
          string(credentialsId: 'autonomy-api-key', variable: 'AUTONOMY_API_KEY'),
          string(credentialsId: 'autonomy-api-url', variable: 'AUTONOMY_API_URL'),
          string(credentialsId: 'autonomy-android-plan-id', variable: 'AUTONOMY_TEST_PLAN_ID'),
          string(credentialsId: 'autonomy-android-package-name', variable: 'APP_IDENTIFIER')
        ]) {
          sh '''#!/usr/bin/env bash
set -euo pipefail
set +x
export ARTIFACT_PATH='android/app/build/outputs/apk/debug/app-debug.apk'
export AUTONOMY_REQUEST_ID="jenkins:${JOB_NAME}:${BUILD_NUMBER}"
export AUTONOMY_BRANCH="${BRANCH_NAME:-${GIT_BRANCH:-manual}}"
export AUTONOMY_COMMIT_SHA="$(git rev-parse HEAD)"
bash .ci/autonomy.sh android
'''
        }
      }
    }
  }
}

Konveieri sidumine otsusega

Abiskript kutsub POST /api/v1/run.trigger ja pärib seejärel POST /api/v1/run.get kaudu iga tagastatud runIds kirje olekut. Järjekorda lisamise vastus tähendab vaid päringu vastuvõtmist. Edukas tulemus nõuab, et iga lõpptulemus sisaldaks verdict: "passed" ja validity: "valid".

API viga, tagasilükatud skannimistulemus, ootamatu olek, ebaõnnestunud või kinnitamata tulemus, tühistamine või ajalõpp annab nullist erineva väljumiskoodi, mis märgib Jenkinsi etapi ebaõnnestunuks. Vaikimisi on kõigi tagastatud käivituste päringute ajapiir 1200 sekundit; pikemate plaanide jaoks suurenda AUTONOMY_WAIT_SECONDS väärtust ja kohanda ka Jenkinsi timeout-i. Konveieri ajalõpp ei tühista juba järjekorras olevat Autonomy käivitust.

AUTONOMY_REQUEST_ID ühendab Jenkinsi töö nime ja build'i numbri; abiskript lisab platvormi. Sama build'i sees uuesti käivitamine kasutab sama idempotentsusvõtit; uus Jenkinsi build saab uue võtme.

Haru- ja sündmusstrateegia

Alusta käsitsi build'idega usaldatud vaikeharust. Kui juurutuse üleandmine töötab, lisa tööle olemasolev SCM-päästik või ajakava. Kasuta usaldatud muudatuste build'ides lühikesi smoke-plaane ning väljalaske- või ajastatud build'ides suuremaid plaane.

Hoidlast võetud skriptidel on mandaatidele juurdepääs. Ära käivita nende mandaatidega ebausaldusväärse pull request'i Jenkinsfile'i ega abiskripti, isegi kui haru nimi vastab filtrile. Kasuta kinnitatud eelvaate-URL-i testimiseks usaldatud tööd. Hoia neid mandaate kasutavad agendid lahus ebausaldusväärseid töid käivitavatest agentidest.

Teenusepakkuja viited

Näited kasutavad dokumenteeritud Declarative Pipeline'i süntaksit, Secret text sidumisi, stash- ja unstash-samme ning Jenkinsi agente. Pipeline from SCM seadistamiseks vaata lehte Using a Jenkinsfile.

On this page