Continuous Delivery ist eine Praxis der Softwareentwicklung, bei der ein Team oder ein Unternehmen bestrebt ist, seine Software stets in einem lieferbaren Zustand zu halten. Eng damit verbunden ist die kontinuierliche Bereitstellung, bei der die Software selbst so oft wie möglich für die Produktion freigegeben wird. Continuous Delivery ist eine Voraussetzung für Continuous Deployment. Aus geschäftlicher Sicht ermöglicht die kontinuierliche Bereitstellung einem Unternehmen, sich schnell an veränderte Marktentwicklungen anzupassen, auf Benutzerfeedback zu reagieren usw. Was jedoch meiner Meinung nach ein viel stärkeres Argument für CD ist, ist die Tatsache, dass es eine große Anzahl von Softwareentwicklungspraktiken durchsetzt. Es ist ein Kernprinzip, auf das man sich beziehen kann, wenn man Entscheidungen über die Praxis der Softwareentwicklung trifft, angefangen bei der Handhabung der Versionskontrolle, der Test- und Release-Automatisierung usw. In diesem Beitrag werde ich auf die Softwareentwicklungspraxis der Versionskontrolle eingehen und eine Reihe von Strategien im Zusammenhang mit Continuous Delivery diskutieren.
Versionskontrolle, automatische Überprüfungen und kontinuierliche Integration
Eines der Grundprinzipien von CD ist es, den Build grün zu halten. Alle Entwickler eines Projekts arbeiten an einer gemeinsamen Codebasis und müssen sich darauf verlassen können, dass diese immer in einem funktionierenden, einsatzfähigen Zustand ist. Ich werde hauptsächlich Begriffe aus Git verwenden, aber das gilt für alle Versionskontrollsysteme.
Trunk-basierte Entwicklung
Der einfachste Weg, mit mehreren Entwicklern an einer einzigen Codebasis zusammenzuarbeiten, ist wahrscheinlich die trunk-basierte Entwicklung, bei der alle Entwickler an einem einzigen Zweig arbeiten, in der Regel dem Zweig master. Diese Methode der Zusammenarbeit impliziert in hohem Maße die kontinuierliche Integration, bei der Änderungen, wie der Name schon sagt, mehrmals am Tag kontinuierlich integriert werden. So bleiben alle auf dem neuesten Stand der Entwicklung, so dass neue und aktualisierte Funktionen schnell im gesamten Team bekannt sind. Damit soll verhindert werden, dass Mitarbeiter auf Inseln arbeiten, die länger als einen Tag vom Rest des Teams isoliert sind.master in einem nicht freigegebenen Zustand befindet. Das unterbricht den Fluss der kontinuierlichen Bereitstellung und behindert alle, die an der Codebasis arbeiten, bis das Problem behoben ist.
Es gibt eine Reihe von Möglichkeiten, dieses Risiko zu minimieren. Ein wichtiger Faktor für die erfolgreiche Anwendung von CD ist die Testautomatisierung. Eine Möglichkeit, um zu verhindern, dass der Build unterbrochen wird, besteht darin, sicherzustellen, dass die automatisierten Tests alle grün sind, bevor sie wieder in den Master integriert werden. Dies kann z.B. durch die
Feature Verzweigung
Kurz gesagt: Beim Feature-Branching erstellt ein Entwickler eine Verzweigung vom Mainline-Quellcode, erledigt seine Arbeit und führt sie wieder mit dem Mainline-Quellcode zusammen. Bevor diese Zusammenführung erfolgt, wird eine Reihe von Überprüfungen durchgeführt. Es werden alle automatisierten Tests ausgeführt, ein Code-Review wird von Kollegen durchgeführt (entweder im selben Team, in einem anderen Team, von einem erfahrenen Entwickler usw.), ein Product Owner inspiziert die neue Funktion und gibt Feedback usw. Um sicherzustellen, dass der master Build nach dem Zusammenführen grün bleibt, ist es am besten, nur das Zusammenführen von Zweigen zuzulassen, die mit dem Master auf dem neuesten Stand sind, d.h. nach dem Zusammenführen ist alles, was gegenüber der Mainline geändert wurde, die eine neue Funktion. Die meisten Versionskontrollprogramme (github, gitlab, bitbucket usw.) verfügen über Verwaltungsoptionen, um dies zu erzwingen; suchen Sie nach einer Option, die nur das Vorspulen erlaubt. Dies gewährleistet eine lineare Historie und stellt sicher, dass nach jedem Merge eine Veröffentlichung mit einer relativ kleinen Änderung im Vergleich zur vorherigen Version möglich ist.master in den vorherigen Beispielen, in Git-Flow develop genannt) und dem "ready for deployment"-Zweig einfügt. Dadurch wird eine indirekte Ebene hinzugefügt, sozusagen ein Puffer, in dem mehr Spielraum für Fehler besteht und der Build abgebrochen werden kann. Ich glaube nicht, dass dies eine gute Strategie ist. Da ein Abbruch des Builds nicht so sehr schmerzt, gibt es weniger Anreize, die Ursachen zu beheben. Die Überführung in die Produktion ist mit mehr Ritualen und Prozessen verbunden, es sind mehrere Schritte erforderlich. Diese Rituale könnten bis zu einem gewissen Grad automatisiert werden, aber es ist besser, die Rituale gar nicht erst zu haben, als zu versuchen, sie zu verstecken - je mehr Rituale, ob automatisiert oder nicht, desto mehr Overhead gibt es, der die CD behindert.
Der Ansatz des "einfachen" Feature-Branching ist derjenige, den ich in meinen Projekten am häufigsten verwendet habe. Ich habe festgestellt, dass sowohl ich als auch andere Entwickler sich zu diesem Ansatz hingezogen fühlen; Es erspart eine Menge Kopfzerbrechen, wenn es darum geht, den Master auf dem neuesten Stand zu halten, es verschiebt die Lösung von Konflikten (wenn nötig) auf den Zeitpunkt der Integration statt auf die ganze Zeit, es ermöglicht automatisierte Tests auf einem CI-Server und vermeidet das Zusammenführen, wenn es eine Regression oder ein Problem gibt, und was wahrscheinlich die Codequalität am meisten verbessert hat, war, dass mit Hilfe von Tools wie Github, Gitlab und Stash formellere Code-Reviews möglich waren.
Bevor wir auf diese Systeme umgestiegen sind, sind wir herumgelaufen und haben jeden gesucht, der bereit war, unseren Code zu überprüfen. Das bedeutete, dass wir jemanden aus seiner Konzentration reißen mussten, was wir als ziemlich lästig empfanden. Das andere Problem bei unseren Code-Reviews war, dass der Reviewer sich nicht die Zeit nahm, den Code durchzugehen, sondern dass der Entwickler den Code nur zeigte, durchblätterte und erklärte. Mit den formelleren Werkzeugen wurde daraus ein asynchroner Prozess, bei dem der Prüfer den Code in seiner eigenen Zeit und zu seinem eigenen Zeitpunkt prüfen konnte. Das Wichtigste dabei ist, dass Sie sich darauf einigen müssen, die Überprüfungen nicht zu lange offen zu lassen, da der ursprüngliche Entwickler sonst bereits zum nächsten Punkt übergegangen ist. Das passiert in der Regel sowieso, sollte aber auf ein Minimum beschränkt werden, um ein übermäßiges Umschalten des Kontexts sowohl für den Entwickler als auch für den Prüfer zu vermeiden.
Die meisten Versionskontrollsysteme sind eine Variation der oben genannten zwei oder drei Ansätze. Der von Code-Hosting-Plattformen wie GitHub populär gemachte Fork & Pull Request Flow ist eine Variante des Feature-Branch-Ansatzes, mit der Besonderheit, dass der Fork nicht in die Upstream-Codebasis integriert werden muss - er kann als eigenes Produkt weiterleben, wenn die ursprünglichen Autoren des Fork-Projekts mit den vorgenommenen Änderungen nicht einverstanden sind. Das Linux-Projekt, das Projekt, für das Git ursprünglich entwickelt wurde und das eine der größten Codebasen ist, die Versionskontrolle verwenden, verwendet einen stark verteilten Ansatz für die Versionskontrolle. Anstelle von Zweigen, Pull-Requests usw. gibt es eine Hierarchie von Maintainern, wobei Linus Torvalds der Hauptintegrator ist, der am Ende alle Änderungen, die per E-Mail von den Top-Maintainern geschickt werden, in seine Mainline-Version des Linux-Kernels zusammenführt. Seiten wie Submitting Patches und First Kernel Patch versuchen, den Prozess bis zu einem gewissen Grad zu erklären. Für welchen Ansatz Sie sich als Team auch immer entscheiden, achten Sie darauf, dass Sie bei einem Ansatz bleiben und konsistent sind, damit jeder weiß, was vor sich geht. Zweitens sollten Sie als Team lernen, Git zu verstehen; lernen Sie den Status Ihres lokalen Repositorys anhand der Befehlszeilenausgabe kennen, seien Sie sich des Unterschieds zwischen lokalen und entfernten Zweigen bewusst, wissen Sie, was Sie lokal haben und was mit anderen geteilt wird. Halten Sie Ihre Historie sauber und verwenden Sie unentgeltlich Tools wie amend und interactive rebase, um die Historie, die Sie erstellen, zu bereinigen - aber nur, solange Sie sie noch nicht mit anderen geteilt haben. In der Tat bieten alle großen Git-Hosting-Lösungen die Möglichkeit, einen Zweig zu schützen. Ich empfehle, dies für den Master-Zweig immer zu aktivieren, damit niemand die Geschichte umschreiben kann. Ich schreibe die Historie in Zweigen um, indem ich (interaktives) Rebasing und Force-Pushing einsetze. Das liegt vor allem daran, dass die anfängliche Arbeit an einem Feature vielleicht nur eine Handvoll Commits umfasst, aber die Korrekturen und Überarbeitungen, die nach der Überprüfung des Codes oft anfallen, fügen eine Menge Commits hinzu, in denen "dies behoben" und "das behoben" wird. Das ist natürlich falsch und es werden später noch Änderungen hinzugefügt, aber zumindest wird der anfängliche Entwicklungsaufwand in Ihrem Git-Verlauf sauber dargestellt. Tun Sie dies auch nicht, wenn mehr als eine Person an demselben Zweig arbeitet, denn das verursacht eine Menge Ärger. Ziehen Sie die Paarprogrammierung vor, wenn Sie wirklich müssen, oder vereinbaren Sie, dass Sie die Historie während der Entwicklung durcheinander bringen, aber nur einen Entwickler die Historie bereinigen lassen, sobald die Entwicklung abgeschlossen ist. Denken Sie auch daran, dass es sich hier um fortgeschrittenes Material handelt Denken Sie daran, dass Sie bei jedem branch-basierten Ansatz (z.B. bei allem, was nicht trunk-basiert ist) Änderungen am Code, an den Commits und an allem bis zum endgültigen Merge vornehmen können - wenn Sie sich für einen Ansatz entscheiden, nutzen Sie diese Option, um sicherzustellen, dass Ihre Historie so sauber wie möglich ist und dass Ihr Produkt, wenn Sie den Merge-Button drücken, bereit für die Produktion ist.
Verfasst von

Freek Wielstra
Freek is an allround developer whose major focus has been on Javascript and large front-end applications for the past couple of years, building web and mobile web applications in Backbone and AngularJS.
Contact