Mestring av Linux-kommandolinjen og Bash-skripting · leksjon

Kjøring av skalltester i CI-pipelines

Koble ShellCheck og Bats til GitHub Actions, slik at hver endring i skallet må bestå kontrollene.

Leksjon 4 av 413 trinn

Kjøring av skalltester i CI-pipelines er en gratis leksjon i Mestring av Linux-kommandolinjen og Bash-skripting på CoddyKit. Dette er leksjon 4 av 4. Du kan lese hele leksjonen gratis nedenfor – og deretter øve praktisk i nettleseren med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i Mestring av Linux-kommandolinjen og Bash-skripting, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i Mestring av Linux-kommandolinjen og Bash-skripting inneholder totalt 4 leksjoner.

Hvorfor CI er viktig for shell-skript

Shell-skript er kode – og i likhet med all annen kode fortjener de automatiserte kvalitetskontroller. Uten CI kan en skrivefeil i et distribusjonsskript ubemerket nå produksjon og føre til driftsstans klokken tre om natten.

En solid CI-pipeline for Bash-prosjekter håndhever to ting ved hver pull request:

  • Statisk analyse med ShellCheck – oppdager syntaksfeil, usikre mønstre og POSIX-portabilitetsproblemer før skriptet i det hele tatt kjøres.
  • Enhets- og integrasjonstester med Bats (Bash Automated Testing System) – kjører funksjonene Deres og kontrollerer at de oppfører seg riktig.

Til sammen danner de et sikkerhetsnett som gjør refaktorering tryggere og opplæring av nye bidragsytere raskere. I denne leksjonen kobler vi begge verktøyene til GitHub Actions, den vanligste kostnadsfrie CI-plattformen for åpen kildekode-prosjekter og små team.

Introduksjon til GitHub Actions for shell-prosjekter

GitHub Actions er hendelsesdrevet CI/CD som er innebygd i GitHub. En workflow er en YAML-fil som lagres under .github/workflows/. Den utløses av hendelser (push, pull_request og så videre) og kjører jobber på driftede kjørere.

Viktige konsepter De trenger:

  • on: – utløseren (for eksempel push og pull_request)
  • jobs: – parallelle arbeidsenheter, hver på en ny virtuell maskin
  • steps: – sekvensielle shell-kommandoer eller gjenbrukbare actions i en jobb
  • runs-on: – kjøreravbildningen (vi bruker ubuntu-latest)

Workflow-filer må committes til repositoriet. GitHub oppdager dem automatisk – ingen ekstern konfigurasjon er nødvendig.

# Minimal skeleton — .github/workflows/ci.yml
name: CI

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

jobs:
  shell-checks:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: echo "Steps go here"

Installere ShellCheck i en workflow

ShellCheck er forhåndsinstallert på ubuntu-latest-kjørere, så i de fleste tilfeller trenger De ingen installasjonstrinn. Den forhåndsinstallerte versjonen kan imidlertid ligge etter den nyeste utgaven. For reproduserbare bygg bør De låse til en bestemt versjon.

To installasjonsstrategier:

  • Bruk den forhåndsinstallerte binærfilen – enklest og tilstrekkelig for de fleste prosjekter.
  • Installer en låst versjon via den offisielle tarballen fra GitHub-utgivelsen – dette garanterer samme linter-versjon lokalt og i CI.

Trinnet nedenfor viser den låste fremgangsmåten ved hjelp av en fast versjonsstreng lagret som en miljøvariabel, slik at oppgraderinger kan gjøres med én linje.

# .github/workflows/ci.yml  — ShellCheck install step
- name: Install ShellCheck
  env:
    SC_VERSION: v0.10.0
  run: |
    curl -sSfL \
      "https://github.com/koalaman/shellcheck/releases/download/${SC_VERSION}/shellcheck-${SC_VERSION}.linux.x86_64.tar.xz" \
      | tar -xJf - --strip-components=1 -C /usr/local/bin shellcheck-${SC_VERSION}/shellcheck
    shellcheck --version

Kjøre ShellCheck på hvert skript

Etter installasjonen trenger De et trinn som finner og analyserer alle shell-skript i repositoriet. Bruk find til å finne filene, og send dem deretter videre til shellcheck.

Viktige flagg å kjenne til:

  • -e SC2034 – utelukk en bestemt regel (bruk dette sparsomt og med en kommentar).
  • --severity=warning – la bare advarsler og mer alvorlige funn føre til feil (ignorerer forslag om style).
  • -x – følg source-direktiver for også å analysere innleste filer.

Hvis shellcheck finner et problem, avsluttes programmet med en status ulik null. Dermed feiler CI-trinnet automatisk – ekstra logikk er ikke nødvendig.

# .github/workflows/ci.yml  — ShellCheck lint step
- name: Lint shell scripts
  run: |
    # Find all .sh files and files with a bash/sh shebang
    mapfile -t scripts < <(
      find . -type f -name '*.sh' -not -path './.git/*'
    )
    if [[ ${#scripts[@]} -eq 0 ]]; then
      echo 'No shell scripts found — skipping.'
      exit 0
    fi
    echo "Linting ${#scripts[@]} file(s)..."
    shellcheck --severity=warning -x "${scripts[@]}"

Hva er Bats, og hvordan fungerer det?

Bats (Bash Automated Testing System) er et TAP-kompatibelt testrammeverk for Bash. Hver testfil er en .bats-fil som inneholder @test-blokker.

En test består når kroppen avsluttes med 0, og feiler når den avsluttes med en status ulik null. Bats tilbyr hjelpevariabler og funksjoner:

  • $status – avslutningskoden til den siste run-kommandoen.
  • $output – samlet stdout og stderr fra den siste run-kommandoen.
  • $lines – en tabell med utdata-linjene.
  • run <cmd> – kjør en kommando uten at testen feiler ved en avslutningsstatus ulik null.

Hjelpefunksjonen run er avgjørende – uten den ville en kommando som feiler, avbrutt testen før De kan undersøke $status.

#!/usr/bin/env bats
# tests/greet.bats

setup() {
  # Runs before every @test block
  source "${BATS_TEST_DIRNAME}/../lib/greet.sh"
}

@test "greet outputs hello with the given name" {
  run greet "Alice"
  [ "$status" -eq 0 ]
  [ "$output" = "Hello, Alice!" ]
}

@test "greet fails when no argument is provided" {
  run greet
  [ "$status" -eq 1 ]
  [[ "$output" == *"Usage"* ]]
}

Installere Bats-Core via Git-submodul

Den kanoniske måten å legge til Bats i et prosjekt på er som en Git-submodul. Dette låser en bestemt commit, sørger for at kjørerversjonen er identisk med versjonen i lokal utvikling, og gjør at De ikke er avhengig av pakkebehandlere.

Kjør disse kommandoene én gang lokalt, og commit deretter resultatet:

  • git submodule add https://github.com/bats-core/bats-core test/bats
  • git submodule add https://github.com/bats-core/bats-support test/test_helper/bats-support
  • git submodule add https://github.com/bats-core/bats-assert test/test_helper/bats-assert

I CI gjenopprettes submodulene med actions/checkout@v4 og alternativet submodules: recursive. Trinnet nedenfor viser den fullstendige checkout-konfigurasjonen.

# .github/workflows/ci.yml  — checkout with submodules
- name: Checkout repository
  uses: actions/checkout@v4
  with:
    submodules: recursive   # restores bats-core + helpers

Kjøre Bats-tester i CI

Når Bats er tilgjengelig (via en submodul eller en pakkeinstallasjon), kjøres testene med én enkelt kommando. Angi en mappe, så finner Bats alle .bats-filer rekursivt med flagget --recursive.

Flagget --formatter tap skriver ut formatet TAP (Test Anything Protocol), som mange CI-systemer kan analysere for testrapportering. Standardformateringen pretty egner seg bedre for mennesker som leser rålogger.

Bruk --timing for å oppdage trege tester tidlig – en test som tar mer enn 5 sekunder, tyder vanligvis på et uønsket nettverkskall eller en manglende mock.

# .github/workflows/ci.yml  — Bats test step
- name: Run Bats tests
  run: |
    # If installed as a submodule:
    ./test/bats/bin/bats \
      --recursive \
      --timing \
      tests/

    # If installed via apt or brew (alternative):
    # bats --recursive --timing tests/

En komplett workflow: ShellCheck + Bats

Nå kombinerer vi alt i én produksjonsklar workflow-fil. Her brukes følgende anbefalte fremgangsmåter:

  • To separate jobber (lint og test) kjører parallelt og gir raskere tilbakemelding.
  • test-jobben erklærer needs: lint, slik at testene bare kjører etter at lintingen er bestått. Dermed unngår De å bruke kjørerminutter på kode som åpenbart er ødelagt.
  • Låste action-versjoner (@v4) hindrer uventede brudd på grunn av oppdateringer oppstrøms.
  • En permissions:-blokk begrenser workflow-tokenet til det som er strengt nødvendig.
# .github/workflows/ci.yml
name: Shell CI

on:
  push:
    branches: [main]
  pull_request:

permissions:
  contents: read

jobs:
  lint:
    name: ShellCheck
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Run ShellCheck
        run: |
          mapfile -t scripts < <(find . -name '*.sh' -not -path './.git/*')
          [[ ${#scripts[@]} -gt 0 ]] && shellcheck --severity=warning -x "${scripts[@]}"

  test:
    name: Bats Tests
    runs-on: ubuntu-latest
    needs: lint
    steps:
      - uses: actions/checkout@v4
        with:
          submodules: recursive
      - name: Run tests
        run: ./test/bats/bin/bats --recursive --timing tests/

Bufre avhengigheter for raskere kjøringer

Når Bats-hjelpeverktøy eller andre verktøy installeres via en pakkebehandler i workflowen, kan bufring gjøre senere kjøringer betydelig raskere. GitHub Actions tilbyr actionen actions/cache for dette.

Viktige punkter for effektiv bufring:

  • Bruk en buffernøkkel som inneholder operativsystemet, verktøynavnet og en hash av lock-filen – da blir bufferen automatisk ugyldig når avhengighetene endres.
  • En restore-keys-reserve gjør at workflowen kan bruke en foreldet buffer i stedet for å starte helt fra begynnelsen når bufferen ikke blir funnet.
  • For Git-submoduler er bufring sjelden nødvendig fordi utsjekking av submoduler går raskt. Bufferen er mest nyttig for npm, pip eller installasjoner av kompilerte verktøy.
# .github/workflows/ci.yml  — cache step example
- name: Cache Bats npm helpers
  uses: actions/cache@v4
  with:
    path: ~/.npm
    key: ${{ runner.os }}-bats-${{ hashFiles('package-lock.json') }}
    restore-keys: |
      ${{ runner.os }}-bats-

- name: Install helpers
  run: npm ci  # uses cache when available

Grenbeskyttelse: Håndheve beståtte kontroller

En CI-workflow som ikke blokkerer sammenslåinger, er i beste fall veiledende. GitHubs regler for grenbeskyttelse gjør kontrollene til obligatoriske krav.

Slik konfigurerer De dem: Velg Settings → Branches → Add rule for main, og aktiver deretter:

  • Require status checks to pass before merging – velg ShellCheck og Bats Tests etter navn.
  • Require branches to be up to date before merging – hindrer at en pull request som besto kontrollene mot et foreldet utgangspunkt, introduserer ødelagt kode.
  • Do not allow bypassing the above settings – håndhever reglene også for administratorer av repositoriet.

Når disse reglene er på plass, er den eneste veien til sammenslåing en pull request der alle CI-jobbene er grønne – akkurat det sikkerhetsnettet De ønsker.

Feilsøke CI-trinn som feiler lokalt

Når en CI-kjøring feiler, er den raskeste løsningen å gjenskape feilen lokalt før De sender en ny commit. To teknikker:

  • Kjør de nøyaktige kommandoene fra trinnet som feiler, i terminalen Deres – CI kjører vanlig shell, så kommandoene kan gjenskapes ved å kopiere og lime dem inn.
  • Bruk act – et verktøy som kjører GitHub Actions-workflows lokalt i Docker og gir det nærmeste mulige samsvaret med miljøet på den driftede kjøreren.

En vanlig årsak til feil som bare oppstår i CI, er ulik verktøyversjon på Mac-maskinen Deres (for eksempel BSD find på macOS sammenlignet med GNU find på Ubuntu). Test alltid med --posix-flagg, eller bruk act til å kjøre Ubuntu-avbildningen lokalt.

#!/usr/bin/env bash
# run_ci_locally.sh  — mimic the CI lint step on your machine
set -euo pipefail

echo '=== ShellCheck ==='
mapfile -t scripts < <(find . -name '*.sh' -not -path './.git/*')
if [[ ${#scripts[@]} -eq 0 ]]; then
  echo 'No .sh files found.'
else
  shellcheck --severity=warning -x "${scripts[@]}"
  echo "Linted ${#scripts[@]} file(s) — OK"
fi

echo '=== Bats ==='
./test/bats/bin/bats --recursive --timing tests/

Kunnskapssjekk: Konsepter for CI-pipelines

Test forståelsen Deres av hvordan ShellCheck og Bats kobles til GitHub Actions.

Oppsummering: Shell-CI med ShellCheck og Bats

I denne leksjonen bygget De en komplett CI-pipeline for Bash-prosjekter ved hjelp av GitHub Actions. Her er det De gikk gjennom:

  • Grunnleggende om GitHub Actions – workflow-YAML lagres i .github/workflows/, utløses av push og pull_request og kjører jobber på ubuntu-latest-kjørere.
  • ShellCheck – forhåndsinstallert på Ubuntu-kjørere. Bruk find til å finne skript og --severity=warning -x som en praktisk lint-kontroll.
  • Bats via submodul – lås bats-core og hjelpeverktøy som Git-submoduler, og gjenopprett dem i CI med submodules: recursive i checkout-actionen.
  • Rekkefølge på jobber – bruk needs: slik at testene bare kjører etter at lintingen er bestått. Da får De rask tilbakemelding og unngår bortkastede beregningsressurser.
  • Grenbeskyttelse – håndhev statuskontroller i GitHub-innstillingene slik at ingen pull request kan flettes inn uten grønn CI.
  • Lokal gjenskaping – kopier CI-kommandoene direkte til terminalen Deres, eller bruk act til å feilsøke uten ekstra committer.

Med denne pipelinen på plass blir hver endring i shell-koden automatisk kontrollert før den berører hovedgrenen Deres.

Gratis å komme i gang

Lær deg Bash med en AI-veileder – gratis

Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.

Kurs
22
Leksjoner
88

Ofte stilte spørsmål

Er leksjonen «Kjøring av skalltester i CI-pipelines» gratis?

Ja – hele teksten i «Kjøring av skalltester i CI-pipelines» er gratis å lese her på nettet. For å øve interaktivt med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt, og for å låse opp resten av Mestring av Linux-kommandolinjen og Bash-skripting-kurset, kan du oppgradere til CoddyKit PRO. Kurset i Mestring av Linux-kommandolinjen og Bash-skripting inneholder totalt 4 leksjoner.

Hva lærer jeg i «Kjøring av skalltester i CI-pipelines»?

Koble ShellCheck og Bats til GitHub Actions, slik at hver endring i skallet må bestå kontrollene. Du øver på Mestring av Linux-kommandolinjen og Bash-skripting med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.

Trenger jeg erfaring for å begynne med Mestring av Linux-kommandolinjen og Bash-skripting?

Ingen tidligere erfaring er nødvendig. Mestring av Linux-kommandolinjen og Bash-skripting på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 4 av 4.

Hvor lang tid tar leksjonen «Kjøring av skalltester i CI-pipelines»?

De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.

Kan jeg skrive og kjøre kode i denne Mestring av Linux-kommandolinjen og Bash-skripting-leksjonen?

Ja. Alle Mestring av Linux-kommandolinjen og Bash-skripting-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.

Alle leksjonene i dette kurset

  1. Enhetstesting av funksjoner med Bats-core
  2. Mocking av kommandoer og stubbing av eksterne verktøy
  3. Testfiksturer, midlertidige miljøer og dekningsgrad
  4. Kjøring av skalltester i CI-pipelines
← Tilbake til Mestring av Linux-kommandolinjen og Bash-skripting