top of page
  • Lukas Oberhänsli

Continuous Integration und Continuous Delivery (CI/CD)

Die Zeiten von manuellen, aufwändigen und fehleranfälligen Softwareinstallationen sind vorbei!


Continuous Integration (CI) sorgt dafür, dass ein Softwareprodukt stets auf dem neuesten Stand bleibt. Jede Änderung wird kontinuierlich in die bestehende Software eingebettet und auf ihre Qualität geprüft.


Mit Continuous Delivery (CD) konzentrieren wir uns auf die effiziente Auslieferung dieser Software. Dank automatisierten und wiederholbaren Prozessen kann die Software zu jeder Zeit problemlos veröffentlicht werden.


In diesem Blogbeitrag werden wir die Best-Practices von CI/CD beleuchten, die einen echten Unterschied in der Softwareentwicklung machen. Zudem geben wir Tipps, worauf bei der Implementierung einer effizienten Integrations- und Delivery-Pipeline zu achten ist.


Continuous Integration (CI)

Kontinuierliche Integration zielt darauf ab, die Änderungen so häufig und schnell wie möglich in die Software einzuspeisen. Schon in der Planungsphase der zu entwickelnden Features sollte dieser Ansatz berücksichtigt werden: Idealerweise werden Funktionen so kompakt gestaltet, dass sie innerhalb eines Arbeitstages entwickelt und integriert werden können. Während dieses Integrationsprozesses sind verschiedene Schritte vorgesehen, die dazu dienen, die Qualität der Software zu gewährleisten.


Branching-Strategie

Unter "Branching" versteht man das Erstellen neuer Versionszweige innerhalb einer Software. Jeder Zweig, auch "Branch" genannt, stellt eine eigenständige Version der Software dar. Bei der Integration fliessen die Änderungen dieser Branches in den Hauptzweig, oft als "Main" oder "Master" bezeichnet, ein. Eine durchdachte und einfache Branching-Strategie ist das Fundament einer erfolgreichen Continuous Integration.


Der direkteste Ansatz besteht darin, jede vorgenommene Änderung – auch "Commit" genannt – unmittelbar in den Haupt-Branch zu überführen. Dieses Vorgehen wird als Trunk Based Development (TBD) bezeichnet. Dadurch bleibt der Haupt-Branch stets auf dem neusten Stand. Zusätzliche Branches können bei Bedarf, beispielsweise für spezielle Releases, ergänzend erstellt werden.

Trunk Based Development (TBD)

Eine weitere bewährte Branching-Strategie ist der Github-Flow. Dabei werden für jedes neue Feature eigene Branches – sogenannte Feature-Branches – erstellt. Nach der Fertigstellung des Features wird dieser Branch in den Haupt-Branch integriert.

Github-Flow

Je komplexer die Branching-Strategie, desto länger kann der Integrationsprozess dauern, wodurch das Risiko von Konflikten bei der Integration steigt. Daher ist es ratsam, komplexe Branching-Strategien, wie beispielsweise Git-Flow, zu meiden.


Qualitätssicherung

Um die Qualität des Haupt-Branchs zu gewährleisten, werden bestimmte Qualitätsstandards festgelegt und bei jeder Integration kontrolliert. Einige essenzielle Qualitätsstandards bei der Integration sind:

  • Code-Kompillierung: Mit jeder Integration wird der Code neu kompiliert, um syntaktische Fehler zu vermeiden.

  • Automatisierte Tests: Der Code sollte durch diverse Testverfahren, sei es Unit-Tests, Integration-Tests oder andere Methoden, umfassend und automatisch überprüft werden.

  • Code-Coverage: Diese stellt sicher, dass der Code in ausreichendem Masse durch Testfälle abgedeckt ist.

  • Statische Code-Analyse: Verschiedene Tools können den Code auf Muster scannen, die häufig Fehler verursachen oder die Qualität beeinträchtigen.

Es gibt zahlreiche weitere Qualitätsstandards, die hinzugefügt werden können. Es ist jedoch wichtig, dass diese Standards automatisiert umsetzbar sind, um den Integrationsprozess effizient zu gestalten.


Code Reviews durch Pull Requests

Ein Pull Request (PR) oder auch Merge Request bietet die Möglichkeit, vorgeschlagene Code-Änderungen aus einem Feature-Branch in den Haupt-Branch zu integrieren. Diese Änderungen werden typischerweise von einem anderen Teammitglied überprüft, bevor sie in den Haupt-Branch überführt werden.


Obwohl dieser Ansatz viele Vorteile hat, gibt es in Verbindung mit CI einige Herausforderungen:

  1. Verzögerung im Integrationsprozess: Durch die Verwendung eines zusätzlichen Feature-Branches und des Pull Requests kann sich der Integrationsprozess verlangsamen. Es ist nicht unüblich, dass PRs mehrere Tage offen bleiben, was dem Grundgedanken der Continuous Integration widerspricht.

  2. Falsches Sicherheitsgefühl: Oftmals entsteht der Eindruck, dass der Review-Prozess als letzte Kontrollinstanz dient. Allerdings hat der Reviewer in der Praxis meist nur einen oberflächlichen Einblick in die Änderungen und benötigt deutlich mehr Zeit für eine gründliche Prüfung.

Während Pull Requests hervorragend dazu dienen, Wissen zu teilen und Qualitätsstandards zu wahren, können regelmässige Code-Reviews und Pair-Programming effektivere Methoden sein, um den Integrationsprozess effizient zu gestalten.


Automatisierte Tests

Ein Schlüsselelement für kontinuierliche Qualität in der Softwareentwicklung sind automatisierte Tests. Diese können in Form von Unit-Tests, Integration-Tests oder anderen Testverfahren durchgeführt werden. Jeder Test dient dazu, spezifische Aspekte des Codes oder der Funktionalität zu überprüfen, wodurch Fehler frühzeitig erkannt und behoben werden können. Mehr Details zu den verschiedenen Testverfahren und deren Einsatzgebieten erfährst du in unserem Blogbeitrag zum Thema "Software Testing".


Continuous Delivery (CD)

Mit der häufigen Integration von Code durch CI ist der nächste logische Schritt, diese Updates zu verifizieren und an den Kunden auszuliefern. Continuous Delivery stellt sicher, dass die Software zu jedem Stand veröffentlicht werden kann.


Kundenfeedback

Continuous Delivery ermöglicht es, schnelleres Feedback von Kunden zu erhalten. Mit CD werden Softwareupdates regelmässig und in kürzeren Zyklen veröffentlicht, was bedeutet, dass Kunden schneller Zugang zu neuen Funktionen und Verbesserungen erhalten. Dies ermöglicht es, direktes Feedback zu sammeln und Anpassungen oder Optimierungen vorzunehmen.


Fehlerbehebung

Durch die kontinuierliche und automatisierte Auslieferung von Softwareupdates ermöglicht CD das frühe Erkennen und schnelle Beheben von Fehlern. Im Gegensatz zu traditionellen Methoden, bei denen Fehler möglicherweise erst nach einem umfangreichen Release aufgedeckt werden, erlaubt CD, Fehler schon in kleineren Updates zu identifizieren. Dies verringert nicht nur die Komplexität der Fehlerbehebung, sondern auch die Zeit von der Entdeckung bis zur Lösung des Problems.


Automatisierte CI/CD Pipelines

Pipelines orchestrieren und automatisieren Continuous Integration und Continuous Delivery. Sie sind darauf ausgelegt, manuelle Eingriffe so weit wie möglich zu reduzieren.

CI/CD Pipeline

Im oben gezeigten Beispiel startet jede Code-Änderung automatisch einen neuen Build im Haupt-Branch. Dieser Build beinhaltet nicht nur die Code-Änderungen, sondern auch die dazugehörigen Tests, welche anschliessend automatisch ausgeführt werden. Wenn alle Schritte der CI-Pipeline erfolgreich durchlaufen wurden, ist die Softwareversion bereit für die Auslieferung.


Die CD-Pipeline beginnt mit der Erstellung eines spezifischen Release-Branches. Der Release-Branch kann entweder den letzten bestehenden Build verwenden oder aber einen neuen Build anstossen. Die Software wird dann weiteren Tests unterzogen, einschliesslich Regression-Tests und manuellen User Acceptance Tests. Nach erfolgreichem Abschluss dieser Tests wird das Softwarepaket für den Release vorbereitet.


Continuous Deployment

Während Continuous Delivery sicherstellt, dass ein auslieferbares Softwareprodukt bereitsteht, bedeutet dies nicht automatisch, dass jede Änderung sofort in der Produktionsumgebung eingespielt wird. Hier kommt Continuous Deployment ins Spiel und sorgt dafür, dass Änderungen automatisch und direkt auf die Produktionsumgebung ausgerollt werden, ohne manuelles Eingreifen.


Allerdings ist eine derart hohe Frequenz von Releases nicht für jedes Softwareprodukt oder jede Geschäftsanforderung geeignet. Unternehmen müssen abwägen, welcher Ansatz am besten zu ihren Zielen, ihrem Produkt und ihrer Zielgruppe passt.


Fazit

Zusammen bilden Continuous Integration und Continuous Delivery ein leistungsstarkes Duo, das den Softwareentwicklungsprozess optimiert. CI gewährleistet durch ständige Integration und Tests, dass Code-Änderungen höchsten Qualitätsstandards entsprechen. Dies minimiert das Risiko von Fehlern und sorgt dafür, dass diese, falls sie auftreten, sofort erkannt und behoben werden können. CD wiederum ermöglicht es, dass Software in einem stabilen, automatisierten Prozess bereitgestellt wird. Dies beschleunigt den Weg von der Code-Änderung bis zur Produktion und gewährleistet gleichzeitig, dass die Auslieferung reibungslos und konsistent erfolgt.

bottom of page