CI/CD met GitHub Actions: Van Code naar Productie in Minuten

Leer hoe je een robuuste CI/CD pipeline bouwt met GitHub Actions, inclusief testen, bouwen en automatisch deployen naar productie.

Jean-Pierre Broeders

Freelance DevOps Engineer

17 februari 20265 min. leestijd

CI/CD met GitHub Actions: Van Code naar Productie in Minuten

Als developer ken je het gevoel: je hebt een feature afgemaakt, maar het deployen is een handmatig proces vol klikken, wachten en kruisvingers houden. GitHub Actions lost dit op — met een paar YAML-bestanden automatiseer je het volledige traject van code naar productie.

Wat is CI/CD eigenlijk?

Continuous Integration (CI) betekent dat elke code-push automatisch getest wordt. Stuk code erin, tests draaien, feedback terug. Geen verrassingen later.

Continuous Deployment (CD) gaat een stap verder: als de tests slagen, wordt de code automatisch uitgerold naar acceptatie of productie. Geen handmatig werk meer.

GitHub Actions is Microsofts antwoord hierop, ingebakken in GitHub zelf. Geen externe CI-server nodig, geen integraties die je moet onderhouden.

Je eerste workflow

Workflows leven in .github/workflows/ en zijn geschreven in YAML. Een basisworkflow voor een Node.js project ziet er zo uit:

name: CI/CD Pipeline

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

jobs:
  test:
    runs-on: ubuntu-latest
    
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'
      
      - name: Installeer dependencies
        run: npm ci
      
      - name: Draai tests
        run: npm test
      
      - name: Build
        run: npm run build

Dit bestand opslaan en pushen is al genoeg om tests automatisch te draaien bij elke push en pull request.

Secrets veilig beheren

Je deployment-stap heeft bijna altijd credentials nodig: API keys, SSH-sleutels, wachtwoorden. Die horen nooit in je code. GitHub biedt hiervoor Secrets:

  1. Ga naar je repo → Settings → Secrets and variables → Actions
  2. Voeg een secret toe, bijvoorbeeld DEPLOY_SSH_KEY
  3. Gebruik het in je workflow:
- name: Deploy naar server
  env:
    SSH_KEY: ${{ secrets.DEPLOY_SSH_KEY }}
  run: |
    echo "$SSH_KEY" > /tmp/deploy_key
    chmod 600 /tmp/deploy_key
    ssh -i /tmp/deploy_key user@server.example.com "cd /app && git pull && npm install && pm2 restart all"

Secrets zijn versleuteld opgeslagen en worden nooit getoond in logs — ook niet als iemand je repo forkt.

Deployment naar meerdere omgevingen

In de praktijk wil je een onderscheid maken tussen staging en productie. Dit doe je met environments en branch-regels:

jobs:
  deploy-staging:
    if: github.ref == 'refs/heads/develop'
    runs-on: ubuntu-latest
    environment: staging
    steps:
      - uses: actions/checkout@v4
      - name: Deploy naar staging
        run: ./deploy.sh staging

  deploy-production:
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    environment: production
    needs: [test]  # Wacht op succesvolle tests
    steps:
      - uses: actions/checkout@v4
      - name: Deploy naar productie
        run: ./deploy.sh production

Met needs: [test] zorg je dat de deployment alleen plaatsvindt als alle tests geslaagd zijn. Essentieel voor productie.

Matrix builds: Test op meerdere versies tegelijk

Wil je zeker weten dat je code werkt op Node 18, 20 én 22? Gebruik matrix strategy:

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [18, 20, 22]
    
    steps:
      - uses: actions/checkout@v4
      - name: Setup Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
      - run: npm ci
      - run: npm test

GitHub start drie parallelle jobs, één per versie. Als één versie faalt, zie je exact welke — zonder dat je handmatig hoeft te switchen.

Caching voor snellere builds

Elke keer npm install draait, download GitHub alle packages opnieuw. Dat kost tijd. Caching lost dit op:

- name: Cache npm dependencies
  uses: actions/cache@v4
  with:
    path: ~/.npm
    key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
    restore-keys: |
      ${{ runner.os }}-node-

De cache slaat de gedownloade packages op op basis van een hash van package-lock.json. Verandert de lockfile niet, dan worden packages uit cache geladen — soms 2-3x sneller.

Praktische tips voor productiegebruik

Gebruik specifieke versies van actions, nooit @main:

uses: actions/checkout@v4  # Goed
uses: actions/checkout@main  # Gevaarlijk — kan onverwacht breken

Beperk permissies tot wat je workflow nodig heeft:

permissions:
  contents: read
  packages: write

Stel timeouts in zodat hangende jobs niet eindeloos draaien:

jobs:
  build:
    timeout-minutes: 15

Gebruik concurrency om dubbele deployments te voorkomen:

concurrency:
  group: production-deploy
  cancel-in-progress: false  # Laat lopende deployments afmaken

Van 0 naar geautomatiseerd in een middag

GitHub Actions is laagdrempelig: je hebt alleen een GitHub-account en een repo nodig. De gratis tier biedt 2.000 minuten per maand voor publieke repos, ongelimiteerd voor publieke repos.

Begin klein: voeg eerst alleen tests toe. Als dat soepel loopt, voeg je de deployment-stap toe. Stap voor stap bouw je een betrouwbare pipeline die je uren per week bespaart.


CI/CD pipelines with GitHub Actions let you automate testing and deployment from a single YAML file. With built-in secrets management, environment support, and parallel matrix builds, it's one of the most accessible DevOps tools available today. Start small, iterate fast.

Wil je op de hoogte blijven?

Schrijf je in voor mijn nieuwsbrief of neem contact op voor freelance projecten.

Neem Contact Op