Git Workflows Teil 2: Workflows meistern

Nachdem wir im vorigen einige Grundlagen zu Workflows und ein erstes Beispiel betrachtet haben, geht es nun ans Eingemachte. Wir vergleichen Workflows und machen uns Gedanken über den praktischen Einsatz von Workflows im alltäglichen Geschäftsbetrieb.

Git machts möglich: Dezentralisierte Workflows

Vorab gilt es zwischen zentralisierten und dezentralisierten Workflows zu unterscheiden. Ein dezentralisierter Workflow basiert auf mehreren Quelltextarchiven, die untereinander synchron gehalten werden. Dabei wird der Vorteil von verteilten Versionskontrollsystem wie Git deutlich: Es ist im Gegensatz zu Systemen wie Subversion kein zentraler Server notwendig, um Änderungen vorzunehmen. Vorgenommene Änderungen lassen sich in Form von Patch-Sets gar via E-Mail zu verschicken und auf andere Archive anwenden.

18333fig0503-tn

Das Wohl prominenteste Beispiel für einen solchen Workflow findet sich in der Entwicklung des Linux-Kernels in Form des Dictator & Lieutenants Workflow. Zwar wir auch hier ein zentrales Archives verwendet, das sogenannte Blessed Repository, jedoch hat darauf nur der Diktator (in diesem Falle Linus Torvalds) Schreibrechte. Alle anderen Entwickler müssen Änderungen aus dem zentralen Repository laden und bei einem Lieutenant (z.b. einem Subsystem/Treiber-Verantwortlichen) einreichen, welcher wiederum die Änderungen prüft, zusammenführt und dem Diktator zukommen lässt. Damit lassen sich auch Entwicklungsprojekte stemmen, dessen Entwicklerschaft in die Hunderte geht.

Zentralisierte Workflows

Ein dezentralisierter Workflow wie er in der Entwicklung des Linux-Kernels praktiziert wird, ist in kommerziellen Projekte eher ungewöhnlich. Wir beschränken uns daher in unserem weitren Vergleich auf einige mehr oder weniger bekannte Workflows aus dem Bereich der zentralisierten Workflows.

Der Github-Workflow

Wir erinnern uns an den -Workflow aus Teil 1: Alles aus master ist permanent und unveränderber in der Historie, während Feature-Zweige temporär und instabil sein können. Der interne GitHub-Workflow fügt dem simplen Master-Workflow ein Rollenkonzept hinzu und setzt die Deploybarkeit von master voraus.

githubflow

Die Regeln sind eindeutig:

  • Es gibt einen master-Branch, dessen inhalte deploybar sein müssen.
  • Um an etwas neuem zu arbeiten, wird ein Zweig von master aus erstellt, z .b. PROJ1-backend-db-redis-connector.
  • Dieser Zweig wird regelmäßig aktuell gehalten und zum Server übertragen
  • Benötigt man Hilfe oder möchte den Zweig integrieren, eröffnet man einen Pull Request
  • Wurden die Änderungen von einer zweiten Person gesichtet und akzeptiert, kann die Änderung in master integriert werden
  • Sobald die Änderungen in master sind, kann und soll man diesen sobald wie möglich veröffentlichen

Dieser Workflow ist einfach genug, sodass er schnell adaptiert werden kann und ist skalierbar. Die Ergänzung um Rollen bzw. Code Reviews macht diesen Workflow für Teams, die Continuous Delivery im Einsatz haben interessant. Das konstante pushen von Zweigen auf den Servern sorgt für eine bessere Übersicht der derzeitigen Arbeiten und lässt z.b. “branch-aware CI” zu.

Jedoch gibt es in diesem System keine Möglichkeit, mehrere Release zu pflegen, denn alle Zweige abseits von master sind lediglich für Aufgaben gedacht und nicht permament, wie es bspw. ein Rel-1.2-Zweig sein müsste.

Stash-Workflow

Das Team von Atlassian benutzt für die Entwicklung des Enterprise Git Hosting-Systems Stash einen ähnlichen Ansatz, ergänzt das Konzept mit Fokus auf Continuous Integration und Release Management.

stash-branching_model
Ein kurzer Überblick:

  • Der master-Zweig wird stabil gehalten, nicht aber in Produktionsqualität wie beim GitHub-Workflow. Die Qualität bzw. Buildstabilität schwankt zwischen “Alpha” und “Release Candidate”. Unterstützt wird dies durch den Einsatz von branch-aware Continous Integration, automatischer Testabdeckung und Performance-Monitoring der Buildresultate.
  • Pro User Story ein Zweig, wird von master aus erstellt.
  • Pro Release ein Zweig, d.h. das Team verwaltet Release-Zweige (z.b. Stash-1.1) für noch unterstützte Versionen von Stash
  • Pro Bugfix ein Zweig, wird automatisch in den passenden Release-Zweig zurückintegriert
  • Pull Requests werden für fertige Implementierungen erstellt und nach einem erfolgten Code Review durch mindestens zwei Team-Mitglieder in den master-Zweig aufgenommen.

Der Entwicklungsworkflow lässt sich somit in drei Schritten zusammenfassen:

  • Neue Features und Bugfixes werden in Zweigen entwickelt
  • Mindestens zwei Mitglieder überprüfen die Änderungen an Features
  • Änderungen werden zurück nach master integriert

Der Ansatz vom Stash-Team berücksichtigt somit auch verschiedene Versionen einer Software, welche zum Teil unterschiedlich lange unterstützt werden und formuliert klare Regeln zu Code Reviews.

GitFlow

Der bekannteste Workflow ist der von Vincient Driessen bereits 2010 beschriebene GitFlow. Hier handelt es sich um einen relativ komplexen Workflow mit klar definierten Abläufen. Ein von bisherigen Modellen abweichender Ansatz in GitFlow sind Konzepte, wie ein Interims-Zweig für Entwickler namens develop, welcher dem master-Zweig aus dem Stash-Workflow gleicht und spezifische Release-Candidate-Zweige, die Stabilität in den Entwicklerzweig für den eigentlichen, auslieferbaren master-Zweig bringen sollen.

4-2-1-1-gitflow

Das GitFlow-Regelwerk ist umfangreich, lässt sich mit den Kenntnissen aus den vorigen Modellen relativ schnell erklären:

Dauerhafte Zweige:

  • develop: Enthält die zurzeit in Entwicklung befindliche Codebasis. Aktuellster Stand immer im zentralen Repo.
  • master: Enthält Snapshots von stabilen (= getesteten, reviewten) Ständen der Codebasis. Aktuellster Stand immer im zentralen Repo.

Temporäre Branches

  • Feature-Branches: Werden vom Entwickler erstellt, z.B. wenn ein Ticket welches ein Feature beschreibt bearbeitet wird. Abgeschlossene Arbeiten werden nach develop gemerged
  • Release-Branches: Werden von develop gebranched und enthalten den Veröffentlichungskandidaten. in release-Branches werden keine neuen Features implementiert, nur noch Fehler ausgemerzt und die Codebasis nochmals intensiv getestet.

Wer jetzt befürchtet, dass Releases über längere Zeit nicht gewartet werden können, sei hiermit entwarnt. Mithilfe von Tags auf dem master-Zweig lässt sich zurückverfolgen, welche Änderung zu welchem Release gehört. Das GitFlow Regelwerk lautet wie folgt:

  • Feature Branches: Können von jedem Entwickler erstellt und verändert werden, befindet sich nicht unbedingt im zentralen Repo. In der Regel ist es auch nicht interessant, besondere Rechte für solche Branches zu setzen, sie liegen in der Verantwortung des Entwicklers der den Branch erstellt hat. Nachdem ein Feature fertig ist, wird es nach develop integriert und der feature branch gelöscht.
  • Develop Branch: In diesen Zweig werden entsprechend Features aus ihren dedizerten Branches (sobald als “done” angesehend sind) hinheingemerged. Des weiteren können (triviale) Änderungen direkt an der Code-Basis durchgeführt werden.
  • Release-Branch: Wird von einem mit der Veröffentlichung betrauten Entwickler aus develop heraus erstellt. Ab diesem Zeitpunkt stehen die Features für die zu veröffentlichende Version fest, neue Features fließen nur nach develop und nicht mehr in diesen Schnappshuss ein. Der Branch wird release-fertig gemacht, üblicherweise durch ausführlichere (Integrations-)Tests und Code Reviews. Änderungen an release-Branches werden in den aktuellen Entwicklungszweig zurückintegriert, damit diese Verbesserungen in künftige Veröffentlichungen mit einfliessen.
  • Sobald ein “Release” fertig ist, wird es nach Master geschoben und getaggt. Der entsprechende Branch wird gelöscht.
  • Hotfix bzw Bugfix: Werden aus Master heraus erstellt, und wieder nach master gemerged ohne release branch. Demnach benötigen hotfixes besondere aufmerksamkeit

Und schlussendlich Master: Enthält einen Schnappschuss einer stabilen Version aus einem Release-Branch heraus, nachdem entsprechende Qualitätssicherungsmaßnahmen durchgeführt wurden. Etwaige Bugfixes werden in Form von Hotfixes bzw. Patches in künftige Versionen integriert werden, der feststehende, “getaggte” Stand in master jedoch nicht mehr verändert.

Git Workflows im Enterprise

Git Flow gibt per se nicht vor, wer welche Rolle ausfüllt. In der Unternehmens-Praxis ist es jedoch meist so, dass es einen verschiedene Rollen wie Release- oder Product Manager zu besetzen gibt. Setzt man also einen Git Workflow im Rahmen eines (agilen) Projektes oder denkt über skalierbare Agilität wie SAFe nach, kommt man um ein Rollenkonzept nicht herum.

Folgende Fragen werden bei der Einführung von Workflows im Unternehmenskontext sehr bald auftauchen:

  • Wie setzt Berechtigungen auf Zweigbasis, wenn ich möchte, dass nur gewisse Personen einen Release durchführen dürfen (d.h. nach master schreiben)?
  • Wie kann man sicherstellen, dass ein feature vor einem Merge-Vorgang nach develop auch einem Code Review unterzogen wurde?
  • Lässt sich auch ein Continous Integration Server einbinden, der beispielsweise einen sauberen Build attestiert, bevor ich ein Release durchführen darf?

Die Antworten liegen meistens im Bereich der eingesetzten Werkzeuge oder einer geschickt aufgebauten Infrastruktur. Im nächsten Teil werden wir betrachten, wie sich Git Flow mit einem spezifischen Rollenkonzept mithilfe von Software-Werkzeugen erfolgreich und praxistauglich umsetzen lässt.

Short URL for this post: http://wp.me/p4nxik-2fk
This entry was posted in Agile Methods and development, Build, config and deploy and tagged , , . Bookmark the permalink.

Leave a Reply