Sjekkpunkt 2 · Azure

Lab 2: Til skyen

Agenten din er deployet, og kurslederen har koblet webhooken. Nå merker du en issue og ser at Azure-jobben leverer en pull request, uten at laptopen din er med. Merket du en issue før lunsj, hopper du rett til steg 4.

MålEn issue starter en jobb fra null i Azure.
ArbeidsstedKursets felles ressursgruppe og ACR, med din egen agent-identitet.
Ferdig nårEn merket issue gir en PR opprettet av Azure-jobben.

Før du starter

Lab 2 bygger på det du gjorde før lunsj. Kryss av dette:

Bruk pwshKommandoene er skrevet for pwsh. Står du i zsh eller bash på Mac eller Linux, skriver du pwsh først. Mangler du den på Mac: brew install --cask powershell. Copy-Item, $Variabel = ... og curl.exe virker bare i pwsh. dotnet, git og gh virker overalt.
Første virkelige kjøringLab 1 var lokal og skrivebeskyttet. Ikke opprett PR, skriv kommentar eller tildel issue manuelt. Nå er det Azure-workeren som tildeler issue, skriver kommentarer og oppretter PR.

Dette kjører i Azure

Receiver

En Container App som validerer webhook-signaturen og legger en melding i Storage Queue. Under kurset har den minReplicas: 1, så GitHub ikke venter på kaldstart. GitHub gir opp etter 10 sekunder.

Queue

Storage Queue holder oppgaven til KEDA ser meldingen og starter en worker-kjøring.

Worker

En Container Apps Job som skalerer til null. Den kloner repoet, kjører claude -p, bygger, tester og åpner PR.

Konfigurasjon

GitHub Actions logget inn med AZURE_CREDENTIALS og sendte GH_TOKEN, ANTHROPIC_API_KEY og WEBHOOK_SECRET secure til deployen.

Viktig skilleIssuen og PR-en bor i fellesrepoet. Receiver, worker og kø ligger i kursets felles ressursgruppe, med unike navn avledet fra AGENT_NAME. Container Registryet er felles for kurset, men bildene ligger under mini-nils/kari/, slik at deltakerne ikke overskriver hverandre. Receiver og worker godtar bare TARGET_REPO, som er novanet/workshop.oslo-live.
GitHub-innstillingNavnBruk
Repository variableAGENT_NAMEAgentnavnet, for eksempel kari. Gir etikett, Azure-navn og ACR-namespace.
Repository secretAZURE_CREDENTIALSContributor på den delte ressursgruppen. Bare i GitHub Actions.
Repository secretGH_TOKENDitt klassiske token med public_repo.
Repository secretANTHROPIC_API_KEYKursets felles Anthropic-nøkkel.
Repository secretWEBHOOK_SECRETSamme verdi som webhooken er registrert med.

Dette satte du i Lab 1, og det er hele listen.

Hva er Actions Summary og KEDA?

Les Actions Summary

Åpne den ferdige workflow-kjøringen og velg Summary. Der finner du Receiver URL, Issue label og Worker job. .deploy-outputs.json ligger bare på den midlertidige Actions-runneren og skal ikke forventes lokalt.

$ReceiverUrl = 'https://ca-...azurecontainerapps.io'

Kopier adressen fra sammendraget inn i terminalen.

KEDA starter jobben

KEDA betyr Kubernetes Event-driven Autoscaling. Azure Container Apps bruker KEDA til å følge med på antall meldinger i Storage Queue og starte Container Apps Job når køen ikke er tom.

Jobben står normalt på null kjøringer. KEDA sjekker køen hvert 30. sekund, starter en kjøring når den finner en melding, og workeren henter én melding før den avslutter. Derfor er en liten forsinkelse normalt, og det finnes ingen worker som står og kjører hele tiden.

Følg verdiene i BicepminExecutions: 0 gir scale-to-zero, maxExecutions: 3 begrenser hvor mange kjøringer skalaen kan starte, og pollingInterval: 30 bestemmer hvor ofte KEDA sjekker køen. KEDA er ikke selve workeren; den er mekanismen som starter den.

Fra issue til PR i fem trinn

1

Mottaket

Sjekk at receiveren svarer

$ReceiverUrl = 'https://ca-...azurecontainerapps.io'
Invoke-RestMethod "$ReceiverUrl/"

Forvent: Mini-Nils receiver. Listening for the «kari» label. curl.exe "$ReceiverUrl/" gir det samme.

2

Trigger

Merk en issue med etiketten din

Åpne GitHub Issues og velg en av Feil 2 til 5 som ingen har tatt ennå. Sett etiketten fra Summary på den, i nettleseren eller slik:

gh issue edit 3 --repo novanet/workshop.oslo-live --add-label kari

Bytt 3 med issuen du valgte. Receiveren mottar alle hendelser, men sender bare dine videre. Ikke tildel issuen, skriv startkommentar eller opprett PR selv.

3

Mens du venter

Velg Lab 3-spor og test 401

En kjøring tar typisk 10 til 20 minutter. Velg Lab 3-spor og gjør endringen lokalt, men ikke push før jobben din er ferdig. Test så at mottaket avviser feil hemmelighet:

$Body = '{"repo":"novanet/workshop.oslo-live","issueNumber":2}'
curl.exe -i -X POST "$ReceiverUrl/tasks" -H "X-Webhook-Secret: deliberately-wrong" -H "Content-Type: application/json" --data-raw $Body

Forvent 401 Unauthorized. Dette starter ingen jobb. Finn kontrollen i src/Receiver/Program.cs. /tasks krever hemmeligheten i en header, og webhooken fra GitHub er signert med HMAC. Selve kømeldingen er ikke signert, så mottaket er porten.

4

Følg jobben

Les issue-kommentarene

gh issue view 3 --repo novanet/workshop.oslo-live --comments

KEDA sjekker køen hvert 30. sekund, så litt venting er normalt. Først kommer startkommentaren fra agenten, så sluttkommentaren med PR-adresse og forbrukstabell. Lukk laptopen mens jobben kjører. PR-en skal komme fra workeren i Azure, ikke fra terminalen din.

Worker-loggen i Azure kan kurslederen vise. Ved feilsøking kan kurslederen midlertidig sette CLAUDE_VERBOSE=true i env:-blokken øverst i .github/workflows/deploy-azure.yml før en ny kjøring. Sett verdien tilbake etterpå.

5

Pull request · sjekkpunkt

Les PR-en

gh pr list --repo novanet/workshop.oslo-live --author "@me"

Åpne PR-en og les rapporten og forbrukstabellen. Agenten merger ikke selv; PR-en venter på review fra et menneske. Var bygget rødt, er PR-en et utkast.

Sjekkpunkt 2En merket issue gir en pull request opprettet av Azure-jobben.
6

Sensor · ny runde

Når Sensor sier nei

Sensor leser PR-en mot akseptansekriteriene i issuen og kjører de skjulte testene. Mangler noe, får PR-en Request changes med en tabell over hva som feiler.

Agenten din leser ikke reviewen. Den kjører én gang per etikett og står stille etterpå. Neste trekk er ditt:

  1. Les tabellen. Hva bommet agenten på?
  2. Fiks agenten, ikke koden i PR-en. Stram inn en prompt i agent/prompts/, agent/conventions.md eller en skill. Commit, push og vent til deployen er grønn.
  3. Ta etiketten av og sett den på igjen:
gh issue edit 3 --repo novanet/workshop.oslo-live --remove-label kari
gh issue edit 3 --repo novanet/workshop.oslo-live --add-label kari

Agenten starter fra main igjen, pusher til samme branch og oppdaterer PR-en du allerede har. Sensor vurderer den nye commiten.

Agenten ser bare issuen og hukommelsen sin, ikke det Sensor skrev. Endrer du ikke agenten, gjør den trolig samme feil en gang til. Vil du at den skal lese reviewen sjøl, er det en oppgave i Spor G i Lab 3. Sier Sensor at issuen allerede er løst av en annen PR, er det ingen vits å kjøre på nytt. Velg en ny issue.

Se kostnaden i Log Analytics

Kurslederen kan vise dette i Azure-portalen. Workeren skriver en LLM request completed-linje for hver modellkjøring, med de samme tallene som står i forbrukstabellen i PR-en. Status summerer fra en skjult sluttmarkør som hver kjøring skriver på issuen.

ContainerAppConsoleLogs_CL
| where ContainerName_s == "worker"
| where Log_s contains "LLM request completed"
| project TimeGenerated, Log_s
| order by TimeGenerated desc

cost_usd er Claude Codes egen utregning. Står det cost_estimated=true, har workeren regnet ut kostnaden selv fra tokens og listepris, fordi steget ble stoppet av tidsgrensen eller Claude Code ikke hadde pris for modellen. I forbrukstabellen i PR-en vises slike beløp med ~.

Hvis du blir tidlig ferdig

Gjør én liten endring i infra/main.bicep som krever ny deploy.

Du ber KEDA sjekke køen oftere. Du endrer ikke hvordan workeren behandler meldingen.

Finn også i infra/main.bicep hvor KEDA-regelen står, hvor repository secrets blir til jobbens miljøvariabler, og hvorfor mottaket har minReplicas: 1 under kurset.

Hvis noe stopper

Webhooken når ikke fram

Ikke legg WEBHOOK_SECRET i terminalhistorikk eller del den i en issue. Be kurslederen kontrollere Recent deliveries og redelivere webhooken med kurslederens oppsett.

Deploy feiler på rettigheter

Kontroller at AZURE_CREDENTIALS finnes som repository secret og at AGENT_NAME er satt. Hvis feilen fortsetter, må kurslederen rette service-principalens roller.

Jobben feiler med en gang

Be kurslederen hente worker-loggen. Manglende miljøvariabler ligger vanligvis under env: i infra/main.bicep.

Når PR-en ikke blir merget

Sensor vurderer hver ny commit på PR-en. Går alt gjennom, godkjenner den og slår på auto-merge. Blir PR-en stående, er det en av disse grunnene.

Sensor ba om endringer

Sensor sjekker bygg og test, den skjulte testen for issuen og akseptansekriteriene. Reviewen viser PASS, FAIL eller USIKKER per kriterium. Det er lista du jobber etter.

Rett det selv. Du har skrivetilgang til agentens branch:

gh repo clone novanet/workshop.oslo-live
Set-Location workshop.oslo-live
gh pr checkout <pr-nummer>

Gjør endringen, kjør dotnet build og dotnet test, og push:

git commit -am "Rett etter Sensor"
git push

Sensor vurderer den nye commiten i neste runde.

Eller gjør agenten bedre og kjør på nytt. Endre prompt, konvensjoner eller modell i ditt eget repo og push, så deployen går. Fjern og sett etiketten igjen. Agenten starter fra main og ser ikke Sensors review av seg selv. Lab 3, spor G, viser hvordan du kan gi den reviewen. Den nye kostnaden legges til på samme PR.

Står det at issuen allerede er løst av en annen PR, har noen andre vunnet den. Lukk PR-en og velg en ny issue.

PR-en har konflikt

GitHub viser This branch has conflicts når noen andre har endret de samme linjene og blitt merget først. Auto-merge venter da for alltid.

Sensor prøver først selv. Er konflikten bare at to PR-er har lagt til hver sin linje i Program.cs eller i en testfil, slår Sensor sammen main, beholder begge linjene, kjører bygg og test og pusher. Da får du en kommentar om det. Gjør du det under bare når Sensor skriver at den ikke kunne løse konflikten.

Enklest: kjør agenten på nytt. Den kloner siste main, lager branchen på nytt og oppdaterer den samme PR-en:

gh issue edit <issue-nummer> --repo novanet/workshop.oslo-live --remove-label kari
gh issue edit <issue-nummer> --repo novanet/workshop.oslo-live --add-label kari

Eller løs den selv i branchen:

gh pr checkout <pr-nummer>
git merge origin/main

Rett konfliktene, kjør dotnet build og dotnet test, og så git commit og git push. Sensor vurderer den nye commiten.

Behold miljøet til Lab 3

Lab 3 bygger videre på denne deployen og bruker samme Container Apps Job, Storage Queue, webhook og Azure-logger. Gjør endringer i agenten lokalt, push dem, og deployen kjører fra Actions.

Ikke slett noeRessursgruppen er delt av hele kurset. Ikke slett noe. Kurslederen rydder etter kurset.