Continuous Integration & Delivery

Continuous Integration und Continuous Delivery sind wichtige Konzepte in der Softwareentwicklung in Hinblick auf die schnelle Anpassung an Marktbedürfnisse. Da die digitale Transformation die Marktteilnehmer vor sich hertreibt, sind die Unternehmen darauf angewiesen, Software schneller entwickeln und in die Produktion bringen zu können.

Digitale Transformation stellt Unternehmen vor neue Herausforderungen

Die digitale Transformation betrifft praktisch alle Unternehmen und macht Marktanpassungen in immer kürzerer Zeit erforderlich. Für die Unternehmen ist es daher entscheidend, so schnell wie möglich mit neuen Versionen bereits eingesetzter Software oder ganz neuen Softwarelösungen beliefert zu werden. Im Ergebnis bedeutet das, dass die Softwareentwicklung agiler werden muss. Der kontinuierliche Ansatz ist hier eine Möglichkeit, auf die Bedürfnisse der Kunden einzugehen und neue Software schneller bereitstellen zu können. Bei diesem Ansatz sollen Funktionstests und die Qualitätssicherung nach Möglichkeit automatisiert werden und bei jedem Entwicklungsschritt stattfinden. Der klassische Ansatz sah so aus, dass ein Softwareprojekt erst abgeschlossen wird, bevor der Entwickler den Code an die Testabteilung und an die Abteilung für Qualitätssicherung übergibt. Dieser Ansatz ist heute jedoch nicht mehr flexibel genug und ist mit der Zeit immer stärker von neuen Ansätzen verdrängt worden. Probleme mit dem Programmcode gilt es heute schneller zu erkennen und zu beseitigen.

Das Ende schwerfälliger Großprojekte

In früheren Jahrzehnten war die Veröffentlichung neuer Softwareversionen im Jahresrhythmus noch der Normalfall. Das Anstoßen neuer Versionen mündete häufig in Software-Großprojekte, die mit immensem Zeit- und Mittelaufwand bewältigt werden mussten. Ergebnisse waren so erst nach einer gewissen Zeit sichtbar. Das machte es schwierig, den Entwicklungsprozess zu lenken. Statt langer Entwicklungsmarathons kommt es heute eher auf den Entwicklungssprint an: Statt eine Software in ihrer Gesamtheit fertigzustellen, steht die Entwicklung kleiner Module oder kleiner Bausteine im Vordergrund. Statt einzelne Teile des Programmcodes mühsam in manueller Arbeit zu testen, wird der Testvorgang automatisiert.

Ein solches Vorgehen zahlt sich für den Kunden nicht nur deshalb aus, weil er schneller Ergebnisse sieht. Der Kunde hat auch die Möglichkeit, in den Entwicklungsprozess rechtzeitig einzugreifen. So lässt sich eine Software entwickeln, die dem Kundenwunsch besser entspricht. Bei Softwareprojekten ist es eher die Regel als die Ausnahme, dass sich die Anforderungen während der Entwicklungsphase noch verändern. Beim kontinuierlichen Ansatz kann auf solche Änderungen der Anforderungen flexibel reagiert werden. Das Ergebnis ist eine Software, die noch genauer den Zielvorgaben entspricht.

Ein Problem bei der klassischen Softwareentwicklung besteht in der langsamen Entdeckung von Fehlern. Tatsächlich ist die Fehleraufdeckung beim klassischen Ansatz meistens erst nach dem Deployment möglich. Die neue Software muss erst auf den Rechnern des Kunden installiert werden, bevor eventuell vorhandene Fehler auftreten können. Besonders kritisch sind hier die sogenannten Seiteneffekte: Der Kunde entdeckt einen kleinen Fehler und der Entwickler spielt einen Bugfix ein, um das Problem zu beheben. Der Bugfix kann jedoch Auswirkungen auf andere Teile des Programmcodes haben, die gar nicht von dem Fehler betroffen und daher auch nicht Gegenstand der Fehlersuche waren. Solche Seiteneffekte können weiterer Nachbesserungen nach sich ziehen, die sehr aufwendig sein können. Hier ist der kontinuierliche Ansatz klar im Vorteil.

Was ist unter dem Begriff Continuous Integration zu verstehen?

In der Softwareentwicklung spielt die Continuous Integration längst eine wichtige Rolle. Die Idee hinter diesem Konzept besteht darin, dass die Arbeiten an Modulen der Software laufend überprüft und in ihrer Qualität verbessert werden. Die Integration erfolgt dabei durch den Einsatz entsprechender Systeme automatisch. Das bringt in der Praxis viele Vorteile mit sich. So lassen sich Schleifen zwischen dem Entwickler und der Qualitätssicherung im Unternehmen deutlich verringern. Entscheidend ist auch, dass Fehler im Programmcode so schnell wie möglich erkannt und beseitigt werden können. Durch das laufende Testen der Software lässt sich deren Qualität erheblich verbessern. Damit grenzt sich die kontinuierliche Integration von einem Entwicklungsprozess ab, bei dem die Software erst fertiggestellt und dann in einem zweiten Schritt getestet wird. Ergeben sich hier Fehler, muss die Software wieder an die Entwicklungsabteilung zurückgegeben werden. Stattdessen greifen beim kontinuierlichen Konzept Entwicklung und Regressionstests ständig ineinander. Langfristig lassen sich damit die Kosten im Unternehmen reduzieren.

Delivery als nächster logischer Schritt

Continuous Delivery stellt ein direktes Feedback an den Entwickler sicher und garantiert damit einen schnellen und reibungslosen Entwicklungsprozess der Software. Grundsätzlich soll gewährleistet sein, dass die Software im Prinzip jederzeit in die Produktion übergeben werden kann. Früher musste die Software lange Zeit Testschleifen durchlaufen, was viele Wochen Zeit in Anspruch nehmen konnte. Erst danach erhielt der Entwickler eine Rückmeldung, die er verwerten und in seine Arbeit einfließen lassen konnte. Die Continuous Delivery hat für den Entwickler noch weitere Vorteile praktischer Natur. Da Entwicklung und Test ineinandergreifen, steckt der Entwickler immer mitten drin in der laufenden Arbeit. So wird vermieden, dass er sich nach einer längeren Pause wieder mühsam in seinen alten Code einarbeiten muss.

Aus Sicht des Unternehmens weist die kontinuierliche Delivery ebenfalls entscheidende Vorteile auf. Hierzu gehört insbesondere eine Minimierung des Risikos. Die Entwicklung von Software ist zeitaufwendig und kostet viel Geld. Hier wäre es problematisch, viele Wochen und Monate auf ein Produkt warten zu müssen, das sich am Markt verwerten lässt. Beim kontinuierlichen Ansatz hingegen steht jederzeit eine Softwareversion zur Verfügung, die funktioniert und an die Produktion übergeben werden kann. Wenn der Vertrieb feststellt, dass schnell eine neue Version der Software in den Markt eingeführt werden sollte, ist das jederzeit möglich.

Wir verhalten sich Integration und Delivery zum Continuous Deployment?

Deployment ist der Schritt, in dem eine fertige Software beim Kunden installiert wird. Hiermit handelt es sich also um den letzten Schritt nach der Entwicklung und dem Testen der Software. Das Deployment wird auch als Softwareverteilung bezeichnet und passiert halb- oder vollautomatisch. Ein Continuous Deployment sorgt dafür, dass eine im Entwicklungsprozess befindliche Software jederzeit auf den Rechnern des Kunden deployed werden kann. Auch hier geht es also um einen nahtlosen Übergang zwischen den einzelnen Schritten von der Entwicklung über die Produktion bis hin zur Verteilung der Software.

So kann ein kontinuierlicher Delivery-Prozess in der Praxis aussehen

Der Delivery-Prozess ist besonders interessant, da er die automatisierten Tests umfasst, die der Qualitätssicherung dienen. Ist der Programmcode geschrieben, speist der Entwickler diesen in das Code-Repository ein. Hierbei handelt es sich um einen zentralen Server, auf den alle Programmierer für Ihre Arbeit Zugriff haben. Von dort aus gelangt der Code in die Delivery-Pipeline und wird auf Herz und Nieren geprüft. Dieser Vorgang erfolgt automatisch. Es versteht sich von selbst, dass die Definition der Tests vorab mit erheblicher Arbeit verbunden sein kann. Die Ergebnisse der Tests fließen als Feedback sofort zurück an den Entwickler. Die Tests begleiten damit den Entwicklungsvorgang, statt diesem nachgelagert zu sein. Der Programmierer wird nie aus seiner Arbeit gerissen.

Wie eine solche Pipeline in der Praxis ausgestaltet ist, hängt vom jeweiligen Projekt ab. Einige Schritte ähneln sich jedoch bei jeder Delivery. So muss der Programmcode erste einmal geschrieben und dann in kleinste Einheiten unterteilt werden. Diese Einheiten werden auch als Units bezeichnet und lassen sich unabhängig von den anderen Teilen testen. Die Unit-Tests stellen deshalb in der Pipeline den ersten Überprüfungsschritt der Software dar. Danach folgt die statische Code-Analyse, bei der Fehler und Verstöße gegen die Coding-Richtlinien aufgedeckt werden.

Der nächste Schritt besteht in der Installation des Codes in einer Testumgebung. Diese ähnelt bereits den Gegebenheiten, wie sie später beim Kunden anzutreffen sein werden. Die Installation erfolgt automatisch und geschieht damit besonders schnell. Es kann die Interaktion der Software mit anderen Systemen getestet werden ebenso wie die Akzeptanz durch den Anwender. In Falle des Akzeptanztests geht es vor allem darum herauszufinden, ob die Erwartungen des Anwenders an die Software erfüllt sind.

Viele weitere Tests können in der Pipeline angehängt werden. Dazu gehören zum Beispiel etwaige Sicherheitstests. Diese Tests können manuell oder automatisch erfolgen. Lasttests sind ebenfalls interessant, denn bestimmte Fehler lassen sich erst unter starker Beanspruchung provozieren. Am Ende der Pipeline stehen dann die manuellen Tests. Gerade Test in Hinblick auf die Nutzerfreundlichkeit lassen sich häufig nur schwer automatisieren.

Was ist ein Unit-Test und warum sind diese Tests so wichtig?

Kleinere Programmcode-Einheiten lassen sich am einfachsten und vor allem am schnellsten Testen. Es ist daher naheliegend, diese Tests in der Delivery-Piepline möglichst weit vorne zu platzieren. Werden die Fehler in den einzelnen Units zuerst ausgemerzt, fällt die Fehlersuche bei den nachfolgenden, komplexeren Tests in der Pipeline umso leichter. Es ist daher wichtig, den Programmcode so früh wie möglich in kleine Einheiten zu zerlegen und diese unabhängig voneinander behandeln zu können.

Werden die Units später zu einem komplexeren Stück Software zusammengefügt, ergeben sich viel mehr gegenseitige Abhängigkeiten, die das Testen erschweren. Diese gilt es so lange wie möglich zu vermeiden. Die Unit-Tests sind hier ein geeignetes Mittel. Da das Feedback an den Entwickler der Unit sofort erfolgt, kann auf Fehler schnell reagiert werden. Die verbesserte Software schickt der Entwickler dann zurück in die Pipeline. Dieser Vorgang kann im Prinzip beliebig oft wiederholt werden, bis die Unit fehlerfrei ist. Erst danach kommen die schwierigeren Tests. Die Units passen damit hervorragend zu einer Herangehensweise des kontinuierlichen Testens.

Konfigurationsmanagement im Überblick

Wenn der kontinuierliche Ansatz bei der Softwareentwicklung noch nicht verfolgt wird, stellt sich automatisch die Frage, wie bestehende Anwendungen in die neue Delivery-Umgebung integriert werden können. Mit dieser Frage beschäftigt sich das Konfigurationsmanagement.

Vorteilhaft ist es zum Beispiel, wenn eine Software ihre eigene Laufzeitumgebung mitbringt. Der Gedanke dahinter ist, dass so wenige Anforderungen an die Umgebung gestellt werden und sich damit der Transport zum Zielsystem vereinfacht. Im Idealfall genügt es, durch das Kopieren einer einzelnen Datei das Programm auf das Zielsystem zu bringen. Hier können die betreffende Anwendung und ihre jeweiligen Abhängigkeiten zum Beispiel in einen Container verpackt werden.

Vorteilhaft ist auch die Verwendung von Feature Flags. Mit diesen lassen sich einzelne Funktionen einer Software anstellen und abstellen. Das ist hilfreich, wenn die Software jederzeit auslieferungsfähig sein soll, dieser Zustand aber nicht für alle Programmteile garantiert werden kann. Ist ein Feature der Software noch nicht so weit, der Vertrieb fordert aber den Übergang in die Produktion an, kann das Feature per Flag deaktiviert werden.

Monitoring ausgelieferter Software

Ist die Software auf dem Rechner oder den Rechnern des Kunden installiert, gilt es das Feedback zu sammeln und zu verwerten. Im Rahmen eines umfassenden Monitorings sollte der Entwickler genau im Auge behalten, wie sich seine aktuelle Softwareversion in der Praxis verhält und welche Schwierigkeiten bei der Verwendung auftreten. Dieses Feedback sollten die Entwickler der einzelnen Programmteile sofort aufnehmen und in die Weiterentwicklung der Software einfließen lassen. Damit alle Entwickler Zugriff auf die Log-Informationen des laufenden Systems haben, sollten diese Daten auf einem zentralen Server gespeichert werden. Die Analyse kann manuell durch die Entwickler selbst oder teilweise automatisiert erfolgen. So kann zum Beispiel eine Warnmeldung ausgegeben werden, wenn im laufenden Betrieb das Auftreten einer bestimmten Anzahl an Fehlern überschritten wurden. Das ist ein wichtiger Bestandteil eines erfolgreichen Deploymentmanagements. Die Entwickler können sofort auf Probleme und Fehler reagieren und die gewonnenen Daten in die weitere Entwicklung einfließen lassen