www.opitz-consulting.com
Langlebige Branches sind out - es lebe die Trunk-basierte Entwicklung. So oder ähnlich lautet ein Mantra im Bereich Continuous Delivery. Und das ist richtig. Aber wenn man die Trunk-basierte Entwicklung naiv einführt, dann schadet sie vielleicht mehr, als sie nützt.
Im Rahmen ihres Vortrags bei der Continuous Lifecycle Conference am 16.11.2016 berichteten Richard Attermeyer (OPITZ CONSULTING) und Jens Kanschik (ista) von ihrer "Reise" von Story-Branches über naive Trunk-basierte Entwicklung hin zu einem Pre-Tested-Commit Workflow. Dabei zeichnen sie nach, welche Anforderungen maßgeblich für die jeweilige Entscheidung für ein Branching- und Commit-Modell und wie die Erfahrungen in einem Projekt mit vier Entwicklungsteams waren.
Wir wollen Sie in diesem Vortrag auf eine Reise mitnehmen und von unseren Erfahrungen berichten, die wir mit unterschiedlichenBranching Methoden gemacht haben.
Der Weg war in der Tat etwas steinig. Und wie auch häufiger in den Bergen war nicht immer klar erkennbar, was uns hinter der nächsten Abbiegung erwartet oder
welchen Weg wir gehen sollten.
Wir haben am Anfang gestritten, wie wir mit der Entwicklung einzelner Stories umgehen.
Durchgesetzt haben sich diejenigen, die keine unfertigen Stories ausliefern wollen… auch wenn alle Tests für die erstellten Teile grün sind.
Dies bedingt, dass wir jede Story in einem Story Branch entwickeln.
Jedes Fachmodul sollte unabhängig von den anderen bauen. Und seine eigene Geschwindigkeit bestimmen können.
Schließlich sollen die einzelnen Fachmodule später auch unabhängige Deploymentzyklen besitzen.
Die Realität sah aber ganz anders aus… wie so häufig.
Wir standen häufig im Stau.
Wir warteten. Und hatten gleichzeitig alle Hände voll zu tun.
Wir hatten ein common Projekt.
Fachmodule sind über das common Projekt gekoppelt.
Es wird etwas am common Modul geändert. Wenn die Änderung wichtig ist für die andern Projekte (und das ist sie in der Regel), dann müssen die Projekte warten, bis das common Modul gebaut und eine neue Version verfügbar ist.
Module sind ebenfalls über die Client Module gekoppelt, die ein Modul für alle Clients zur Verfügung stellt.
Oder ander ausgedrückt: Module sind über ihre Schnittstellen gekoppelt. Wenn eine Schnittstelle in der Entwicklung ist und noch regelmäßig Anpassungen erfährt (etwa beim Format des Payloads), dann müssen die Clients nachziehen (wenn sie im gleichen Sprint am gleichen Feature arbeiten).
Das haben wir doch dann gut gemacht, oder?
Also lassen wir uns feiern
Zwar war das Handling in der Entwicklung einfacher.
Aber Story Branches waren von der Entwicklung des Masters abgekoppelt.
Ein Merge konnte durchaus 2 Tage in Anspruch nehmen. Die Differenzen zum Master konnten schnell sehr groß werden.
Manchmal erscheint dann ein Heilsbringer, dem man nur noch folgen muss.
Folgt der Sandale!
(Übereinstimmungen mit Life of Brian sind rein zufällig).
Manchmal erscheint dann ein Heilsbringer, dem man nur noch folgen muss.
Folgt der Sandale!
(Übereinstimmungen mit Life of Brian sind rein zufällig).
Jetzt geht alles reibungslos und schnell… leider: nein.
Allerdings waren alle Ampeln auf rot.
Und das die meiste Zeit.
Wir waren nicht in der Lage zum Review etwas auf die Reviewumgebung zu bringen.
Auch wenn ein Fehler schnell behoben wurde, dann war meistens der nächste Fehler drin, welcher die Pipeline rot bleiben ließ.
Irgend etwas machen wir falsch, oder?
Bei Abhängigkeiten zwischen den Teams müssen auch Zwischenstände einer Story für andere Teams verfügbar sein:
Beispiel: In App X wird eine Schnittstelle bereitgestellt, die von App Y genutzt wird. Diese Schnittstelle sollte so schnell wie möglich im Team 2 genutzt werden können.
Fehler in den Builds bzw. Behebung der Fehler sollen möglichst schnell sichtbar sein:
Beispiel: In einem E2E-Test tritt ein Fehler auf oder wird korrigiert; der Entwickler muss zur Zeit bis zu einer Stunde warten, bis es Feedback gibt.
Beispiel: In einem E2E-Test tritt ein Fehler auf, aufgrund eines Fehlers in einem anderen Modul und aufgrund einer „fremden“ Story werden die E2E-Tests aber nicht gestartet.
Im Regelfall sollte SYS als Ganzes funktionieren und auf Test deploybar sein:
Für integrative Tests der Teams muss SYS auf die Test-Umgebung deployed werden; das ist nur sinnvoll, wenn die Applikation auch funktioniert (d.h. die Tests sind grün). Ohne solche Tests können bestimmte Stories nicht abgeschlossen werden.
Fehlgeschlagene Builds sollten mit Commits im Zusammenhang stehen:
Zurzeit ist es nicht immer möglich, am Commit den Grund für den fehlgeschlagenen Test zu ermitteln: zu häufig brechen Builds bereits vorher wegen anderen Stories/Infrastruktur ab, es sind Tests auskommentiert oder es werden nur einzelne Tests ausgeführt („fdescribe“).
Größere Änderungen dürfen nicht dazu führen, dass andere Ergebnisse nicht ausgeliefert werden können.
Beispiel: Ein Team führt Änderungen durch, die auf mehrere Stellen/Module Auswirkungen haben (Validierungen in den REST-Schnittstellen, Raum bei Geräten/Messstellen etc.). Während der Entwicklung werden nennenswerte Teile der Applikation inkonsistent/fehlerhaft sein. Das darf nicht dazu führen, dass die Teams nicht mehr arbeiten können bzw. nicht deployed werden kann.
Bei bestimmten Arten von Stories sollten keine Zwischenergebnisse deployed werden, sondern erst der fertige (oder fast fertige) Stand.
Beispiel: Änderungen am Datenmodell sind in sich konsistent und fehlerfrei, aber bei dem Import von Verträgen fehlt noch ein Teil der Logik. Importe aus SAP würden bei einem Deployment immer fehlschlagen.
Aktuell ein Problem: Wir können das Starten des Flows nur durch einen Failure verhindern.
Entwickler müssen Fehlernachricht genau lesen (Subject Line), um zu wissen, ob es ein echter Fehler ist.
Das wird manchmal übersehen
Aktuell ein Problem: Wir können das Starten des Flows nur durch einen Failure verhindern.
Entwickler müssen Fehlernachricht genau lesen (Subject Line), um zu wissen, ob es ein echter Fehler ist.
Das wird manchmal übersehen
Das Konzept der Testuiten kann auch auf Integrationstests ausgeweitet werden