Continuous Integration (CI)
In dieser Lerneinheit tauchst du in die Grundlagen und Praktiken von Continuous Integration (CI) ein und lernst, wie Code-Änderungen kontinuierlich in ein Projekt integriert werden. Du verstehst die wichtigsten CI-Konzepte wie automatisierte Builds, Tests und Qualitätssicherung, die in modernen Entwicklungsteams unverzichtbar sind. Anhand konkreter Beispiele erfährst du, wie CI-Prozesse die Codequalität verbessern und Entwicklungsteams effizienter zusammenarbeiten können.
Einführung
Fünf Entwickler arbeiten am selben Projekt. Jeder programmiert neue Features, fixt Bugs, schreibt Tests. Am Ende der Woche sollen alle Änderungen zusammengeführt werden – und plötzlich bricht alles zusammen.

‘Mein Code hat lokal funktioniert! Warum gibt es jetzt 47 Merge-Konflikte und 23 fehlgeschlagene Tests?’
Dieses Chaos entsteht, wenn Code nur selten integriert wird. Continuous Integration (CI) löst dieses Problem, indem Code kontinuierlich – idealerweise mehrmals täglich – automatisch integriert und getestet wird. So werden Konflikte sofort erkannt, nicht erst nach Tagen oder Wochen.
In dieser Lerneinheit lernst du, wie CI funktioniert, welche Tools du nutzen kannst und wie du automatisierte Pipelines aufsetzt, die dein Team produktiver machen.
Lernziele
Nach dieser Lerneinheit kannst du:
- Die Prinzipien von Continuous Integration erklären und den Nutzen für Entwicklerteams begründen
- Die 7 Kernpraktiken von CI anwenden und in eigenen Projekten umsetzen
- Eine CI-Pipeline in Jenkins, GitLab CI oder GitHub Actions konfigurieren
- Automatisierte Tests und Code-Qualitätsprüfungen in CI-Pipelines integrieren
- Container-basierte CI-Builds verstehen und deren Vorteile benennen
Überleitung
Das Problem ist klar: Seltene Integration führt zu Chaos. CI bietet die Lösung.
Aber was genau ist CI eigentlich? Und warum setzen so viele erfolgreiche Teams auf diese Praxis?
Schauen wir uns die Grundlagen an.
Was ist Continuous Integration?
Continuous Integration (CI) ist eine Entwicklungspraxis, bei der Code-Änderungen kontinuierlich – idealerweise mehrmals täglich – in ein gemeinsames Repository integriert werden.
Die Kernidee:
Statt Wochen isoliert an Features zu arbeiten und dann alles auf einmal zu mergen, integrieren Entwickler ihre Änderungen häufig und automatisch.
Was passiert bei jeder Integration?
- Code wird ins Repository gepusht
- Automatischer Build startet
- Automatisierte Tests laufen durch
- Entwickler erhalten sofortiges Feedback
Falls etwas schief geht, wird es sofort erkannt – nicht erst Wochen später.
Warum CI? Konflikte früh erkennen und Qualität verbessern
Konflikte früh erkennen
Das Problem ohne CI: Entwickler arbeiten tagelang isoliert. Beim Merge gibt es 50 Konflikte. Niemand weiß mehr, welche Änderung was beeinflusst.
Mit CI: Konflikte entstehen nach Stunden, nicht nach Wochen. Sie sind klein, überschaubar, schnell lösbar.
Softwarequalität verbessern
Automatisierte Builds und Tests gewährleisten kontinuierliche Qualitätskontrolle:
- Jeder Commit wird getestet
- Bugs werden sofort erkannt
- Code-Qualität bleibt konstant hoch
Je früher Probleme erkannt werden, desto günstiger und einfacher sind sie zu beheben.
Warum CI? Entwicklungszeit verkürzen
Frühes Erkennen = weniger Debugging:
Statt Tage damit zu verbringen, herauszufinden welcher Commit welches Problem verursacht hat, wird jeder Commit sofort getestet.
Beispiel:
- Ohne CI: 20 Commits in 3 Tagen → Build bricht. Welcher Commit? 3 Stunden Debugging.
- Mit CI: Commit 7 von 20 bricht Build → 15 Minuten Fix.
Das Ergebnis:
Teams verbringen weniger Zeit mit Fehlersuche und mehr Zeit mit produktiver Entwicklung.
CI macht Entwicklung schneller, nicht langsamer – durch sofortiges Feedback.
Die 7 Kernpraktiken von CI (Teil 1)
CI besteht aus sieben zentralen Praktiken. Hier sind die ersten drei:
1. Einziger Integrationspunkt
Alle Entwickler pushen Code in ein gemeinsames Repository (z.B. Git). Dort werden automatisch Builds und Tests ausgelöst. Das Repository ist die Single Source of Truth – jeder arbeitet mit dem gleichen Code-Stand.
2. Automatisierter Build
Jeder Commit triggert einen automatischen Build-Prozess. Der CI-Server kompiliert den Code, resolved Dependencies und erstellt ausführbare Artefakte. Falls der Build fehlschlägt, wissen Entwickler sofort: “Dieser Commit hat etwas kaputt gemacht.”
3. Automatisierte Tests
Nach dem Build laufen automatisierte Tests (Unit Tests, Integrationstests). Sie stellen sicher, dass neue Änderungen keine bestehenden Funktionen brechen. Ohne Tests wäre CI nur “Continuous Integration of Bugs”.
Diese drei Praktiken bilden das Fundament jeder CI-Pipeline.
Die 7 Kernpraktiken von CI (Teil 2)
4. Keep the Build Fast
Der Build-Prozess sollte schnell sein (idealerweise unter 10 Minuten). Warum? Weil Entwickler auf Feedback warten. Ein 2-Stunden-Build bedeutet: Entwickler arbeiten an anderem Code, bevor sie wissen, ob ihr letzter Commit funktioniert hat. Das führt zu Kontextwechseln und verzögerten Fixes.
5. Main-Branch deployfähig halten
Jeder Commit sollte auf dem Main-Branch gebaut werden. Der Main-Branch muss immer in einem releasefähigen Zustand sein. Das bedeutet: Keine “Work in Progress”-Commits auf Main. Feature Branches werden erst gemergt, wenn sie vollständig funktionieren und alle Tests bestehen.
Moderne Teams nutzen den Main-Branch (früher: Master-Branch) als einzige Quelle der Wahrheit.
Die 7 Kernpraktiken von CI (Teil 3)
6. Fix Broken Builds Immediately
Wenn ein Build fehlschlägt, hat dessen Behebung höchste Priorität. Warum? Ein kaputtes Build blockiert alle anderen Entwickler. Niemand kann sicher neuen Code integrieren, wenn der aktuelle Stand bereits broken ist. Die Regel: “Wer den Build bricht, fixt ihn sofort – oder der Commit wird zurückgerollt.”
7. Transparente Build- und Testergebnisse
Ergebnisse von Builds und Tests müssen für das gesamte Team sofort sichtbar sein. Das funktioniert über:
- CI-Dashboards (Echtzeit-Ansicht des Build-Status)
- Slack/Teams-Notifications (automatische Benachrichtigungen bei Failures)
- Badge-Integration (grüne/rote Badges im Repository)
Das Ziel: Jeder im Team weiß jederzeit, ob der aktuelle Code funktioniert.
Transparenz schafft Verantwortung und schnelle Reaktion.
Eine CI-Pipeline in Aktion
So sieht der typische CI-Ablauf aus:

Der Ablauf:
- Code wird gepusht → CI-Server erkennt Änderung
- Automatischer Build startet
- Tests laufen durch
- Erfolg: Grünes Licht ✅ | Fehler: Sofortige Benachrichtigung ❌
Dieser Kreislauf läuft bei jedem Commit – vollautomatisch.
CI-Tools im Überblick
Es gibt viele CI-Tools. Hier sind die wichtigsten:
| Tool | Typ | Besonderheit |
|---|---|---|
| Jenkins | Open Source | Sehr flexibel, viele Plugins |
| GitLab CI | Integriert | Teil von GitLab, YAML-Konfiguration |
| GitHub Actions | Integriert | Direkt in GitHub, Marketplace |
| CircleCI | Cloud | Schnell, einfache Konfiguration |
Welches Tool wählen?
- Neu starten? GitHub Actions oder GitLab CI
- Maximale Flexibilität? Jenkins
- Cloud-basiert? CircleCI
Im nächsten Abschnitt schauen wir uns diese Tools im Detail an.
Jenkins - Der flexible Klassiker
Jenkins ist ein Open-Source-Automatisierungsserver, geschrieben in Java.
Schlüsselfunktionen:
- Plugin-Ökosystem: Über 1.800 Plugins für nahezu jeden Anwendungsfall (Git, Docker, Kubernetes, Slack, etc.)
- Pipeline as Code: Jenkinsfiles definieren CI/CD-Pipelines als Code im Repository
- Distributed Builds: Kann Builds auf mehrere Agents verteilen
- Container-Unterstützung: Kann Builds in Docker-Containern ausführen
Konfiguration:
- Web-UI für einfache Jobs
- Jenkinsfile (Groovy) für komplexe Pipelines
Ideal für: Teams, die maximale Flexibilität und Kontrolle benötigen.
Jenkins ist der Marktführer, aber erfordert mehr Setup als moderne Cloud-Lösungen.
Jenkins Pipeline-Beispiel
Ein Jenkinsfile definiert die Pipeline als Code. Schauen wir uns ein vollständiges Beispiel an:
pipeline {
agent any // Führe auf beliebigem Agent aus
stages {
stage("Checkout") {
steps {
// Hole Code aus Git
git url: "https://github.com/firma/webshop-backend.git"
}
}
stage("Build") {
steps {
// Führe Maven Build aus
sh "mvn clean package"
}
}
stage("Test") {
steps {
// Führe alle Tests aus
sh "mvn test"
}
}
}
post {
always {
// Archiviere Build-Artefakte
archiveArtifacts artifacts: "**/target/*.jar", fingerprint: true
}
}
}Was passiert hier?
- agent any: Der Build kann auf jedem verfügbaren Jenkins-Agent laufen
- stages: Die Pipeline hat 3 Stages (Checkout, Build, Test)
- git url: Holt Code aus dem Repository
- sh “mvn clean package”: Führt Maven-Build aus und erstellt JAR-Dateien
- sh “mvn test”: Führt alle Unit- und Integrationstests aus
- post { always }: Wird immer ausgeführt, auch bei Fehler
- archiveArtifacts: Speichert die gebauten JAR-Dateien für späteren Download
Wichtig: Jenkinsfiles verwenden Groovy-Syntax, nicht YAML.
GitLab CI - Die integrierte Lösung
GitLab CI ist Teil der GitLab-Plattform und nahtlos integriert.
Schlüsselfunktionen:
- YAML-Konfiguration: Pipelines werden in
.gitlab-ci.ymldefiniert - Integrierte Container Registry: Docker-Images direkt in GitLab speichern
- Auto DevOps: Automatische CI/CD-Konfiguration für Standard-Projekte
- Parallel & Sequential Jobs: Flexibles Pipeline-Design
- Visuelle Pipeline-Übersicht: Echtzeit-Status aller Jobs
Vorteile:
- Keine separate CI-Infrastruktur nötig
- Direkte Integration mit Merge Requests
- GitLab Runner auf eigener Infrastruktur oder Cloud
Ideal für: Teams, die bereits GitLab nutzen.
GitLab CI ist schnell einzurichten und gut dokumentiert.
GitLab CI Pipeline-Beispiel
Eine .gitlab-ci.yml definiert die Pipeline. Hier ein vollständiges Beispiel:
stages:
- build
- test
- deploy
build_job:
stage: build
script:
- npm ci # Installiert Dependencies aus package-lock.json
- npm run build # Baue Anwendung
test_job:
stage: test
script:
- npm ci # Installiere Dependencies
- npm run lint # Führe ESLint aus (als devDependency definiert)
- npm test # Führe Unit-Tests aus
deploy_job:
stage: deploy
script:
- npm ci
- npm run deploy # Deployment-Script
only:
- main # Nur auf Main-Branch deployenWas passiert hier?
- stages: Definiert 3 Stages (build, test, deploy) die nacheinander laufen
- npm ci: Installiert Dependencies aus package-lock.json (reproduzierbar!)
- npm run build: Führt Build-Script aus package.json aus
- npm run lint: Führt ESLint aus (muss als devDependency in package.json definiert sein)
- npm test: Führt alle Tests aus
- only: - main: Deploy-Job läuft nur auf Main-Branch, nicht auf Feature-Branches
Best Practice: Nutze npm ci statt npm install für reproduzierbare Builds.
ESLint sollte als devDependency in package.json definiert sein, nicht separat installiert werden.
GitHub Actions - Der moderne Standard
GitHub Actions ist eines der aktuell meistgenutzten CI/CD-Tools, besonders in Open-Source-Projekten.
Schlüsselfunktionen:
- Direkt in GitHub integriert – keine separate Platform nötig
- YAML-Workflows in
.github/workflows/ - GitHub Marketplace mit tausenden vorgefertigten Actions
- Matrix Builds: Teste auf mehreren Node/Python/OS-Versionen gleichzeitig
- Kostenlos für Public Repositories, flexible Preise für Private Repos
Warum GitHub Actions wichtig ist:
Viele moderne Projekte setzen auf GitHub Actions, da es einfacher zu konfigurieren ist als Jenkins und keine separate Infrastruktur benötigt.
Ideal für: Teams, die bereits GitHub nutzen.
GitHub Actions ist der De-facto-Standard für moderne Open-Source-Projekte.
GitHub Actions Workflow-Beispiel
Ein Workflow in .github/workflows/ci.yml:
name: CI Pipeline
on:
push:
branches: [ main ] # Bei Push auf Main
pull_request:
branches: [ main ] # Bei Pull Requests
jobs:
build:
runs-on: ubuntu-latest # Führe auf Ubuntu Runner aus
steps:
- uses: actions/checkout@v4 # Hole Code aus Repository
- name: Setup Node.js
uses: actions/setup-node@v4 # Installiere Node.js
with:
node-version: "20"
- name: Install Dependencies
run: npm ci # Installiere Dependencies
- name: Run Tests
run: npm test # Führe Tests aus
- name: Build
run: npm run build # Baue AnwendungWas passiert hier?
- on: push/pull_request: Workflow triggert bei Push oder Pull Request auf Main-Branch
- runs-on: ubuntu-latest: Build läuft auf Ubuntu-Container
- uses: actions/checkout@v4: Holt Code aus dem Repository (vorgefertigte Action aus Marketplace)
- uses: actions/setup-node@v4: Installiert Node.js (auch aus Marketplace)
- with: node-version: “20”: Nutzt Node.js Version 20
- run: npm ci: Führt Shell-Befehl aus (installiert Dependencies)
- run: npm test: Führt Tests aus
Besonderheit: uses: nutzt vorgefertigte Actions aus dem Marketplace. Das ist der Hauptvorteil von GitHub Actions – du musst nicht alles selbst konfigurieren.
Container-basierte CI - Isolation und Reproduzierbarkeit
Container-basierte CI-Pipelines sind der aktuelle Standard in modernen Entwicklungsteams.
Wie funktioniert das?
Jeder Build läuft in einem isolierten Docker-Container. Das bedeutet:
- Isolation: Builds beeinflussen sich nicht gegenseitig
- Reproduzierbarkeit: Gleiche Umgebung auf jedem System (lokal, CI, Produktion)
- Sauberkeit: Jeder Build startet mit “sauberer Slate”
Beispiel in Jenkins:
pipeline {
agent {
docker {
image "maven:3.9-eclipse-temurin-21" // Maven Container
}
}
stages {
stage("Build") {
steps {
sh "mvn clean package"
}
}
}
}Was passiert hier?
- agent { docker }: Jenkins startet einen Docker-Container für den Build
- image “maven:3.9-eclipse-temurin-21”: Verwendet offizielles Maven-Image mit Java 21
- sh “mvn clean package”: Führt Maven-Build IM Container aus
Der Vorteil: Statt Maven lokal auf dem CI-Server zu installieren, läuft der Build in einem Maven-Container. Das eliminiert “Works on my machine”-Probleme. Jeder Build nutzt exakt die gleiche Maven- und Java-Version.
Build-Integration in CI
Die Integration von Build-Prozessen in CI erfolgt in mehreren Schritten:
1. Source Code Management (SCM) Integration
Der CI-Server überwacht das Repository (Git) und startet bei jeder Änderung automatisch einen Build.
2. Build-Artefakte verwalten
Nach erfolgreichem Build werden Artefakte (JAR, WAR, Docker Images) gespeichert und archiviert.
3. Feedbackschleife
Entwickler erhalten sofortiges Feedback:
- Erfolg: Build läuft durch, grünes Licht
- Fehler: Build schlägt fehl, Benachrichtigung (E-Mail, Slack)
Wichtig: Der CI-Server benötigt Zugriff auf alle Dependencies (Maven Central, npm Registry, etc.).
Schnelles Feedback ist entscheidend: Entwickler sollten innerhalb von Minuten wissen, ob ihr Code funktioniert.
Automatisierte Tests in CI
Automatisierte Tests sind das Rückgrat von CI. Sie gewährleisten, dass Code-Änderungen keine Fehler einführen.
Test-Typen in CI:
| Test-Typ | Zweck | Dauer | Wann ausführen? |
|---|---|---|---|
| Unit Tests | Einzelne Funktionen testen | Sekunden | Bei jedem Commit |
| Integrationstests | Komponenten-Zusammenspiel | Minuten | Bei jedem Commit |
| E2E Tests | Gesamte User-Flows | Minuten-Stunden | Vor Deployment |
Best Practices:
- Unit Tests: Schnell, isoliert, hohe Abdeckung
- Integrationstests: Datenbank, APIs, Services
- E2E Tests: Nur kritische User-Journeys
Je früher Tests laufen, desto günstiger sind Fehler zu beheben.
Code-Qualitätsprüfungen in CI
Code-Qualität ist mehr als nur funktionierende Tests. Static Analysis Tools prüfen Code auf potenzielle Probleme, bevor sie zu echten Bugs werden.
Wichtige Tools:
- SonarQube: Code-Qualität, technische Schulden, Sicherheitslücken
- ESLint (JavaScript): Code-Style, Best Practices, potenzielle Fehler
- Pylint (Python): Code-Quality-Checks für Python
- SAST (Static Application Security Testing): Sicherheitslücken automatisch erkennen
Best Practices:
- Quality Gates: Build schlägt fehl bei kritischen Issues
- Code Coverage: Mindestens 70-80% Test-Abdeckung
- Security Scans: Regelmäßig auf Vulnerabilities prüfen
Beispiel (GitLab CI):
Code-Quality-Job läuft parallel zu Tests und meldet Probleme direkt im Merge Request.
Automatisierte Qualitätsprüfungen fangen Probleme, bevor sie in Production gehen.
Ausblick
Du hast die Grundlagen von Continuous Integration kennengelernt und verstehst jetzt, wie CI-Pipelines funktionieren, welche Tools es gibt und wie automatisierte Tests integriert werden.
In der nächsten Lerneinheit “Release-Management” lernst du:
Builds sind fertig, Tests laufen durch – aber wie bringst du die Software kontrolliert zu den Nutzern? In der nächsten Lerneinheit erfährst du, wie Release-Management diesen kritischen Schritt koordiniert.
Du lernst Release-Strategien wie Continuous Delivery und Continuous Deployment kennen, verstehst Versionierung mit Semantic Versioning und erfährst, wie Release-Dokumentation und -Kommunikation professionell durchgeführt werden.
So schließt sich der Kreis vom automatisierten Build zur strukturierten Auslieferung an Produktivumgebungen.
Tipp: CI sorgt für getestete Builds – Release-Management steuert, WANN und WIE diese Builds zu Nutzern gelangen.