GitHub Actions
Alusta Autonomy käivitusi GitHub Actionsi töövoost veebieelvaate või Androidi APK jaoks ja kukuta töövoog läbi, kui iga käivitus ei läbi.
Kasuta GitHub Actionsit, kui soovid Autonomyt oma töövoo sammuna: pärast kohandatud juurutusskripti, mobiilibuildi jaoks või enne väljalasketööd. Töövoog alustab käivitused, ootab nende tulemusi ja kukub läbi, kui iga käivitus pole Passed.
Kui soovid testiplaani käivitada igal pull request'il ilma töövoofailita, kasuta hoopis GitHubi rakendust. See käivitab projekti pull request'i plaani eelvaate juurutuse vastu ja teatab tulemusest GitHubi kontrollina. Vaata Pull request'ide testimine.
Koht töövoos
Pane Autonomy samm pärast tööd, mis juurutab eelvaate või ehitab rakenduse. Käivitus peab saama lõpliku URL-i, mille ülevaataja avaks, või buildifaili enda. Allolev veebinäide võtab juba juurutatud URL-i; see ei juuruta sinu rakendust.
Iga allolev töövoog on terviklik fail. Kui lisad selle olemasolevasse töövoogu, jäta oma buildi- ja juurutustööd alles ning suuna needs tööle, mis URL-i või buildi loob.
Vajalikud saladused
Lisa hoidla lehel Settings → Secrets and variables → Actions:
| Nimi | Liik | Väärtus |
|---|---|---|
AUTONOMY_API_KEY | Saladus | Organisatsiooni API-võti, mis algab eesliitega aut_. Omanikud ja administraatorid loovad võtmeid lehel Organization → API keys. |
AUTONOMY_TEST_PLAN_ID | Muutuja | Käivitatav testiplaan. Ava see projekti lehel Test plans: ID on lehe URL-i viimane osa, /p/<project>/plans/<id>. |
PREVIEW_URL | Muutuja | Ainult veeb: juurutatud HTTPS-URL, millele Autonomy internetist ligi pääseb, mitte localhost. |
AUTONOMY_IOS_BUNDLE_ID | Muutuja | Ainult iOS: ehitatud rakenduse bundle ID. |
AUTONOMY_ANDROID_PACKAGE_NAME | Muutuja | Ainult Android: ehitatud APK rakenduse ID. |
Valikulised väärtused, mida abiskript loeb:
AUTONOMY_TEST_CASE_ID: käivita plaani asemel üks testjuhtum. Selle ID on aadressi/p/<project>/tests/<id>viimane osa. Sea täpselt üks väärtustestAUTONOMY_TEST_CASE_IDjaAUTONOMY_TEST_PLAN_ID.AUTONOMY_ENVIRONMENT_SLUG: käivita selle töö URL-i või buildi asemel sama projekti salvestatud keskkonnas, selle sihtmärkide ja keskkonna väärtustega. Abiskript jätab siis üleslaadimise vahele.AUTONOMY_WAIT_SECONDS: kõigi käivituste kogu ooteaeg, vaikimisi 1200 sekundit.
Ilma keskkonnata pole käivitusel keskkonna väärtusi: samm, mis kasutab {{env.NAME}} väärtust, lõpeb tulemusega Couldn't start. Sea AUTONOMY_ENVIRONMENT_SLUG või kasuta testjuhtumeid, mis keskkonna väärtusi ei vaja. Kasuta iga platvormi jaoks eraldi testiplaani, et tulemus viitaks õigele rakendusele.
Veebieelvaate URL
Loo hoidla juurkausta kaust .ci ja salvesta see skript failina .ci/autonomy.sh. Kõik selle lehe töövood ning GitLabi, Jenkinsi, Bitrise'i ja CircleCI retseptid kasutavad sama faili. See vajab Bashi, jq-d ja curl'i versiooni 7.76 või uuemat; GitHubi majutatud runneritel on need olemas.
#!/usr/bin/env bash
# Usage: bash .ci/autonomy.sh web|ios|android
# Starts Autonomy runs for this CI job and exits 0 only if every run passed.
set -euo pipefail
set +x
: "${AUTONOMY_API_KEY:?Set an aut_ organization API key}"
: "${AUTONOMY_REQUEST_ID:?Set an ID that is unique for this CI job attempt}"
platform="${1:?Usage: bash .ci/autonomy.sh web|ios|android}"
api="${AUTONOMY_API_URL:-https://api.autonomyqa.com}"
api="${api%/}"
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"
}
# 1. What to run: a test plan or one test case.
if [ -n "${AUTONOMY_TEST_PLAN_ID:-}" ] && [ -z "${AUTONOMY_TEST_CASE_ID:-}" ]; then
what=$(jq -n --arg id "$AUTONOMY_TEST_PLAN_ID" '{testPlanId:$id}')
elif [ -n "${AUTONOMY_TEST_CASE_ID:-}" ] && [ -z "${AUTONOMY_TEST_PLAN_ID:-}" ]; then
what=$(jq -n --arg id "$AUTONOMY_TEST_CASE_ID" '{testCaseId:$id}')
else
echo 'Set exactly one of AUTONOMY_TEST_PLAN_ID or AUTONOMY_TEST_CASE_ID.' >&2
exit 2
fi
# 2. Where to run: a saved environment, or this job's preview URL or build.
if [ -n "${AUTONOMY_ENVIRONMENT_SLUG:-}" ]; then
where=$(jq -n --arg slug "$AUTONOMY_ENVIRONMENT_SLUG" '{environmentSlug:$slug}')
else
case "$platform" in
web)
: "${PREVIEW_URL:?Set PREVIEW_URL, or AUTONOMY_ENVIRONMENT_SLUG}"
where=$(jq -n --arg url "$PREVIEW_URL" '{targets:{web:{baseUrl:$url}}}')
;;
ios|android)
: "${ARTIFACT_PATH:?Set the path to the zipped .app, .apk or .aab}"
: "${APP_IDENTIFIER:?Set the iOS bundle ID or Android package name}"
file=$(basename "$ARTIFACT_PATH")
bytes=$(wc -c < "$ARTIFACT_PATH" | tr -d '[:space:]')
if [ "$platform" = ios ]; then
type=application/zip
else
type=application/vnd.android.package-archive
fi
upload=$(post /api/artifacts/upload-url "$(jq -n \
--arg platform "$platform" --arg fileName "$file" \
--arg contentType "$type" --argjson declaredBytes "$bytes" \
'{platform:$platform,fileName:$fileName,contentType:$contentType,declaredBytes:$declaredBytes}')")
storage=$(jq -er '.storageId' <<< "$upload")
intent=$(jq -er '.intentId' <<< "$upload")
curl --fail-with-body --silent --show-error \
--connect-timeout 15 --max-time 600 \
-X PUT "$(jq -er '.uploadUrl' <<< "$upload")" \
-H "Content-Type: $type" --data-binary "@$ARTIFACT_PATH"
scan=$(post /api/artifacts/scan "$(jq -n \
--arg storageId "$storage" --arg intentId "$intent" \
'{storageId:$storageId,intentId:$intentId}')")
if [ "$(jq -r '.status' <<< "$scan")" != clean ]; then
echo 'The build did not pass the safety check, so no run was started:' >&2
jq -r '.findings[]?.message' <<< "$scan" >&2
exit 1
fi
where=$(jq -n --arg p "$platform" --arg storageId "$storage" \
--arg fileName "$file" --arg id "$APP_IDENTIFIER" \
'{targets:{($p):({storageId:$storageId,sourceMode:"upload",fileName:$fileName}
+ (if $p == "ios" then {bundleId:$id} else {packageName:$id} end))}}')
;;
*) echo 'Usage: bash .ci/autonomy.sh web|ios|android' >&2; exit 2 ;;
esac
fi
# 3. Start the runs. A plan starts one run per test case.
# The request ID's prefix (github, gitlab, ...) names the CI provider.
body=$(jq -n --argjson what "$what" --argjson where "$where" \
--arg platform "$platform" \
--arg branch "${AUTONOMY_BRANCH:-}" --arg pr "${AUTONOMY_PR:-}" \
--arg commitSha "${AUTONOMY_COMMIT_SHA:-}" \
--arg provider "${AUTONOMY_REQUEST_ID%%:*}" \
--arg key "$AUTONOMY_REQUEST_ID:$platform" \
'$what + $where + ({
platforms: [$platform],
branch: $branch,
pr: $pr,
deployment: ({provider: $provider, branch: $branch, commitSha: $commitSha}
| with_entries(select(.value != ""))),
idempotencyKey: $key
} | with_entries(select(.value != "")))')
run_ids=$(post /api/v1/run.trigger "$body" | jq -er '.runIds[]')
printf 'Started Autonomy runs:\n%s\n' "$run_ids"
# 4. Follow each run until it ends. run.get waits up to 25 s for a change;
# sending the last cursor back makes each call wait for something new.
deadline=$((SECONDS + ${AUTONOMY_WAIT_SECONDS:-1200}))
all_passed=true
for run_id in $run_ids; do
cursor=null
while :; do
left=$((deadline - SECONDS))
if [ "$left" -le 0 ]; then
echo "Stopped waiting for run $run_id after AUTONOMY_WAIT_SECONDS. It keeps going in Autonomy." >&2
exit 1
fi
wait_ms=$(( left < 25 ? left * 1000 : 25000 ))
run=$(post /api/v1/run.get "$(jq -n --arg runId "$run_id" \
--argjson cursor "$cursor" --argjson waitMs "$wait_ms" \
'{runId:$runId,cursor:$cursor,waitMs:$waitMs}')")
cursor=$(jq '.cursor' <<< "$run")
status=$(jq -r '.status' <<< "$run")
[ "$status" = queued ] || [ "$status" = running ] || break
done
name="$(jq -r '.testCaseName' <<< "$run") ($run_id)"
case "$status" in
passed)
echo "Passed: $name" ;;
failed)
echo "Failed: $name. Open the run in Autonomy to see which step failed." >&2
all_passed=false ;;
couldnt_start)
echo "Couldn't start: $name. The environment couldn't be tested, so this says nothing about your app. Open the run for the reason, fix it and run again." >&2
all_passed=false ;;
cancelled)
echo "Cancelled: $name." >&2
all_passed=false ;;
*)
echo "Unexpected status $status: $name." >&2
all_passed=false ;;
esac
done
if [ "$all_passed" != true ]; then
echo 'Not every Autonomy run passed.' >&2
exit 1
fi
echo 'Every Autonomy run passed.'Salvesta see failina .github/workflows/autonomy-web.yml. Käivita see lehelt Actions → Autonomy web → Run workflow, soovi korral eelvaate URL-iga.
name: Autonomy web
on:
push:
branches: [main]
workflow_dispatch:
inputs:
preview_url:
description: Preview URL to test
required: false
jobs:
autonomy:
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v5
- name: Run Autonomy
env:
AUTONOMY_API_KEY: ${{ secrets.AUTONOMY_API_KEY }}
AUTONOMY_TEST_PLAN_ID: ${{ vars.AUTONOMY_TEST_PLAN_ID }}
PREVIEW_URL: ${{ inputs.preview_url || vars.PREVIEW_URL }}
AUTONOMY_REQUEST_ID: github-actions:${{ github.run_id }}:${{ github.run_attempt }}
AUTONOMY_BRANCH: ${{ github.head_ref || github.ref_name }}
AUTONOMY_COMMIT_SHA: ${{ github.sha }}
run: bash .ci/autonomy.sh webKui eelvaate juurutab varasem töö, avalda selle URL töö väljundina, lisa see töö loendisse needs ja sea PREVIEW_URL: ${{ needs.deploy.outputs.url }}.
Mobiiliartefakti üleandmine
Kasuta sama faili .ci/autonomy.sh. iOS-i ja Androidi puhul küsib see üleslaadimise URL-i, laadib buildi üles, ootab, kuni turvakontroll tuleb puhtana tagasi, ja alustab seejärel käivitused üleslaaditud buildiga.
iOS
iOS-i testimine tuleb peagi. Hoia see alles ajaks, mil see on saadaval. Seni ei alusta Autonomy iOS-is käivitusi.
Ehita simulaatori .app macOS-is, paki see seal zip-faili, et õigused ja sümbolingid säiliksid, ning anna zip Actionsi artefaktina edasi Linuxi tööle. Üleslaadimine ja ootamine kulutavad siis Linuxi minuteid. Asenda MyApp ja tööruumi tee enda omadega; ilma tööruumita projekti puhul kasuta -project ios/MyApp.xcodeproj. Ehita simulaatori jaoks, mitte seadme .ipa.
name: Autonomy iOS
on:
push:
branches: [main]
workflow_dispatch:
jobs:
build:
runs-on: macos-latest
timeout-minutes: 60
steps:
- uses: actions/checkout@v5
- name: Build and zip the simulator app
run: |
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
(cd ios/build/Build/Products/Release-iphonesimulator && \
zip -qry "$GITHUB_WORKSPACE/.build/MyApp.app.zip" MyApp.app)
- uses: actions/upload-artifact@v5
with:
name: ios-simulator-app
path: .build/MyApp.app.zip
retention-days: 1
autonomy:
needs: build
runs-on: ubuntu-latest
timeout-minutes: 35
steps:
- uses: actions/checkout@v5
- uses: actions/download-artifact@v5
with:
name: ios-simulator-app
path: .build
- name: Run Autonomy
env:
AUTONOMY_API_KEY: ${{ secrets.AUTONOMY_API_KEY }}
AUTONOMY_TEST_PLAN_ID: ${{ vars.AUTONOMY_TEST_PLAN_ID }}
APP_IDENTIFIER: ${{ vars.AUTONOMY_IOS_BUNDLE_ID }}
ARTIFACT_PATH: .build/MyApp.app.zip
AUTONOMY_REQUEST_ID: github-actions:${{ github.run_id }}:${{ github.run_attempt }}
AUTONOMY_BRANCH: ${{ github.ref_name }}
AUTONOMY_COMMIT_SHA: ${{ github.sha }}
run: bash .ci/autonomy.sh iosAndroid
Androidi build'id jooksevad Linuxis, seega mahuvad build ja üleslaadimine ühte töösse. Kui kasutad teist moodulit või buildi varianti, muuda Gradle'i ülesannet ja APK teed koos. Sobib ka .aab.
name: Autonomy Android
on:
push:
branches: [main]
workflow_dispatch:
jobs:
autonomy:
runs-on: ubuntu-latest
timeout-minutes: 60
steps:
- uses: actions/checkout@v5
- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: '17'
- name: Build the debug APK
run: |
set -euo pipefail
cd android
./gradlew --no-daemon assembleDebug
- name: Run Autonomy
env:
AUTONOMY_API_KEY: ${{ secrets.AUTONOMY_API_KEY }}
AUTONOMY_TEST_PLAN_ID: ${{ vars.AUTONOMY_TEST_PLAN_ID }}
APP_IDENTIFIER: ${{ vars.AUTONOMY_ANDROID_PACKAGE_NAME }}
ARTIFACT_PATH: android/app/build/outputs/apk/debug/app-debug.apk
AUTONOMY_REQUEST_ID: github-actions:${{ github.run_id }}:${{ github.run_attempt }}
AUTONOMY_BRANCH: ${{ github.ref_name }}
AUTONOMY_COMMIT_SHA: ${{ github.sha }}
run: bash .ci/autonomy.sh androidKui build on juba lühiajalise HTTPS-lingi taga, võid üleslaadimise vahele jätta: kutsu run.trigger väärtusega targets.ios.artifactUrl või targets.android.artifactUrl ja sourceMode: "url". Vaata Mobiilibuild'id.
Pipeline'i sidumine tulemusega
Abiskript alustab käivitused päringuga POST /api/v1/run.trigger ja prindib nende ID-d. Testiplaan alustab iga testjuhtumi kohta ühe käivituse. Seejärel jälgib see iga käivitust päringuga POST /api/v1/run.get, saates tagasi viimase cursor väärtuse koos waitMs: 25000, nii et iga kutse ootab, kuni käivitus muutub. Vastus timedOut: true tähendab ainult, et midagi pole veel muutunud. Vaata Käivitused ja välised tõendid.
| Käivituse tulemus | Töö | Mida logi ütleb |
|---|---|---|
| Passed | Läbib, kui ka kõik teised käivitused läbisid. Ebastabiilne läbimine loeb läbinuks. | Passed |
| Failed | Kukub läbi. | Ava käivitus, et näha, milline samm läbi kukkus ja miks, sealhulgas Runner problem. |
| Couldn't start | Kukub läbi. | Keskkonda ei saanud testida, näiteks build ei paigaldunud või mõni väärtus puudus. See ei ütle sinu rakenduse kohta midagi; paranda põhjus ja käivita uuesti. |
| Cancelled | Kukub läbi. | Cancelled |
Töö kukub läbi ka API-vigade, turvakontrollist mitte läbi tulnud buildi ja ooteaja lõppemise korral. AUTONOMY_WAIT_SECONDS on kõigi käivituste kogu ooteaeg, vaikimisi 1200 sekundit. Hoia CI-töö ajalimiit sellest pikem, lisades buildi ja üleslaadimise aja. CI-töö peatamine ei tühista juba alanud käivitusi.
AUTONOMY_REQUEST_ID koos lisatud platvormiga saab päringu run.trigger väärtuseks idempotencyKey: kui sama tööpüüe saadab päringu uuesti, saab see uute asemel tagasi samad käivitused. Anna igale tööpüüdele oma ID. Esimese koolonini ulatuv osa saadetakse juurutuse pakkujana ning haru ja commit saadetakse koos käivitustega. Päringu ja vastuse täielik kuju on lehel Toimingud.
Harude ja sündmuste strateegia
Need töövood käivituvad push'idel harusse main ja käsitsi alustamisel. Käivita tavalistel push'idel lühikesi suitsutesti plaane ning väljalaskeharudel, ajakavade järgi või käsitsi laiemaid plaane. Kui plaan puudutab tasulisi teenuseid või napilt saadaolevaid testandmeid, alusta seda käsitsi.
GitHub ei anna saladusi forkitud pull request'ide töövoogudele, seega need töövood nende jaoks käivituda ei saa. Kui soovid käivitust igal pull request'il selle eelvaate juurutuse vastu, kasuta GitHubi rakendust: vaata Pull request'ide testimine.
Tõrkeotsing
Veebikäivitus algab enne, kui eelvaade on valmis
Jaga juurutamine ja testimine eraldi töödeks ning anna juurutuse URL edasi töö väljundi kaudu. Alusta Autonomyt alles siis, kui URL on teada ja vastab.
Üleslaadimine lükatakse tagasi
Abiskript prindib turvakontrolli põhjused. iOS-i puhul kontrolli, et build kasutas valikut -sdk iphonesimulator ja simulaatori sihtkohta: seadme .ipa ei tööta simulaatoris. Androidi puhul laadi üles .apk või .aab.
Keskkonna väärtusi kasutavad sammud ei saanud alata
Selgesõnalise URL-i või buildiga käivitusel pole keskkonda. Sea AUTONOMY_ENVIRONMENT_SLUG salvestatud keskkonnale või eemalda nendest testjuhtumitest {{env.NAME}} viited.
Androidi build ei leia SDK-d
GitHubi majutatud Ubuntu runneritel on Androidi SDK olemas. Oma runneril paigalda käsureatööriistad enne Gradle'i sammu.
Ei leidnud?