Opprette en egendefinert GitHub-handling
GitHub Actions er en kraftig funksjon som hjelper deg med å gå fra kode til sky, alt fra komfort og bekvemmelighet for ditt eget repositorium. Her lærer du om de ulike typene GitHub-handlinger og metadata-, syntaks- og arbeidsflytkommandoene for å opprette egendefinerte GitHub-handlinger.
Typer GitHub-handlinger
Handlinger er individuelle oppgaver som du kan bruke til å tilpasse utviklingsarbeidsflytene. Du kan opprette dine egne handlinger ved å skrive egendefinert kode som samhandler med repositoriet for å utføre egendefinerte oppgaver, eller ved hjelp av handlinger gitHub-fellesskapet deler. Når du navigerer gjennom ulike handlinger, ser du at det finnes tre ulike typer handlinger: Docker-beholderhandlinger, JavaScript-handlingerog handlinger for sammensatte kjøringstrinn. La oss ta en nærmere titt på hver handlingstype.
Docker-beholderhandlinger
Docker-beholdere pakker miljøet med GitHub-handlingskoden. Dette betyr at handlingen kjører i et konsekvent og pålitelig miljø fordi alle avhengighetene er innenfor denne beholderen. Hvis handlingen må kjøres i en bestemt miljøkonfigurasjon, er Docker-beholdere en god måte å gå på, fordi du kan tilpasse operativsystemet og verktøyene. Ulempen er at fordi jobben må bygge og hente beholderen, er Docker-beholderhandlinger ofte tregere enn JavaScript-handlinger.
Før du bygger en Docker-beholderhandling, bør du ha en grunnleggende forståelse av hvordan du bruker miljøvariabler og Docker-beholderfilsystemet. Trinnene for å bygge en Docker-beholderhandling er da minimal og grei:
- Opprett en
Dockerfilefor å definere kommandoene for å sette sammen Docker-bildet. - Opprett en
action.ymlmetadatafil for å definere inndata og utdata for handlingen. Angiruns: using:-verdien tildockerogruns: image:-verdien for åDockerfilei filen. - Opprett en
entrypoint.shfil for å beskrive docker-bildet. - Utfør og skyv handlingen til GitHub med følgende filer:
action.yml,entrypoint.sh,DockerfileogREADME.md.
JavaScript-handlinger
JavaScript-handlinger kan kjøre direkte på løpermaskinen og skille handlingskoden fra miljøet som brukes til å kjøre handlingen. På grunn av dette er handlingskoden forenklet og kan kjøre raskere enn handlinger i en Docker-beholder.
Som en forutsetning for å opprette og bruke pakkede JavaScript-handlinger, må du laste ned Node.js, som inkluderer npm. Som et valgfritt trinn (men ett som vi anbefaler) er å bruke GitHub Actions Toolkit Node.js, som er en samling av Node.js pakker som lar deg raskt bygge JavaScript-handlinger med mer konsekvens.
Trinnene for å bygge en JavaScript-handling er minimal og enkel:
- Opprett en
action.ymlmetadatafil for å definere inndata og utdata for handlingen, samt fortell handlingsløperen hvordan du begynner å kjøre denne JavaScript-handlingen. - Opprett en
index.jsfil med kontekstinformasjon om Verktøysett-pakker, ruting og andre funksjoner i handlingen. - Utfør og send handlingen til GitHub med følgende filer:
action.yml,index.js,node_modules,package.json,package-lock.jsonogREADME.md.
Handlinger for sammensatte kjøringstrinn
Handlinger for sammensatte kjøringstrinn lar deg bruke handlinger på nytt ved hjelp av skallskript. Du kan til og med blande flere skallspråk i samme handling. Hvis du har mange skallskript for å automatisere flere oppgaver, kan du nå enkelt gjøre dem om til en handling og bruke dem på nytt for ulike arbeidsflyter. Noen ganger er det enklere å skrive et skallskript enn å bruke JavaScript eller bryte koden i en Docker-beholder.
Pakket sammensatt handling
Pakkede sammensatte handlinger samler flere trinn i en gjenbrukbar enhet. Disse handlingene er definert i et repositorium og kan refereres i arbeidsflyter på tvers av ulike repositorier. Pakking av en sammensatt handling forenkler arbeidsflyter, reduserer duplisering og forbedrer vedlikeholdsevnen.
Når du oppretter en pakket sammensatt handling, defineres trinnene i én enkelt action.yml fil. Denne filen angir inndata, utdata og sekvensen av kommandoer eller handlinger som skal utføres. Pakkede sammensatte handlinger er spesielt nyttige for å automatisere gjentakende oppgaver eller kombinere flere skallkommandoer til én enkelt gjenbrukbar handling.
Opprette en sammensatt qction
1. Konfigurere en katalog for den sammensatte handlingen
Du må plassere den sammensatte handlingen i sin egen katalog i repositoriet.
Eksempel på katalogstruktur:
.github/actions/my-composite-action/
├── action.yml
└── scripts/
└── my-script.sh
2. Definer action.yml filen
Opprett en fil i action.yml.
name: "My Composite Action"
description: "A reusable composite action that checks out code and sets up Node.js"
inputs:
node-version:
description: "The Node.js version to use"
required: true
runs:
using: "composite"
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node-version }}
Notat: Feltet «sammensatt» angir at denne handlingen er en sammensatt handling.
3. Bruk den sammensatte handlingen i en arbeidsflyt
Når den sammensatte handlingen er opprettet, kan den refereres til i en Arbeidsflyt for GitHub-handlinger.
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Use my composite action
uses: ./.github/actions/my-composite-action
with:
node-version: '18'
Hvis den sammensatte handlingen deles fra et annet repositorium, kan du referere den slik:
uses: owner/repository/.github/actions/my-composite-action@v1
Legge til utdata i en sammensatt handling
Sammensatte handlinger kan definere utdata som arbeidsflyter kan bruke til å sende data mellom trinn eller jobber. Utdata er spesielt nyttige for deling av resultater eller beregnede verdier fra én handling til en annen.
Følgende eksempel viser hvordan du definerer og bruker utdata i en sammensatt handling:
Definer et utdata i action.yml
Filen action.yml angir et utdata med navnet script-result. Denne utdataene henter verdien fra result utdataene for run-script trinnet. Trinnet run-script kjører en Bash-kommando for å angi utdataverdien.
outputs:
script-result:
description: "Result from the script"
value: ${{ steps.run-script.outputs.result }}
runs:
using: "composite"
steps:
- id: run-script
run: echo "result=Success" >> $GITHUB_OUTPUT
shell: bash
Bruke utdataene i en arbeidsflyt
Når den sammensatte handlingen er opprettet, kan utdataene åpnes i en arbeidsflyt. Her er et eksempel:
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Run composite action
id: my-action
uses: ./.github/actions/my-composite-action
- name: Display result
run: echo "Script Result: ${{ steps.my-action.outputs.script-result }}"
I dette eksemplet:
- Den sammensatte handlingen aktiveres ved hjelp av
usesnøkkelordet. - Få tilgang til utdataene
script-resultved hjelp av syntaksensteps.<step-id>.outputs.<output-name>. - Vis resultatet i arbeidsflytloggene.
Definer utdata i sammensatte handlinger for å opprette gjenbrukbare og modulære arbeidsflyter. Denne fremgangsmåten forenkler datadeling og forbedrer vedlikeholdbarheten.
Anbefalte fremgangsmåter for sammensatte handlinger
| Anbefalt fremgangsmåte | Beskrivelse |
|---|---|
| Bruk versjonskontroll | Bruk en v1 kode til å referere til stabil versjon 1. |
| Behold handlinger modulær | Grupper relaterte trinn i en sammensatt handling. |
| Dokumentinndata og utdata | Legg til beskrivelser for inndata/utdata i action.yml. |
| Test før publisering | Valider den sammensatte handlingen i et testrepositorium. |
Sammensatt handling i en arbeidsflyt
Sammensatte handlinger er en effektiv måte å forenkle arbeidsflyter på ved å samle flere trinn i en gjenbrukbar enhet. Disse handlingene lar deg definere en sekvens med kommandoer eller handlinger i én enkelt action.yml fil, noe som gjør det enklere å vedlikeholde og gjenbruke logikk på tvers av arbeidsflyter.
Fordeler med sammensatte handlinger:
- Gjenbruk - Definer handlinger én gang og bruk dem i flere arbeidsflyter.
- Vedlikeholdsevne – Reduser duplisering ved å sentralisere logikk i én enkelt handling.
- Modularitet – Kombiner flere skallkommandoer eller andre handlinger til én enkelt enhet.
Utvikle en handling for å konfigurere en CLI på GitHub Actions-løpere
Mange CI/CD-arbeidsflyter krever en bestemt versjon av et CLI-verktøy for å samhandle med skytjenester, administrere infrastruktur eller kjøre skript. Selv om GitHub-vertsbaserte løpere er forhåndsinstallert med mange verktøy, kan det hende at de ikke inkluderer den nøyaktige versjonen arbeidsflyten trenger, spesielt hvis det er en eldre eller ikke støttet versjon. I stedet for å installere den nødvendige CLI-versjonen i hver arbeidsflyt, kan du opprette en gjenbrukbar GitHub-handling som:
- Sikrer konsekvent installasjon av den nødvendige CLI-versjonen på tvers av jobber.
- Forenkler arbeidsflyter ved å sentralisere installasjonslogikken.
- Optimaliserer hurtigbufring for raskere kjøring av arbeidsflyt.
Slik utvikler du en cli-konfigurasjonshandling
En CLI-konfigurasjonshandling er en JavaScript-basert handling som installerer og konfigurerer en CLI på en GitHub-løper.
Fremgangsmåte for å opprette handlingen:
Trinn 1: Konfigurere handlingskatalogen
Følg disse trinnene for å opprette katalogen manuelt for cli-konfigurasjonshandlingen:
- Gå til repositoriet
Opprette en ny katalog for handlingen
Opprett en ny katalog med navnetmy-cli-actioni.github/actionsmappen. Dette sikrer at handlingen er organisert og følger GitHubs anbefalte struktur for egendefinerte handlinger.Gå til den nye katalogen
Endre til den nylig opprettede katalogen for å begynne å legge til filer for handlingen:Bekreft katalogstrukturen
Når du har opprettet katalogen, skal repositoriumstrukturen se slik ut:
your-repository/
├── .github/
│ ├── actions/
│ │ ├── my-cli-action/
Du er nå klar til å fortsette med å opprette action.yml filen og andre nødvendige filer for cli-konfigurasjonshandlingen.
Trinn 2: Definer action.yml metadatafilen
Opprett en action.yml fil for å beskrive handlingen.
name: "Setup MyCLI"
description: "Installs MyCLI and adds it to the PATH"
author: "Your Name"
inputs:
version:
description: "The CLI version to install"
required: false
default: "latest"
runs:
using: "node16"
main: "index.js"
Hvorfor bruke : node16? Denne handlingen kjører JavaScript-kode ved hjelp av Node.js 16.
Trinn 3: Opprette et JavaScript-skript for å installere CLI
Opprett en fil med navnet index.js i samme katalog, og legg til følgende kode:
const core = require('@actions/core');
const { execSync } = require('child_process');
async function run() {
try {
const version = core.getInput('version') || 'latest';
console.log(`Installing MyCLI version: ${version}...`);
execSync(`curl -fsSL https://cli.example.com/install.sh | sh`, { stdio: 'inherit' });
console.log("MyCLI installed successfully.");
} catch (error) {
core.setFailed(`Installation failed: ${error.message}`);
}
}
run();
JavaScript-koden ovenfor bruker core.getInput() til å hente CLI-versjonen som er angitt som inndata. Den utfører deretter en curl-kommando for å laste ned og installere CLI. Hvis installasjonsprosessen mislykkes, bruker handlingen core.setFailed() til å markere arbeidsflyten som mislykket.
Trinn 4: Teste handlingen lokalt
Før du bruker handlingen i en arbeidsflyt, må du teste den på en GitHub-vert.
Opprett en arbeidsflytfil (GITHUB/arbeidsflyter/test.yml) i repositoriet:
name: Test MyCLI Setup
on:
push:
branches:
- main
- feature/*
1. Utløser arbeidsflyten
Arbeidsflyten utløses ved push-enheter til hovedgrenen og en hvilken som helst gren som samsvarer med funksjon/*-mønsteret. Du kan justere dette slik at det samsvarer med repositoriets forgreningsstrategi.
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
2. Klon repositoriet
Handlingen handlinger/checkout@v4 brukes til å klone repositoriet til løperen. Dette sikrer at arbeidsflyten har tilgang til repositoriets filer.
- name: Install MyCLI
uses: ./.github/actions/my-cli-action
with:
version: '1.2.3'
3. Kjør den egendefinerte handlingen
Bruksområdene: ./.github/actions/my-cli-action line refererer til den egendefinerte handlingen lokalt. Kontroller at handlingskatalogen og action.yml filen er riktig konfigurert. Versjonsinndataene angir CLI-versjonen som skal installeres– i dette tilfellet versjon 1.2.3.
- name: Verify CLI Installation
run: |
echo "Checking MyCLI version..."
mycli --version
4. Kontroller CLI-installasjonen
Dette trinnet kjører en skallkommando for å bekrefte at CLI ble installert. Den kontrollerer versjonen av den installerte CLI ved å kjøre mycli --version.
Test lokalt
Hvis du vil teste denne arbeidsflyten lokalt, bruker du CLI-verktøyet act :
act -j test
Dette simulerer GitHub Actions-miljøet på den lokale maskinen, slik at du kan feilsøke og validere arbeidsflyten før du skyver endringer.
Optimaliseringstips: Hurtigbufring
Hvis du vil forbedre arbeidsflytytelsen, bufrer du CLI-installasjonskatalogen actions/cache ved hjelp av handlingen:
- name: Cache MyCLI
uses: actions/cache@v4
with:
path: ~/.mycli
key: mycli-${{ runner.os }}-${{ inputs.version }}
Dette sikrer at etterfølgende kjøringer bruker den hurtigbufrede CLI-installasjonen på nytt, noe som reduserer installasjonstiden.
Anbefalte fremgangsmåter for cli-konfigurasjonshandlinger
| Anbefalte fremgangsmåter | Beskrivelse |
|---|---|
| Bruk versjonskontroll | Tillat brukere å angi en CLI-versjon via inputs.version. |
| Håndtere feil på riktig måte | Brukes core.setFailed() til å avslutte feil. |
| Cache CLI-installasjon | Optimaliser arbeidsflytytelse ved hjelp av actions/cache. |
| Gi dokumentasjon | Forklar bruk og inndata i README.md. |
Feilsøke JavaScript-handlinger
Når du arbeider med JavaScript-baserte GitHub-handlinger, kan det hende du støter på uventet atferd, feil eller feil under kjøring av arbeidsflyt. Denne enheten inneholder teknikker og verktøy som hjelper deg med å identifisere og løse problemer i JavaScript-handlingene.
Vanlige feilsøkingsscenarioer
| Problem | Mulig årsak | Foreslått løsning |
|---|---|---|
| Handlingen mislykkes med en stakksporing | Syntaks eller kjøretidsfeil i index.js |
Bruke console.log() og kontrollere logger |
Inndata er undefined |
Feil inndatanavn eller manglende inndata | Kontroller action.yml og hvordan inndata sendes |
| Miljøvariabler er ikke angitt |
core.exportVariable eller process.env ikke brukt riktig |
Se gjennom kodeinnstillingen for variablene |
| Finner ikke filen | Manglende relative baner | Bruke __dirname eller fullstendige baner til filer |
| Hurtigbufferen er ikke gjenopprettet | Feil key eller path verdier |
Kontroller hurtigbufferkonfigurasjon og -nøkler |
Bruke Logging for feilsøking
Logg meldinger med core.info, core.debugog console.log
const core = require('@actions/core');
core.info("This is an info message");
core.debug("This is a debug message");
console.log("This is a raw console log");
✅ Bruk core.debug for feilsøkingslogger – disse vises bare når ACTIONS_STEP_DEBUG er satt til sann.
Aktiver feilsøkingslogging
Du kan aktivere feilsøkingslogger på trinnnivå ved å angi følgende hemmelighet:
ACTIONS_STEP_DEBUG=true
Hvis du vil aktivere diagnoselogger for løper, angir du:
ACTIONS_RUNNER_DEBUG=true
Angi hemmeligheter for feilsøking
- Gå til GitHub-repositoriet.
- Gå til Innstillinger>Hemmeligheter og variabler>Handlinger.
- Legg til nye hemmeligheter med følgende navn og verdier:
-
ACTIONS_STEP_DEBUG:
true -
ACTIONS_RUNNER_DEBUG:
true
-
ACTIONS_STEP_DEBUG:
Undersøk arbeidsflytlogger
Når en arbeidsflyt mislykkes, klikker du på den mislykkede jobben på Handlinger-fanen. Utvid hvert trinn til:
- Vis detaljerte logger
- Kontroller standardutdata (stdout)
- Se avslutningskoden for skript
- Identifisere ubehandlede unntak
🔍 Eksempelloggutdata
Error: Cannot find module '@actions/core'
Require stack:
- /home/runner/work/_actions/my-org/my-action/index.js
✅ Løsning: Kjør npm installer @actions/core og utfør node_modules (eller bruk blindkopi til å samle handlingen).
Test handlingen lokalt
Bruk handling – et CLI-verktøy for å kjøre GitHub-handlinger lokalt. Eksempel:
act -j test
🛠 Pass på å simulere GitHub-miljøet riktig når du tester lokalt.
Håndtere feil på en grasiøs måte
Fange unntak og mislykkes med nyttige meldinger:
try {
// your logic
} catch (error) {
core.setFailed(`Action failed with error: ${error.message}`);
}
🔁 Dette sikrer at GitHub stopper arbeidsflyten ved feil og gir lesbare logger.
Anbefalte fremgangsmåter for feilsøking av JavaScript-handlinger
| Praksis | Beskrivelse |
|---|---|
| Bruk core.debug() | Skjul detaljerte logger med mindre feilsøking er aktivert. |
| Valider action.yml | Sørg for at inndata og utdata er riktig definert. |
| Pakkekode | Brukes @vercel/ncc til å kompilere JavaScript til én enkelt fil. Dette reduserer avhengigheter og sikrer at alle nødvendige moduler er inkludert, og forhindrer kjøretidsfeil forårsaket av manglende filer. |
| Test med handling | Simuler kjøringer lokalt for raskere gjentakelser. |
| Bruk prøv/fange | Hindre arbeidsflyter i å mislykkes i stillhet. |
Feilsøke Docker-beholderhandlinger
Docker-beholderhandlinger er kraftige for å innkapsle komplekse verktøy og miljøer i Arbeidsflyter for GitHub-handlinger. Feilsøking av disse handlingene kan imidlertid være mer utfordrende enn JavaScript-handlinger på grunn av deres isolerte kjøretidsmiljø. Denne enheten veileder deg gjennom identifisering, diagnostisering og løsning av problemer med Docker-baserte handlinger.
Vanlige problemer i Docker-beholderhandlinger
| Problem | Årsak | Foreslått løsning |
|---|---|---|
| Handlingen starter ikke |
ENTRYPOINT eller CMD feilkonfigurert |
Bekreft at Dockerfile bruker ENTRYPOINT riktig |
| Manglende avhengigheter | Avhengigheter som ikke er installert eller feilkonfigurert | Sørg for at alle pakker er installert i bildet |
| Inndata ikke mottatt |
INPUT_ tilgang til miljøvariabler |
Bruk process.env.INPUT_<INPUT_NAME> (eller skallekvivalent) |
| Finner ikke filen | Feil filbane i beholderen | Bruk absolutte baner eller valider katalogstruktur |
| Ingen tillatelse | Fil eller skript mangler kjøringstillatelse | Legg til RUN chmod +x <script> i Dockerfile |
| Nettverksrelaterte feil | Eksterne tjenester er ikke tilgjengelige | Valider nettverksinnstillinger og prøv logikk på nytt |
Forstå livssyklusen til Docker-handlingen
Før feilsøking er det nyttig å forstå hvordan Docker-beholderhandlinger kjører.
1. Arbeidsflytutløser
En Arbeidsflyt for GitHub-handlinger starter som svar på en konfigurert hendelse , for eksempel en , pusheller en pull_requestmanuell workflow_dispatch.
2. Løperoppsett
GitHub klargjør en ny virtuell maskin ( løperen) for å utføre arbeidsflyten. Løperen forbereder miljøet ved å laste ned handlingsdefinisjoner og løse avhengigheter.
3. Handlingsoppløsning
Hvis handlingen angir runs.using: docker i action.yml filen, gjenkjenner GitHub den som en Docker-basert handling.
4. Bildebygg eller pull
GitHub bygger Docker-bildet som er definert i handlingen, Dockerfile eller henter et forhåndsbygd bilde hvis det er angitt. Dette bildet definerer miljøet der handlingskoden kjøres.
5. Kjøring av beholder
Løperen starter Docker-beholderen, monterer arbeidsområdet og injiserer miljøvariabler, inkludert hemmeligheter og inndata definert i arbeidsflyten.
6. Inngangspunkt kjøres
GitHub utfører entrypoint kommandoen fra Dockerfile i beholderen. Det er her den egendefinerte handlingslogikken kjører, vanligvis et skript eller program.
7. Resultatbehandling
Eventuelle utdata som angis av beholderhandlingen, hentes av løperen og sendes videre til påfølgende trinn i arbeidsflyten. Når den er ferdig, stenges beholderen, og løperen kastes.
Obs! Docker-beholderhandlinger kjører i et rent, isolert miljø. Filsystemtilstand, installerte verktøy og miljøvariabler må alle defineres i Dockerfile.
Feilsøkingsteknikker
1. Legg til logging
Bruk ekko-, utskrifts- eller loggingssetninger i oppføringsskriptet:
echo "Starting Docker action..."
echo "Input VALUE: $INPUT_VALUE"
Logg alle kritiske inndata og trinn for å diagnostisere hvor feilen oppstår.
2. Bygg og test lokalt
Bruk Docker på maskinen til å simulere beholderens virkemåte:
docker build -t my-action .
docker run -e INPUT_NAME=value my-action
Sikre at miljøvariabler etterligner de GitHub-settene.
3. Bruk act CLI til å simulere GitHub-arbeidsflyter
Installer handling for å kjøre GitHub-arbeidsflytene lokalt:
act -j test-job
Flott for testing av Docker-handlinger i arbeidsflyter uten å gå til GitHub.
4. Valider Dockerfile-konfigurasjon
Kontroller at du definerer enten ENTRYPOINT eller CMD. Kopier skriptene til bildet, og gi dem kjøretillatelse:
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
5. Undersøk GitHub-logger
Klikk på en mislykket arbeidsflytkjøring, utvid hvert trinn og undersøk:
- Docker-bygglogger
- Standardutdata og standardfeil fra beholderen
- Avslutningskoder og stakksporingslogger 🔍 viser ofte manglende pakker, syntaksproblemer eller tillatelsesfeil.
Eksempel: Inngangspunktfeil
Error: container_linux.go:380: starting container process caused "exec: \"/entrypoint.sh\": permission denied"
✅ Løsning: Legg til RUN chmod +x /entrypoint.sh i Dockerfile.
Miljøvariabeltilordning
| GitHub-inndata | Docker-miljøvariabel |
|---|---|
with: name: test |
INPUT_NAME=test |
GITHUB_WORKSPACE |
Tilordnet til /github/workspace |
GITHUB_EVENT_NAME |
Hendelse som utløste arbeidsflyten |
echo "Input was $INPUT_NAME"
echo "Working dir: $GITHUB_WORKSPACE"
Bruke feilsøkingshemmeligheter
Aktiver ytterligere logging ved å legge til disse hemmelighetene i repositoriet eller organisasjonen:
| Hemmelighet | Beskrivelse |
|---|---|
ACTIONS_STEP_DEBUG |
Aktiverer feilsøkingslogging |
ACTIONS_RUNNER_DEBUG |
Aktiverer løperdiagnose |
Anbefalte fremgangsmåter for feilsøking av Docker-handling
| Anbefalt fremgangsmåte | Hvorfor |
|---|---|
| Bruk logging sjenerøst | Hjelper sporing av feilpunkter |
| Angi alltid chmod +x | Unngå tillatelsesfeil på skallskript |
| Validere inndata i skriptet | Fange manglende eller misformede inndata tidlig |
| Minimere beholderavhengigheter | Mindre bilder er enklere å feilsøke |
| Test lokalt med docker run eller act | Raskere gjentakelser og umiddelbar tilbakemelding |