Was ist eine CI/CD-Pipeline?

Was genau ist eine Continuous-Integration-/Continuous-Delivery-Pipeline? Und wie baut man eine Pipeline auf?

Wenn Sie bereits unsere Anleitung für Continuous Integration, Continuous Delivery und Continuous Deployment (zusammenfassend als CI/CD bezeichnet) kennen, sind Sie mit ziemlicher Sicherheit auf den Begriff „automatisierte Pipeline“ gestoßen und wissen, dass diese bei der CI/CD-Umsetzung eine zentrale Rolle spielt.

CI/CD ist eine DevOps-Praxis, die Ihnen hilft, Software schneller bereitzustellen, ohne bei der Qualität Kompromisse einzugehen. CI/CD erfordert häufige Commits, strenge Tests dieser Aktualisierungen und eine schnelle Reaktion auf Feedback. Eine automatisierte CI/CD-Pipeline ist für diese Arbeitsweise unerlässlich.

CI/CD-Pipelines erklärt

Wenn wir über eine CI/CD-Pipeline sprechen, meinen wir damit den Prozess, die Ihr Code durchläuft, um von Ihrer Entwicklungsumgebung über Test- und Staging-Phasen in die Hände Ihrer Benutzercommunity zu gelangen.

Das Ziel von CI/CD ist es, diesen Prozess regelmäßig auszuführen – mehrmals am Tag oder sogar stündlich. Daher ist es wichtig, die CI/CD-Pipeline so weit wie möglich zu automatisieren. Wenn ein Schritt erfolgreich abgeschlossen wurde, sollte er automatisch den nächsten auslösen. Wenn ein Schritt fehlschlägt, sollte dieses Feedback schnell übermittelt werden, damit das Problem behoben werden kann.

Die Automatisierung Ihrer CI/CD-Pipelines beschleunigt nicht nur den Gesamtprozess der Erstellung, des Testens und der Bereitstellung von Software, sondern stellt auch sicher, dass jeder Schritt stets zuverlässig und auf die gleiche Weise durchgeführt wird.

Phasen einer Build-Pipeline

Zwar hängt die genaue Form Ihrer CI/CD-Pipeline von Ihrem Produkt und Ihrem Unternehmen ab, doch alle Pipelines folgen grob betrachtet einem allgemeinen Muster:

  1. Der Prozess beginnt mit einem Commit in den Main-Branch (oder einen beliebigen anderen Branch, den Sie zum CI-Branch erkoren haben). Dieser Commit löst entweder einen Buildvorgang oder eine erste Unit-Test-Phase aus. Die Ergebnisse werden in der Regel in einem Dashboard angezeigt. Die Pipeline kann so gestaltet werden, dass sie bei Build- oder Testfehlern anhält, damit Sie sich um jedes Problem kümmern können, bevor Sie fortfahren. Sobald eine Korrektur durchgeführt wurde, beginnt die Pipeline automatisch wieder von vorne, um sicherzustellen, dass alles wie vorgesehen funktioniert. Alternativ können Sie die Pipeline so konfigurieren, dass sie weiterläuft und Fehler zur Untersuchung markiert werden.
  2. Die nächste Phase umfasst eine Reihe von automatisierten Tests, wobei nach jeder Testrunde Feedback bereitgestellt wird. Üblicherweise sind die Tests so angeordnet, dass die schnellsten Tests zuerst ausgeführt werden, um so früh wie möglich Feedback zu erhalten. Ressourcenintensive Tests werden zuletzt ausgeführt, aber nur, wenn alle vorangegangenen Schritte erfolgreich abgeschlossen wurden. Auch hier gilt: Wenn ein Test fehlschlägt, können Sie die Pipeline stoppen und neu beginnen oder fortfahren und das Problem zur Untersuchung melden.
  3. Sobald die automatisierten Tests abgeschlossen sind, wird die Software in der Regel in verschiedenen Staging-Umgebungen bereitgestellt. Einige davon können für weitere manuelle Tests und andere für Schulungen, Support oder Kundenvorführungen verwendet werden.
  4. In der letzten Phase der CI/CD-Pipeline-Architektur werden die Änderungen live geschaltet. Das Release kann entweder manuell (bei Continuous Delivery) oder automatisch (bei Continuous Deployment) erfolgen.

Sehen wir uns jetzt einige wichtige Aspekte dieser Phasen etwas genauer an.

Flags und Branches

Der erste Schritt zur Einführung von Continuous Integration besteht darin, Ihren gesamten Codebestand in ein Versionsverwaltungssystem (VCS, auch Source Control Management oder SCM genannt) zu überführen – zum Beispiel Git, Mercurial oder Perforce. Wenn das geschafft ist, müssen Sie alle Mitglieder Ihres Teams dazu bringen, häufige Commits vorzunehmen. Jeder Commit in den Main-Branch löst einen Continuous-Integration-Pipeline aus: Der Code wird kompiliert und getestet, um Ihnen schnelles Feedback zu Ihren Änderungen zu geben.

Häufige Commits sind zwar ein wichtiger Bestandteil der CI/CD-Pipeline, aber während der Arbeit an einem größeren Feature, das mehrere Tage oder Wochen in Anspruch nimmt, können sich regelmäßige Commits während dieses Prozesses etwas kontraproduktiv anfühlen.

Einerseits erhalten Sie schnelles Feedback, wenn Sie Ihre Änderungen in regelmäßigen Abständen durch die Pipeline schieben. Außerdem ist die Wahrscheinlichkeit von komplexen Merge-Konflikten geringer, als wenn Sie warten, bis Sie die Funktion fertiggestellt haben.

Andererseits ist es vielleicht nicht ideal, unvollendete Funktionen durch die Pipeline zu schieben. Die Weitergabe unvollständiger Arbeit an Benutzer*innen, selbst in Staging-Umgebungen, ist ebenfalls nicht wünschenswert.

Feature-Flags und Feature-Branches bieten eine Lösung für dieses Problem. Mit Feature-Flags können Sie angeben, in welchen Umgebungen Ihr Code sichtbar sein soll. Ihre Änderungen sind zwar im Hauptbranch vorhanden und für Ihr Team sichtbar, aber Sie können frei entscheiden, wann die Funktionalität auch in den Staging-Umgebungen und in der Produktion freigeschaltet wird.

Mit Feature-Branches entwickeln Sie Ihr Feature in einem separaten Branch, ohne auf die Vorteile automatisierter Build- und Testabläufe zu verzichten. Indem Sie die CI/CD-Pipeline bei jedem Commit in einen Feature-Branch auslösen, erhalten Sie wie bei einem Main-Commit schnelles Feedback zu Ihrer Arbeit.

Build- und Testablauf

Nachdem Sie mit einem Commit eine Instanz Ihrer Pipeline ausgelöst haben, sind als Nächstes die Build- und Testvorgänge an der Reihe. Wenn Sie über automatisierte Unit-Tests verfügen, werden diese normalerweise zusammen mit Linting- und statischen Analyseprüfungen vor dem Buildvorgang ausgeführt.

Das verwendete Build-Tool (z. B. Ant oder Maven) sowie die Details der Build-Schritte hängen von der Sprache und dem Framework ab, mit denen Sie arbeiten. Indem Sie den automatisierten Buildvorgang auf einem dedizierten Buildserver ausführen, können Sie das klassische, durch fehlende Abhängigkeiten verursachte „Aber auf meinem System funktioniert es doch“-Syndrom vermeiden.

Der Build-Schritt erzeugt die Artefakte der Anwendung, zu denen Installationsprogramme, Binärdateien oder Container gehören können. Diese Artefakte werden dann in Testumgebungen eingesetzt und mit anderen Systemkomponenten integriert, um übergeordnete automatisierte Tests durchzuführen: Integrationstests, Komponententests und End-to-End-Tests sowie nicht-funktionale Tests wie Leistungs- und Sicherheitsanalysen.

Diese Tests können parallel ausgeführt werden, um die Pipeline zu beschleunigen und Ihnen schneller Feedback zu geben.

Container und VMs im Vergleich

Damit Ihre automatisierten Tests zuverlässige Ergebnisse liefern, müssen Sie sicherstellen, dass sie stets auf die gleiche Weise ausgeführt werden.

Idealerweise sollten Ihre Testumgebungen so konfiguriert werden, dass sie der Produktionsumgebung möglichst ähnlich sind, und sie sollten zwischen den Testläufen zurückgesetzt werden, um zu vermeiden, dass Variationen in der Umgebung Ihre Testergebnisse verfälschen.

Virtuelle Maschinen (VMs) sind seit langem eine beliebte Wahl für die Ausführung von Testumgebungen, da Sie die Umgebung für jeden neuen Buildvorgang skriptbasiert zurücksetzen können.

Das Herunterfahren und Hochfahren neuer VMs kostet jedoch Zeit, und Ihre Skripte müssen eine Konfiguration für jede virtuelle Umgebung enthalten, um alle zum Ausführen der Software notwendigen Abhängigkeiten bereitzustellen. Wenn neue Abhängigkeiten hinzukommen, müssen die Umgebungsskripte angepasst werden – ein Detail, das gerne übersehen wird, mit dem Ergebnis, dass der Build nicht durchläuft.

Diese Probleme können Sie vermeiden, indem Sie Ihren Code in einem ersten Build-Schritt in einen Container packen. Ein Container enthält alle Abhängigkeiten, die die Software zum Ausführen benötigt. Dies sorgt für eine einfache Portabilität und eine leichte Bereitstellung in verschiedenen Umgebungen.

Wenn Sie Ihre CI/CD-Pipelines auf Ihrer eigenen Infrastruktur hosten, benötigen Sie zwar immer noch VMs für die Bereitstellung der Container, aber der Aufwand für die Vorbereitung der Testumgebungen ist geringer. Wenn Sie Ihre Pipeline in der Cloud ausführen, können Sie durch den Einsatz von Containern die Vorteile von Managed Services nutzen und die Verwaltung der Infrastruktur an Ihren Cloud-Anbieter auslagern.

Vorproduktions­umgebungen

Die Anzahl der Test- und Staging-Umgebungen in Ihrer Pipeline-Architektur hängt von Ihrem Produkt und den Anforderungen der Beteiligten ab. Mögliche Einsatzbereiche sind explorative Tests, Sicherheitsüberprüfungen, Benutzerforschung, Verkaufsvorführungen, Schulungsumgebungen und Sandbox-Umgebungen zum Reproduzieren von Kundenproblemen.

Das automatisierte Erstellen und Bereitstellen dieser Umgebungen ist effizienter als das manuelle Zurücksetzen. Sie können verschiedene Pipeline-Trigger für verschiedene Umgebungen konfigurieren.

So lässt sich beispielsweise festlegen, dass Testumgebungen für jeden Buildvorgang aktualisiert werden, während in Staging-Umgebungen nur einmal täglich oder wöchentlich der neueste erfolgreiche Build bereitgestellt wird.

Bereitstellen

Wenn Ihre Codeänderungen alle vorherigen Pipeline-Phasen erfolgreich durchlaufen haben, sind sie bereit für die Produktionsfreigabe. Dieser letzte Schritt kann manuell oder automatisch erfolgen.

Eine manuelle Freigabe (Continuous Delivery) ist sinnvoll, wenn:

  • Sie möchten kontrollieren, wann neue Funktionen zur Verfügung gestellt werden.
  • Ihr Bereitstellungsprozess ist mit Ausfallzeiten für Ihre Benutzer*innen verbunden.
  • Benutzer*innen müssen Ihr Produkt installieren, und Sie möchten die Änderungen nach einem regelmäßigen Zeitplan bereitstellen.

Bei der kontinuierlichen Bereitstellung erfolgt die Freigabe automatisch. Änderungen werden freigeschaltet, wenn sie alle vorherigen Phasen durchlaufen haben. Für größere Teams mit häufigen Commits kann dies bedeuten, dass Updates Dutzende Male pro Tag an die Benutzer*innen verteilt werden – eine Leistung, das ohne eine automatisierte Pipeline praktisch unmöglich ist.

CI/CD-Pipelines verstehen: Zusammenfassung

CI/CD ist eine DevOps-Praxis, bei der Automatisierung eingesetzt wird, um schnelles Feedback zu jeder Phase des Softwareentwicklungslebenszyklus zu erhalten. Die Entdeckung von Problemen, die durch Ihre letzten Codeänderungen entstanden sind, macht die Softwareentwicklung effizienter. Durch die Linksshift-Methode (frühere Interaktionen und früheres Feedback) sind Sie in der Lage, schnell zu scheitern, und der Aufbau einer automatisierten Pipeline hilft, diese Techniken in die Praxis umzusetzen.

Bei der Gestaltung Ihres eigenen CI/CD-Prozesses empfiehlt es sich, schrittweise vorzugehen und mit Continuous Integration zu beginnen. Die genauen Phasen der Pipeline und die logischen Schritte zum Auslösen der einzelnen Phasen hängen von Ihrem Produkt und Ihrer Organisation ab.

Wenn Sie sich für eine CI/CD-Plattform entscheiden, die eine flexible Anpassung der Pipeline an Ihre Anforderungen ermöglicht und trotzdem einfach zu verwalten ist, können Sie einen zuverlässigen Releaseprozess aufbauen und die Qualität Ihrer Software verbessern.

So kann TeamCity helfen

Unsere TeamCity-Pipelines-Lösung hilft Ihnen, Ihre bestehenden CI/CD-Prozesse zu automatisieren.

Durch die Unterstützung aller führenden Versionsverwaltungen und die Integration mit gängigen Build-, Test- und Paketmanagement-Tools können Sie mit TeamCity Pipelines Ihre Entwicklungsabläufe in effiziente, automatisierte Pipelines verwandeln.

Flexible Trigger-Optionen und ein visueller Pipeline-Editor erleichtern die Konfiguration von Pipelines für jeden Workflow. Ihre Konfigurationen werden automatisch als Code gespeichert – Sie können Ihre Pipelines unkompliziert in der grafischen Bedienoberfläche erstellen und verwalten und trotzdem von den Vorteilen profitieren, die Konfiguration als Code bietet.

Die On-Premises- und Cloud-nativen Bereitstellungsoptionen von TeamCity geben Ihnen die Flexibilität, Ihre Pipelines in beliebigen Umgebungen auszuführen und bei Bedarf zu skalieren. Funktionen wie Testparallelisierung und Echtzeit-Feedback helfen Ihnen dabei, Fehler schnell zu erkennen und so die Produktivität Ihrer Entwickler*innen zu steigern.

Sie haben noch Fragen? Erfahren Sie mehr in unserem FAQ-Bereich.