Shelltests uitvoeren in CI-pipelines
Integreer ShellCheck en Bats in GitHub Actions en laat elke wijziging aan de shell alleen door bij geslaagde controles.
Shelltests uitvoeren in CI-pipelines is een gratis DevOps-bootcamp-les op CoddyKit. Dit is les 4 van 4. Je kunt 3 lessen uit dit leerpad gratis volledig lezen — daarna ontgrendelt CoddyKit PRO alle lessen, plus praktische oefeningen met een ingebouwde code-editor en een AI-tutor die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject DevOps-bootcamp. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus DevOps-bootcamp bevat in totaal 4 lessen.
Waarom CI belangrijk is voor shellscripts
Shellscripts zijn code en verdienen, net als alle code, geautomatiseerde kwaliteitscontroles. Zonder CI kan een typefout in een implementatiescript ongemerkt productie bereiken en om drie uur 's nachts een storing veroorzaken.
Een degelijke CI-pijplijn voor Bash-projecten dwingt bij elke pull request twee zaken af:
- Statische analyse via
ShellCheck— detecteert syntaxisfouten, onveilige patronen en POSIX-portabiliteitsproblemen voordat het script ooit wordt uitgevoerd. - Eenheids- en integratietests via
Bats(Bash Automated Testing System) — voert uw functies uit en controleert of ze zich correct gedragen.
Samen vormen ze een vangnet dat refactoren zonder zorgen en het inwerken van nieuwe teamleden sneller maakt. In deze les koppelt u beide hulpmiddelen aan GitHub Actions, het meestgebruikte gratis CI-platform voor opensource- en kleine teamprojecten.
Inleiding tot GitHub Actions voor shellprojecten
GitHub Actions is gebeurtenisgestuurde CI/CD die in GitHub is ingebouwd. Een werkstroom is een YAML-bestand dat onder .github/workflows/ is opgeslagen. De werkstroom wordt geactiveerd door gebeurtenissen (push, pull_request enzovoort) en voert taken uit op gehoste runners.
De belangrijkste concepten:
on:— de trigger (bijvoorbeeldpush,pull_request)jobs:— parallelle werkeenheden, elk op een nieuwe virtuele machinesteps:— opeenvolgende shellopdrachten of herbruikbare acties binnen een taakruns-on:— de runnerimage (we gebruikenubuntu-latest)
Werkstroombestanden moeten naar de repository worden gecommit. GitHub detecteert ze automatisch; externe configuratie is niet nodig.
# 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"ShellCheck installeren in een werkstroom
ShellCheck is vooraf geïnstalleerd op runners met ubuntu-latest, dus meestal hebt u helemaal geen installatiestappen nodig. De vooraf geïnstalleerde versie kan echter achterlopen op de nieuwste uitgave. Zet voor reproduceerbare builds een specifieke versie vast.
Twee installatiestrategieën:
- Het vooraf geïnstalleerde binaire bestand gebruiken — het eenvoudigst en goed genoeg voor de meeste projecten.
- Een vastgezette versie installeren via het officiële GitHub-release-tarball — garandeert lokaal en in CI dezelfde linterversie.
De onderstaande stap laat de vastgezette aanpak zien met een vaste versietekenreeks die als omgevingsvariabele is opgeslagen, zodat upgraden een wijziging van één regel wordt.
# .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 --versionShellCheck op elk script uitvoeren
Na de installatie hebt u een stap nodig die alle shellscripts in de repository vindt en controleert. Gebruik find om bestanden te vinden en leid ze vervolgens door naar shellcheck.
Belangrijke opties:
-e SC2034— sluit een specifieke regel uit (gebruik dit spaarzaam en met een opmerking).--severity=warning— laat alleen waarschuwingen en ernstigere meldingen mislukken (suggesties over stijl worden genegeerd).-x— volgsource-instructies om ook ingelezen bestanden te controleren.
Als shellcheck een probleem vindt, wordt het afgesloten met een niet-nulstatus. Daardoor mislukt de CI-stap automatisch; extra logica is niet nodig.
# .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[@]}"Wat is Bats en hoe werkt het?
Bats (Bash Automated Testing System) is een TAP-compatibel testframework voor Bash. Elk testbestand is een .bats-bestand met @test-blokken.
Een test slaagt als de hoofdtekst wordt afgesloten met 0 en mislukt als deze wordt afgesloten met een niet-nulstatus. Bats biedt helpervariabelen en -functies:
$status— de afsluitcode van de laatste opdracht metrun.$output— de gecombineerde stdout en stderr van de laatste opdracht metrun.$lines— array met uitvoerregels.run <cmd>— voer een opdracht uit zonder de test te laten mislukken bij een niet-nulstatus.
De helper run is essentieel: zonder deze helper zou een mislukte opdracht de test afbreken voordat u $status kunt bekijken.
#!/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"* ]]
}Bats-Core installeren via een Git-submodule
De gebruikelijke manier om Bats aan een project toe te voegen is als Git-submodule. Hiermee legt u een specifieke commit vast, blijft de versie van de runner gelijk aan die van de lokale ontwikkelomgeving en hoeft u niet op pakketbeheerders te vertrouwen.
Voer deze opdrachten eenmaal lokaal uit en commit vervolgens het resultaat:
git submodule add https://github.com/bats-core/bats-core test/batsgit submodule add https://github.com/bats-core/bats-support test/test_helper/bats-supportgit submodule add https://github.com/bats-core/bats-assert test/test_helper/bats-assert
Herstel submodules in CI met actions/checkout@v4 en de optie submodules: recursive. De onderstaande stap toont de volledige checkoutconfiguratie.
# .github/workflows/ci.yml — checkout with submodules
- name: Checkout repository
uses: actions/checkout@v4
with:
submodules: recursive # restores bats-core + helpersBats-tests uitvoeren in CI
Zodra Bats beschikbaar is (via een submodule of pakketinstallatie), voert u de tests uit met één opdracht. Geef een map op; Bats vindt vervolgens met de optie --recursive elk .bats-bestand recursief.
De optie --formatter tap produceert de TAP-indeling (Test Anything Protocol), die veel CI-systemen kunnen verwerken voor testrapportage. De standaardopmaak pretty is beter leesbaar voor mensen in onbewerkte logboeken.
Gebruik --timing om trage tests vroeg zichtbaar te maken: een test die langer dan 5 seconden duurt, wijst meestal op een ongewenste netwerkaanroep of een ontbrekende 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/Een volledige werkstroom: ShellCheck + Bats
Voeg nu alles samen in één werkstroombestand dat geschikt is voor productie. Hier zijn de toegepaste best practices:
- Twee afzonderlijke taken (
lintentest) worden parallel uitgevoerd, zodat u sneller feedback krijgt. - De taak
testdeclareertneeds: lint, zodat tests pas worden uitgevoerd nadat de lintcontrole is geslaagd. Zo verspilt u geen runnerminuten aan duidelijk defecte code. - Vastgezette actieversies (
@v4) voorkomen onverwachte problemen door updates van upstream. - Een blok
permissions:beperkt het werkstroomtoken tot de minimaal vereiste rechten.
# .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/Afhankelijkheden cachen voor snellere uitvoeringen
Wanneer Bats-helpers of andere hulpmiddelen in de werkstroom via een pakketbeheerder worden geïnstalleerd, versnelt caching volgende uitvoeringen aanzienlijk. GitHub Actions biedt hiervoor de actie actions/cache.
Belangrijke punten voor effectief cachen:
- Gebruik een cachesleutel met daarin het besturingssysteem, de naam van het hulpmiddel en een hash van het lockbestand, zodat de cache automatisch ongeldig wordt wanneer afhankelijkheden veranderen.
- Met een
restore-keys-terugval kan de werkstroom een verouderde cache gebruiken in plaats van bij een cachemisser helemaal opnieuw te beginnen. - Voor Git-submodules is caching zelden nodig, omdat het ophalen van submodules snel gaat. Caching is vooral waardevol voor
npm,pipof installaties van gecompileerde hulpmiddelen.
# .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 availableBranchbeveiliging: geslaagde controles afdwingen
Een CI-werkstroom die samenvoegingen niet blokkeert, is op zijn best adviserend. Met de regels voor branchbeveiliging van GitHub maakt u van uw controles harde poorten.
Configureer deze als volgt: ga naar Settings → Branches → Add rule voor main en schakel het volgende in:
- Require status checks to pass before merging — selecteer ShellCheck en Bats Tests op naam.
- Require branches to be up to date before merging — voorkomt dat een pull request die controles op een verouderde basis heeft doorstaan, defecte code toevoegt.
- Do not allow bypassing the above settings — past de regels ook toe op repositorybeheerders.
Met deze regels is een pull request met alle groene CI-taken de enige route naar samenvoeging, precies het vangnet dat u nodig hebt.
Mislukte CI-stappen lokaal debuggen
Wanneer een CI-uitvoering mislukt, herstelt u dit het snelst door de fout lokaal te reproduceren voordat u nog een commit pusht. Twee technieken:
- Voer de exacte opdrachten uit uit de mislukte stap in uw terminal. CI voert gewone shell uit, dus de opdrachten kunnen worden gekopieerd en opnieuw uitgevoerd.
- Gebruik
act— een hulpmiddel dat GitHub Actions-werkstromen lokaal in Docker uitvoert en daarmee de gehoste runneromgeving zo nauwkeurig mogelijk nabootst.
Een veelvoorkomende oorzaak van fouten die alleen in CI optreden, is een verschil in hulpmiddelversies tussen uw Mac (bijvoorbeeld BSD find op macOS versus GNU find op Ubuntu). Test altijd met opties van --posix of gebruik act om de Ubuntu-installatie lokaal uit te voeren.
#!/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/Kenniscontrole: concepten van CI-pijplijnen
Test uw begrip van het koppelen van ShellCheck en Bats aan GitHub Actions.
Samenvatting: shell-CI met ShellCheck en Bats
In deze les hebt u met GitHub Actions een volledige CI-pijplijn voor Bash-projecten gebouwd. Dit hebt u behandeld:
- Basisprincipes van GitHub Actions — YAML voor werkstromen staat in
.github/workflows/, wordt geactiveerd door push en pull_request en voert taken uit op runners metubuntu-latest. - ShellCheck — vooraf geïnstalleerd op Ubuntu-runners; gebruik
findom scripts te vinden en--severity=warning -xals praktische lintcontrole. - Bats via een submodule — zet bats-core en helpers vast als Git-submodules en herstel ze in CI met
submodules: recursivebij de checkoutactie. - Volgorde van taken — gebruik
needs:zodat tests pas worden uitgevoerd nadat de lintcontrole is geslaagd. Zo behoudt u snelle feedback en voorkomt u verspilde rekenkracht. - Branchbeveiliging — dwing statuscontroles af in de GitHub-instellingen, zodat geen pull request kan worden samengevoegd zonder groene CI.
- Lokale reproductie — kopieer CI-opdrachten rechtstreeks naar uw terminal of gebruik
actom fouten te debuggen zonder extra commits.
Met deze pijplijn wordt elke wijziging aan de shell automatisch gevalideerd voordat deze uw hoofdbranch raakt.
Leer DevOps-bootcamp met een AI-tutor — gratis
Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.
- Cursussen
- 142
- Lessen
- 568
Veelgestelde vragen
Is de les “Shelltests uitvoeren in CI-pipelines” gratis?
Ja — je kunt hier op het web alle 3 lessen van het leerpad DevOps-bootcamp, waaronder “Shelltests uitvoeren in CI-pipelines”, gratis volledig lezen. Daarna ontgrendelt CoddyKit PRO alle lessen, plus interactieve oefeningen met een ingebouwde code-editor en een AI-tutor die 24/7 beschikbaar is. De cursus DevOps-bootcamp bevat in totaal 4 lessen.
Wat leer ik in “Shelltests uitvoeren in CI-pipelines”?
Integreer ShellCheck en Bats in GitHub Actions en laat elke wijziging aan de shell alleen door bij geslaagde controles. Je oefent met DevOps-bootcamp door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.
Heb ik ervaring nodig om met DevOps-bootcamp te beginnen?
Ervaring vooraf is niet nodig. DevOps-bootcamp op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 4 van 4.
Hoe lang duurt de les “Shelltests uitvoeren in CI-pipelines”?
De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.
Kan ik code schrijven en uitvoeren in deze les over DevOps-bootcamp?
Ja. Elke les over DevOps-bootcamp bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.
Alle lessen in deze cursus
- Functies testen met Bats-core
- Commando's mocken en externe tools stubben
- Fixtures, tijdelijke omgevingen en coverage
- Shelltests uitvoeren in CI-pipelines