Kontinuierliche Integration
Kontinuierliche Integration (auch fortlaufende oder permanente Integration; englisch continuous integration, CI) ist ein Begriff aus der Software-Entwicklung, der den Prozess des fortlaufenden Zusammenfügens von Komponenten zu einer Anwendung beschreibt. Das Ziel der kontinuierlichen Integration ist die Steigerung der Softwarequalität. Typische Aktionen sind das Übersetzen und Linken der Anwendungsteile, prinzipiell können aber auch beliebige andere Operationen zur Erzeugung abgeleiteter Informationen durchgeführt werden. Üblicherweise wird dafür nicht nur das Gesamtsystem neu gebaut, sondern es werden auch automatisierte Tests durchgeführt und Softwaremetriken zur Messung der Softwarequalität erstellt. Der gesamte Vorgang wird automatisch ausgelöst durch Einchecken in die Versionsverwaltung.
Eine Vorstufe der kontinuierlichen Integration ist der Nightly Build (nächtlicher Erstellungsprozess). In der Praxis trifft man auch auf kontinuierliche Integration, gepaart mit einem Nightly Build, um die Vorteile beider Systeme zu kombinieren. In der Methode DevOps wird diese Automatisierung auch Pipeline genannt, da die einzelnen Schritte sequentiell abgearbeitet werden. Die Pipeline ermöglicht hier, die Entwicklungsgeschwindigkeit zu erhöhen, denn schon nach wenigen Minuten erhält der Entwickler Rückmeldung, ob die Qualitätsansprüche erreicht wurden oder nicht.
Eine Weiterentwicklung der kontinuierlichen Integration stellt die Continuous Delivery (CD) dar. Dabei wird in bestimmten Zeitabständen oder bei Erreichen einer bestimmten Qualitätsmetrik eine neue Version der Software ausgeliefert.
Grundsätze
Spätestens seit das Konzept der permanenten Integration von Kent Beck im Rahmen von Extreme Programming populär gemacht wurde, ist der Begriff der kontinuierlichen Integration an sich bekannt, für die erfolgreiche Einführung müssen allerdings einige Grundsätze (vgl. "Continuous Integration"[1] von Martin Fowler) befolgt werden:
- Gemeinsame Codebasis
- Um innerhalb einer Arbeitsgruppe sinnvoll integrieren zu können, muss eine Versionsverwaltung existieren, in die alle Entwickler ihre Änderungen kontinuierlich integrieren können.
- Automatisierte Übersetzung
- Jede Integration muss einheitlich definierte Tests wie statische Code-Überprüfungen durchlaufen, bevor die Änderungen integriert werden. Dafür ist eine automatisierte Übersetzung notwendig.
- Um Testergebnisse von den Arbeitsumgebungen unabhängig zu machen, empfiehlt sich der Einsatz von separaten Test-Umgebungen. Damit können auf diesen Rechnern auch gezielt Verfahren implementiert werden, um die Testlaufzeit zu minimieren.
- Kontinuierliche Test-Entwicklung
- Jede Änderung sollte möglichst zeitgleich mit einem dazugehörigen Test entwickelt werden (beispielsweise mittels testgetriebener Entwicklung). Mit Hilfe von kontrollflussorientierten Testverfahren (Analyse der Code-Überdeckung, engl.: "Code Coverage Analysis") kann diese Vorgehensweise dokumentiert und kontrolliert werden.
- Häufige Integration
- Jeder Entwickler sollte seine Änderungen so oft wie möglich in die gemeinsame Code-Basis integrieren. Mit kurzen Integrations-Intervallen reduziert man das Risiko fehlschlagender Integrationen und sichert gleichzeitig den Arbeitsfortschritt der Entwickler in der gemeinsamen Code-Basis (Datensicherung, engl.: "backup").
- Integration in den Hauptbranch
- Jeder Entwickler sollte seine Änderungen in den Hauptbranch des Produktes integrieren, wo dann automatisch ein Build- und Testzyklus gestartet wird. Dieser Build wird der kontinuierliche Integrationsbuild genannt.
- Kurze Testzyklen
- Der Test-Zyklus vor der Integration sollte kurz gehalten sein, um häufige Integrationen zu fördern. Mit steigenden Qualitätsanforderungen für die einzelnen Integrationen steigt auch die Laufzeit zur Ausführung der Test-Zyklen. Die Menge der vor der Integration durchgeführten Tests muss sorgfältig abgewogen werden, weniger wichtige Tests werden dann nur nach der Integration durchgeführt.
- Gespiegelte Produktionsumgebung
- Die Änderungen sollten in einem Abbild der realen Produktionsumgebung getestet werden.
- Einfacher Zugriff
- Auch Nicht-Entwickler brauchen einfachen Zugriff auf die Ergebnisse der Software-Entwicklung. Dies müssen nicht notwendigerweise Quellen sein, sondern kann beispielsweise das in das Testsystem gespielte Produkt für Tester, die Qualitäts-Zahlen für Qualitäts-Verantwortliche, die Dokumentation oder ein fertig paketiertes Abbild für Release Manager sein.
- Automatisiertes Reporting
- Die Ergebnisse der Integrationen müssen leicht zugreifbar sein. Sowohl Entwickler als auch andere Beteiligte müssen leicht Informationen darüber bekommen können, wann die letzte erfolgreiche Integration ausgeführt wurde, welche Änderungen seit der letzten Lieferung eingebracht wurden und welche Qualität die Version hat.
- Automatisierte Verteilung
- Jede Version sollte leicht in eine Produktionsumgebung (oder ein Abbild derselbigen) überführt werden können. Hierfür sollte die Softwareverteilung automatisiert sein.
Kontinuierliche Integration kann auf jedem Rechner mit Zugang zum Quellcode durchgeführt werden. Es ist insbesondere möglich, die Integration gleichzeitig auf unterschiedlichen Systemen (etwa verschiedenen Betriebssystemen) durchzuführen.
Vorteile
- Integrations-Probleme werden laufend entdeckt und behoben (gefixt) – nicht erst kurz vor einem Meilenstein.
- Frühe Warnungen bei nicht zusammenpassenden Bestandteilen.
- Sofortige Unittests entdecken Fehler zeitnah. Im Idealfall kann so beispielsweise direkt bemerkt werden, wenn ein Commit einen Fehler einführt.
- Ständige Verfügbarkeit eines lauffähigen Standes für Demo-, Test- oder Vertriebszwecke.
- Die sofortige Reaktion des Systems auf das Einchecken eines fehlerhaften oder unvollständigen Codes „erzieht“ die Entwickler im positiven Sinne zu einem verantwortlicheren Umgang und kürzeren Checkin-Intervallen. Der Merge-Aufwand wird immer größer, je länger man mit der Integration wartet.
Nachteile
- Es gibt keine traditionellen Meilensteine im herkömmlichen Sinne mehr.
Software
Beispielhafte Werkzeuge für kontinuierliche Integration:
- Bamboo – ein kommerzieller Server für fortlaufende Integration von Atlassian.
- Rational Build Forge – ein Framework der IBM-Tochtergesellschaft Rational Software, das die Build- und Release-Prozesse automatisieren soll.
- Continuum – ein Subprojekt des Apache Maven Projekts. Unterstützt Maven 1, Maven 2, Ant und Shell-Skripte.
- CruiseControl – ein Java-basiertes Framework für kontinuierliche Erstellungsprozesse, Derivate auch für das .Net-Framework und Ruby.
- GitLab – mit MIT-Lizenz, unterstützt Git und Shell-Skripte.
- Hudson – mit MIT-Lizenz, geschrieben in Java, läuft in Servlet-Container, unterstützt CVS, Subversion, Ant, Maven und Shell-Skripte.
- Jenkins – mit MIT-Lizenz, geschrieben in Java, läuft standalone oder in Servlet-Container, unterstützt CVS, Apache Subversion, Git, ClearCase, Ant, Maven, Perforce und Shell-Skripte (Hudson Fork).
- Team Foundation Server – eine Plattform für kollaborative Softwareprojekte auf Basis von Microsoft SQL Server und Windows SharePoint Services.
- Teamcity – ein Werkzeug von JetBrains, webbasiert, verträglich mit den integrierten Entwicklungsumgebungen IntelliJ IDEA, Eclipse und Microsoft Visual Studio.
- Travis CI – gehostetes und verteiltes Tool für GitHub-Projekte.
Weblinks
- Multi-stage Continuous Integration von Damon Poole (englisch)
- Continuous integration von Martin Fowler (eine Einführung, englisch)
- Continuous Integration im Portland Pattern Repository (englisch)
- Continuous Integration Server Feature Matrix (Übersicht über diverse Werkzeuge, englisch)
- Continuous Integration: The Cornerstone of a Great Shop von Jared Richardson (Einführung, englisch)
- Continuous Integration on a Dollar a Day von James Shore (Anleitung, englisch)
- A Recipe for Build Maintainability and Reusability von Jay Flowers (englisch)
Einzelnachweise
- FOWLER, Martin. Continuous Integration (englisch)