GitLab CI
Alusta Autonomy käivitusi GitLab CI-st eelvaate URL-i või Androidi APK jaoks ja kukuta pipeline läbi, kui iga käivitus ei läbi.
Alusta Autonomy pärast juurutust või mobiilibuildi ja hoia GitLabi töö avatuna, kuni igal käivitusel on tulemus. Töö läbib ainult siis, kui iga käivitus on Passed. Kopeeri jagatud skript ja selle platvormi konfiguratsioon, mida välja annad.
Koht töövoos
Pane Autonomy pärast juurutustööd, mis leiab lõpliku eelvaate URL-i, või pärast tööd, mis ehitab mobiilirakenduse. Allolev veebinäide võtab juba juurutatud URL-i ja kontrollib, et see vastab. See ei juuruta sinu rakendust.
Iga YAML-näide on terviklik alternatiivne .gitlab-ci.yml. Kui lisad selle olemasolevasse pipeline'i, jäta oma buildi- ja juurutustööd alles, ühenda selle etapid ja suuna needs tööle, mis URL-i või buildi loob. Käivita kaitstud vaikeharul ainult usaldusväärset koodi.
Vajalikud saladused
Lisa lehel Settings → CI/CD → Variables need väärtused tüübiga Variable, mitte File, keskkonna ulatusega *. Kaitse muutujad ja lülita muutujaviidete laiendamine välja. Märgi API-võti valikuga Masked and hidden. Kaitse vaikeharu enne näidete käivitamist.
-
AUTONOMY_API_KEY: organisatsiooni API-võti, mis algab eesliitegaaut_. Omanikud ja administraatorid loovad võtmeid lehel Organization → API keys. Võti pääseb ligi organisatsiooni kõigile projektidele. -
AUTONOMY_TEST_PLAN_ID: käivitatav testiplaan. Ava see projekti lehel Test plans: ID on lehe URL-i viimane osa,/p/<project>/plans/<id>. Plaanis peab olema vähemalt üks selle platvormi testjuhtum. Kui soovid hoopis üht testjuhtumit käivitada, seaAUTONOMY_TEST_CASE_ID(aadressist/p/<project>/tests/<id>) ja jäta plaani ID seadmata. Sea täpselt üks neist kahest. -
PREVIEW_URL: veebinäite jaoks valmis HTTPS-eelvaate URL. Autonomy peab sellele internetist ligi pääsema: mittelocalhostega teenus, mis on olemas ainult CI-töö sees. - iOS-i jaoks lisa
AUTONOMY_IOS_TEST_PLAN_IDjaAUTONOMY_IOS_BUNDLE_ID. Androidi jaoks lisaAUTONOMY_ANDROID_TEST_PLAN_IDjaAUTONOMY_ANDROID_PACKAGE_NAME. Igas plaanis peavad olema selle platvormi testjuhtumid ja identifikaatorid peavad vastama ehitatud rakendusele. - Valikuline:
AUTONOMY_ENVIRONMENT_SLUGkäivitab 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_SECONDSmuudab kogu ooteaega.
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.
Näited seavad AUTONOMY_REQUEST_ID väärtuse muutujast CI_JOB_ID, nii et korratud GitLabi töö saab uue päringu. Haru ja commit tulevad GitLabi eeldefineeritud muutujatest. Testjuhtumite koondamise kohta vaata Testiplaanid ja ajakavad.
Veebieelvaate URL
Loo hoidla juurkausta .ci/, salvesta see skript failina .ci/autonomy.sh ja lisa see commit'i koos oma pipeline'i failiga. Kõik selle lehe retseptid kasutavad sama skripti. See vajab Bashi, jq-d ja curl'i versiooni 7.76 või uuemat; konteineritööd paigaldavad need.
#!/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 .gitlab-ci.yml. Lülita oma projektile sisse GitLabi majutatud Linuxi runnerid; veebitöö ja iOS-i üleslaadimistöö valivad sildi saas-linux-small-amd64. GitLab Self-Managedis asenda see silt igas Linuxi konteineritöös oma Linuxi Docker executor'iga runneri sildiga. Alusta kaitstud vaikeharul valikuga Build → Pipelines → New pipeline. Kui Autonomy päringu vastu võtab, prindib logi Started Autonomy runs: ja käivituste ID-d.
stages: [prepare, qa]
workflow:
rules:
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_COMMIT_REF_PROTECTED == "true"'
- when: never
default:
tags: [saas-linux-small-amd64]
image: debian:stable-slim
before_script:
- apt-get update && apt-get install -y --no-install-recommends bash curl jq ca-certificates
preview_ready:
stage: prepare
script:
- |
: "${PREVIEW_URL:?Set the deployed preview URL in CI/CD Variables}"
curl --fail --silent --show-error --location \
--connect-timeout 15 --max-time 60 "$PREVIEW_URL" > /dev/null
printf 'PREVIEW_URL=%s\n' "$PREVIEW_URL" > preview.env
artifacts:
reports:
dotenv: preview.env
expire_in: 1 day
autonomy_web:
stage: qa
timeout: 30m
needs:
- job: preview_ready
artifacts: true
script:
- |
export AUTONOMY_REQUEST_ID="gitlab:$CI_PROJECT_ID:$CI_JOB_ID"
export AUTONOMY_BRANCH="$CI_COMMIT_REF_NAME"
export AUTONOMY_COMMIT_SHA="$CI_COMMIT_SHA"
bash .ci/autonomy.sh webKui URL luuakse sinu olemasolevas juurutustöös, vii kirjed printf ja artifacts:reports:dotenv sellesse töösse ning muuda needs selle nimeks. Eemalda fikseeritud projektimuutuja PREVIEW_URL, et see genereeritud väärtust üle ei kirjutaks. Ära pane mandaate faili preview.env; GitLab salvestab selle allalaaditava artefaktina.
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 käivitused üleslaaditud buildiga. Kasuta ainult seda platvormi, mille build on sinu hoidlas.
iOS
iOS-i testimine tuleb peagi. Hoia see alles ajaks, mil see on saadaval. Seni ei alusta Autonomy iOS-is käivitusi.
Kasuta eraldi, kaitstud, isehallatavat macOS-i runnerit, millel on silt macos, Bashi shell executor, Xcode ja iOS Simulator SDK. Lülita selle runneri jaoks välja Run untagged jobs ja ära anna talle Linuxi runneri silti. GitLabi majutatud macOS-i runnerid vajavad paketti Premium või Ultimate, välja arvatud sobivates avatud lähtekoodi programmides, seega vajab Free-projekt oma Maci. Linux seda Xcode'i buildi teha ei saa.
See näide eeldab faili ios/MyApp.xcodeproj, jagatud skeemi MyApp ja toodet MyApp.app. Asenda kõik kolm oma nimedega ja paigalda enne xcodebuild käsku oma projekti sõltuvused. Tööruumi puhul kasuta valiku -project asemel -workspace ios/MyApp.xcworkspace. See ehitab simulaatori .app, mitte seadme .ipa.
macOS-i töö pakib rakenduse zip-faili, säilitades õigused ja sümbolingid, enne kui GitLab selle edasi viib. needs:artifacts laadib zip-faili alla Linuxi töösse, mis laadib selle üles ja ootab tulemusi.
stages: [build, qa]
workflow:
rules:
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_COMMIT_REF_PROTECTED == "true"'
- when: never
build_ios:
stage: build
tags: [macos]
script:
- |
set -euo pipefail
xcodebuild \
-project ios/MyApp.xcodeproj \
-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 "$CI_PROJECT_DIR/.build/MyApp.app.zip" MyApp.app)
artifacts:
paths:
- .build/MyApp.app.zip
expire_in: 1 day
autonomy_ios:
stage: qa
tags: [saas-linux-small-amd64]
image: debian:stable-slim
timeout: 30m
needs:
- job: build_ios
artifacts: true
before_script:
- apt-get update && apt-get install -y --no-install-recommends bash curl jq ca-certificates
script:
- |
export AUTONOMY_TEST_PLAN_ID="$AUTONOMY_IOS_TEST_PLAN_ID"
export APP_IDENTIFIER="$AUTONOMY_IOS_BUNDLE_ID"
export ARTIFACT_PATH=".build/MyApp.app.zip"
export AUTONOMY_REQUEST_ID="gitlab:$CI_PROJECT_ID:$CI_JOB_ID"
export AUTONOMY_BRANCH="$CI_COMMIT_REF_NAME"
export AUTONOMY_COMMIT_SHA="$CI_COMMIT_SHA"
bash .ci/autonomy.sh iosAndroid
Registreeri eraldi, kaitstud Linuxi runner, millel on silt android-linux ja Bashi shell executor. Lülita selle runneri jaoks välja Run untagged jobs ja ära anna talle Linuxi konteinerirunneri silti. Paigalda sellesse masinasse JDK, mida su projekt vajab, Androidi käsureatööriistad, sinu compile SDK ja build-tools'i versioonid, Bash, jq, curl 7.76 või uuem ning usaldusväärsed CA-sertifikaadid. Sea ANDROID_HOME, nõustu SDK litsentsidega ja lisa commit'i käivitatav android/gradlew koos selle wrapper-failidega. Shell executor kasutab hosti tööriistu; see ei paigalda sinu eest Androidi SDK-d.
See näide ehitab mooduli app silumis-APK ja laadib selle samas töös üles. Kui kasutad flavor'eid või teist moodulit, muuda Gradle'i ülesannet ja ARTIFACT_PATH väärtust koos. Sobib ka .aab.
stages: [qa]
workflow:
rules:
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_COMMIT_REF_PROTECTED == "true"'
- when: never
autonomy_android:
stage: qa
tags: [android-linux]
timeout: 60m
script:
- |
set -euo pipefail
(cd android && ./gradlew --no-daemon assembleDebug)
export AUTONOMY_TEST_PLAN_ID="$AUTONOMY_ANDROID_TEST_PLAN_ID"
export APP_IDENTIFIER="$AUTONOMY_ANDROID_PACKAGE_NAME"
export ARTIFACT_PATH="android/app/build/outputs/apk/debug/app-debug.apk"
export AUTONOMY_REQUEST_ID="gitlab:$CI_PROJECT_ID:$CI_JOB_ID"
export AUTONOMY_BRANCH="$CI_COMMIT_REF_NAME"
export AUTONOMY_COMMIT_SHA="$CI_COMMIT_SHA"
bash .ci/autonomy.sh androidPipeline'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.
Hoia Autonomy töödel allow_failure välja lülitatuna.
Harude ja sündmuste strateegia
Need konfiguratsioonid lubavad push'e, ajakavasid ja käsitsi alustatud pipeline'e ainult kaitstud vaikeharul. Merge request'i pipeline'id ja forkide kood võtit ei saa. Hoia tavaliste juurutuste puhul lühikesi suitsutesti plaane; väljalaskekontrollideks kasuta ajakava või käsitsi pipeline'i laiema plaaniga.
Merge request'i eelvaate kontrollimiseks käivita usaldusväärne vaikeharu konfiguratsioon käsitsi, andes sellele üle vaadatud eelvaate URL-i. Ära anna ebausaldusväärsele merge request'i koodile juurdepääsu kaitstud muutujatele. Kui laiendad harureegleid, kaitse need harud ja vaata enne üle nende pipeline'i muudatused.
Teenusepakkuja viited
- GitLab CI/CD YAML-i viide: etapid, töövoo reeglid, runnerite sildid, ajalimiidid ja
needs. - CI/CD muutujad: muutujate väärtused, maskeerimine ja kaitstud harud.
- Tööde artefaktid ja dotenv-aruanded: zip-faili või URL-i edasiandmine tööde vahel.
- Eeldefineeritud muutujad: tööde ID-d, harude nimed ja commit'ide SHA-d.
- Majutatud Linuxi runnerid: silt
saas-linux-small-amd64ja konteinerites käivitamine. - Majutatud macOS-i runnerid ja shell executor: runnerite saadavus ja hosti eeltingimused.
Ei leidnud?