Hvert GitHub Actions-workflow, du har skrevet, er en YAML-fil. Alt — triggers, job, trin, miljøvariabler, matrixstrategi — udtrykkes i YAML. Det betyder, at en dyb forståelse af YAML ikke bare er akademisk: det er forskellen mellem CI, der fungerer pålideligt, og CI, der mystisk bryder sammen kl. 16 om fredagen, når du prøver at udsende en release.

GitHub Actions har fremragende dokumentation om workflow-syntaks, men den fokuserer på Actions-funktionerne frem for YAML-mekanikken underneath. Denne artikel dækker begge dele — workflow-strukturen og de YAML-specifikke mønstre (og faldgruber), der afgør om CI-konfigurationer lykkes eller fejler.

Workflow-struktur: Nøglerne på øverste niveau

En GitHub Actions workflow-fil ligger i .github/workflows/ og har tre påkrævede nøgler på øverste niveau. Den officielle workflow-oversigt forklarer, hvor filen ligger i dit repo, og hvordan GitHub opdager den:

yaml
name: CI Pipeline          # optional but shown in the Actions UI

on:                        # triggers
  push:
    branches: [main]
  pull_request:

jobs:                      # the actual work
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci && npm test
Pas på on som YAML-boolean: I YAML 1.1 fortolkes det bare ord on som boolean true. GitHubs parser håndterer dette korrekt, men hvis du nogensinde ser din workflow-fil markeret af en generisk YAML-linter, er det grunden. Den sikre form er at citere den: "on": — dog kræver GitHub Actions selv ikke anførselstegnene.

Triggers: Nøglen on:

Nøglen on: styrer, hvornår dit workflow kører. Den fulde liste over trigger-hændelser dækker alt fra pull request-anmeldelser til repository dispatches. Her er de mest almindelige mønstre:

yaml
on:
  # Push to specific branches
  push:
    branches:
      - main
      - "release/**"       # glob pattern — quotes needed for /**
    paths-ignore:
      - "docs/**"
      - "*.md"

  # PRs targeting main
  pull_request:
    branches: [main]
    types: [opened, synchronize, reopened]

  # Scheduled (cron syntax)
  schedule:
    - cron: "0 2 * * 1"   # every Monday at 2am UTC

  # Manual trigger with input
  workflow_dispatch:
    inputs:
      environment:
        description: "Target environment"
        required: true
        default: staging
        type: choice
        options: [staging, production]

Flerlinjede run:-kommandoer og YAML-blokkede skalarer

Nøglen run: er, hvor YAMLs bogstavelige blokkede skalar (|) virkelig tjener sin ret — se referencen på yaml-multiline.info for enhver variation af blok- og foldede skalarer. Uden den ville du kæde kommandoer med && på en enkelt linje, hvilket er ulæseligt:

yaml
steps:
  # Single line — works but hard to read
  - name: Build
    run: npm ci && npm run lint && npm run test && npm run build

  # Multi-line with literal block scalar — much better
  - name: Build
    run: |
      npm ci
      npm run lint
      npm run test -- --coverage
      npm run build

  # Folded scalar (>) joins lines with spaces — NOT what you want for shell
  # This would run as a single command with spaces where the newlines are:
  - name: Wrong for shell
    run: >
      npm ci
      npm test
Brug altid | til flerlinjede shell-scripts, aldrig >. Den foldede skalar folder linjeskift til mellemrum, hvilket betyder, at dine shell-kommandoer samles til én lang streng. Det forårsager kryptiske fejl. Den bogstavelige blokskalar | bevarer linjeskift præcist, så hver linje køres som en separat shell-kommando.

Miljøvariabler og hemmeligheder

Miljøvariabler i GitHub Actions bruger YAML i kombination med Actions kontekst- og udtryksyntaks. Sådan passer de sammen:

yaml
env:
  NODE_ENV: production         # workflow-level env var
  API_VERSION: "2.1"          # quoted to force string type

jobs:
  deploy:
    runs-on: ubuntu-latest
    env:
      DEPLOY_ENV: staging      # job-level env var (overrides workflow-level)

    steps:
      - name: Deploy to staging
        env:
          API_KEY: ${{ secrets.STAGING_API_KEY }}     # step-level, from secret
          DATABASE_URL: ${{ vars.STAGING_DB_URL }}    # step-level, from variable
        run: |
          echo "Deploying to $DEPLOY_ENV"
          ./scripts/deploy.sh

Udtrykssyntaksen ${{ }} er GitHub Actions' eget skabelonsprog oven på YAML. Det evalueres før YAML-parsing i nogle kontekster, hvilket kan interagere uventet med YAMLs egne citatregler. Omgiv værdier, der starter med ${{, i dobbelte anførselstegn ved tvivl.

Matrixstrategi: Byg på tværs af flere konfigurationer

Matrixstrategien er en af GitHub Actions' mest kraftfulde funktioner — og den udtrykkes udelukkende i YAML. Den kører dit job én gang for hver kombination af matrixværdier:

yaml
jobs:
  test:
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false         # don't cancel other matrix jobs on failure
      matrix:
        os: [ubuntu-latest, windows-latest, macos-latest]
        node: ["18", "20", "22"]
        exclude:
          - os: windows-latest
            node: "18"         # skip this combination

    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node }}
      - run: npm ci && npm test

Denne enkle jobdefinition producerer op til 9 parallelle kørsler (3 OS × 3 Node-versioner, minus 1 undtaget). YAML-matrixværdierne er almindelige arrays — det eneste at se efter er, at versionsnumre som 18 bør citeres som "18" for at holde dem som strenge. Uden anførselstegn fortolker YAML dem som heltal, og nogle Actions kan klage.

Betingede trin med if:

Nøglen if: lader dig springe trin over baseret på betingelser. Den bruger GitHubs udtryks-sprog, ikke almindelige YAML-værdier:

yaml
steps:
  - name: Run tests
    run: npm test

  - name: Upload coverage
    if: success() && github.ref == 'refs/heads/main'
    uses: codecov/codecov-action@v4

  - name: Notify on failure
    if: failure()
    uses: slackapi/slack-github-action@v1
    with:
      slack-message: "Build failed on ${{ github.ref }}"
      channel-id: "C12345ABC"
    env:
      SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}

  - name: Deploy (only on tag push)
    if: startsWith(github.ref, 'refs/tags/v')
    run: ./scripts/deploy.sh production

Genbrugelige workflows

Til at eliminere duplikering på tværs af repositories (ikke bare inden for en fil) understøtter GitHub Actions genbrugelige workflows. Det kaldte workflow bruger on: workflow_call:, og den, der kalder, bruger uses: på jobniveau — ikke trinniveau:

yaml
# .github/workflows/reusable-test.yml (the reusable workflow)
on:
  workflow_call:
    inputs:
      node-version:
        required: false
        type: string
        default: "20"
    secrets:
      NPM_TOKEN:
        required: true

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ inputs.node-version }}
      - run: npm ci && npm test
        env:
          NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
yaml
# .github/workflows/ci.yml (the caller)
on: [push, pull_request]

jobs:
  run-tests:
    uses: my-org/shared-workflows/.github/workflows/reusable-test.yml@main
    with:
      node-version: "22"
    secrets:
      NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

De mest almindelige YAML-fejl i GitHub Actions

  • Forkert indrykning på trin. Trin skal indrykkes under steps: med konsistente mellemrum. Et enkelt ekstra eller manglende mellemrum flytter et trin uden for dets job.
  • Uciterede versionsnumre. node-version: 20 sender et heltal; nogle actions forventer en streng. Brug node-version: "20" for sikkerhed.
  • Brug af > i stedet for | til shell-scripts. Foldede skalarer kollapser linjeskift. Dit flerlinjede script bliver til én lang streng og fejler.
  • Manglende anførselstegn på glob-mønstre. Mønstre som release/** indeholder *, som YAML kan fortolke som et alias. Citér altid glob-mønstre.
  • Hemmeligheder brugt i if:-betingelser. GitHub maskerer hemmeligheder i logfiler, men tillader dem ikke i if:-udtryk. Brug en miljøvariabel i stedet.
  • At glemme fail-fast: false i matrixjob. Som standard annulleres alle andre matrixjob, hvis ét matrixjob fejler. Normalt ikke hvad du ønsker under fejlfinding.

Afslutning

GitHub Actions-workflows er fundamentalt YAML-filer — forståelse af YAMLs bogstavelige blokskalarer, citatregler og typetvang oversætter direkte til at skrive mere pålidelig CI. De mest almindelige fejl kommer fra indrykningsfejl, uciterede værdier, der konverteres til den forkerte type, og brug af den forkerte flerlinjede strengoperator til shell-scripts. Få de tre ting rigtigt, og det meste workflow-fejlfinding bliver ligetil. Brug YAML-validatoren til at fange syntaksfejl inden push, og YAML-formateringen til at håndhæve konsistent indrykning på tværs af dine workflow-filer.