Entwicklung auf dem Trunk Raus aus der Merge-Hölle!

Mit Trunk-Based Development (TBD) gelingt es, neue Funktionen wesentlich schneller bereitzustellen als beispielsweise durch die Verwendung von Feature-Branching. Das große Plus: Die gefürchtete Merge-Hölle kann verhindert werden!

Statt vieler Code-Branches vertraut man beim Trunk-based Development dem Namen gemäß auf einen Code-Stamm, also einen Hauptzweig.
Statt vieler Code-Branches vertraut man beim Trunk-based Development dem Namen gemäß auf einen Code-Stamm, also einen Hauptzweig.
(Bild: Jace Abshire (@jaceabshirephotography) / Unsplash)

Bevor Entwickler mit dem Codieren beginnen, sollten sie genau abschätzen, wie komplex die gestellte Aufgabe ist und was sie benötigen, um sie optimal erledigen zu können. Während der Planungsphase gilt es deshalb, sich unter anderem die folgenden Fragen zu stellen:

  • Lässt sich ein jeweiliges Feature in kleinere Aufgaben aufteilen?
  • Kann man dieses Feature parallel zum Team entwickeln?
  • Was muss getan werden, um jede kleinere Aufgabe in diesem Feature zu erledigen?

Die Beantwortung dieser Fragen hilft dabei, sich vorzustellen, wie der Code für ein Feature aussehen könnte (Klassen, Objekte, Funktionen usw.). Das Teilen von Informationen ist einer der Schlüssel für den zukünftigen Projekterfolg. Planungssitzungen sind daher in der Trunk-basierten Entwicklung (TBD) äußerst wichtig. Es hilft beim Koordinieren der Arbeit, ermöglicht den Informationsaustausch und ist ein ideales Werkzeug für schnellere Codeüberprüfungen.

Erstellen eines neuen Features

Nach der Planung sollte das Board mit den jeweiligen Aufgaben aufgefüllt werden. Dabei ist zu beherzigen, dass jeder Code, der geschrieben wird, auch gut getestet sein sollte. Dies stellt wiederum eine gute Gelegenheit dar, TBD in die Arbeit zu integrieren. Hier gilt es, insbesondere diese Kernregel zu beachten: Die tägliche Bereitstellung eines neuen Commit für den Trunk dient nicht nur als Symbol für den Projektfortschritt, sondern verhindert auch mögliche Merge-Konflikte.

Zu Beginn eines typischen Entwicklertags mit dem Trunk-basierten Entwicklungsansatz wird als erstes lokal aus dem Trunk ein Branch erstellt. Daraus sollte ein möglichst kleiner Commit entstehen, der einen funktionierenden Teil eines Features enthält. Dabei ist zu beachten, dass kein Commit die Mainline (Trunk Branch) unterbrechen darf.

Ein Release Manager sollte nämlich dazu in der Lage sein, aus jedem historischen Punkt einen Release-Branch zu erstellen. Um dies sicherzustellen, darf kein Code einer unvollendeten Funktion geliefert und einem User erlaubt werden, ihn einzugeben. Die Problematik kann nun über zwei Wege gelöst werden: „Branch by Abstraction“ und „Feature Flag“.

Branch by Abstraction

Diese Vorgehensweise ist vor allem dann nützlich, wenn ein Entwickler Komponenten ersetzen muss. Angenommen, es ist eine Memcached-Instanz als Cache-Manager im Einsatz; nur drei Komponenten hängen von Memcached ab, obwohl die Anzahl der Komponenten eigentlich sehr groß ist. Eine Lösung durch Branch by Abstraction ist in wenigen einfachen Schritten umzusetzen:

  • Mit der alten Komponente wird eine Abstraktionsschicht für einen Client erstellt.
  • Umleitung aller Clients zur Verwendung der Abstraktionsschicht.
  • Es wird eine neue Komponente für nur einen Client erstellt und diese über die Abstraktionsschicht verbunden.
  • Entwicklung und Test der neuen Komponente.
  • Umleitung der Abstraktionsschicht, dass sie nur die neue Komponente verwendet.
  • Alte Komponente entfernen.

Mit dieser Technik lassen sich veraltete Komponenten leicht durch neue ersetzen, ohne die Mainline (Trunk Branch) zu unterbrechen.

Feature Flag

Die zweite Vorgehensweise wird vielfach in der Trunk-basierten Entwicklung verwendet. Die Grundidee dieses Ansatzes liegt darin, eine Konfigurationsdatei (oder auch Datenbanktabelle) mit einer Reihe von Flags und spezifischen Namen zu erstellen. Eine Lösung durch Feature-Flag kann in wenigen einfachen Schritten angewandt werden:

  • Eine neue Flag wird in einer Konfigurationsdatei oder einer Datenbank erstellt.
  • Das neue Feature wird hinter der Flag versteckt.
  • Entwicklung des neuen Features.
  • Vorbereitung einer Liste mit Flags für die aktuelle Version.
  • Entfernung der Flags von den Features aus der Konfigurationsdatei bzw. Datenbank, die sich in der Produktion befinden.

Fehler in der Produktion beheben

Es ist natürlich immer möglich, dass sich Fehler in einen Release-Branch einschleichen. Dazu sollte der jeweilige Fehler im Trunk Branch lokalisiert und mit einem zusätzlichen Commit behoben werden. Es ist zu beachten, dass die Mainline und der Release-Branch denselben Code enthalten, sodass es kein Problem sein sollte, einen Fehler aus dem Release-Branch auf dem Trunk zu reproduzieren.

Überprüfung des Codes

In der Planung wurde festgelegt, dass das Team jeden Tag ein paar zu überprüfende Commits erstellt, die sich meist auch sehr schnell testen lassen. Zudem sind dem Team nach der Planung die Zusammenhänge aller Features bekannt, sodass es im Grunde nur die technischen Aspekte des Codes prüfen müssen.

Testläufe

Es gibt zwei Möglichkeiten zum Testen. Für die erste Variante liefern Unit-Tests eine neu erstellte Methode oder Funktion. Man beachte, dass Unit-Tests nur die getestete Funktion abdecken sollten, andere Funktionen könnten ein Stub oder Mock sein. Eine weitere Testgruppe deckt den Integrationsprozess ab. Irgendwann könnte man Code schreiben, der Funktionen aus einem separaten Modul verwendet. Auch diese Verbindung sollte getestet werden. Übrigens, es ist im Grunde doch eine großartige Gelegenheit, A/B-Tests in einem Unternehmen einzuführen, wenn man über eine Reihe von Flags verfügt, die man über eine Funktion einfach ein- und ausschalten kann.

Konflikte zusammenführen und lösen

Da es nur einen Branch gibt, erübrigt sich auch eine Zusammenführung. Das heißt, es gibt logischerweise auch keine Konflikte bei der Zusammenführung. Dies ist einer der großen Vorteile der Trunk-basierten Entwicklung.

Jetzt Newsletter abonnieren

Täglich die wichtigsten Infos zu Softwareentwicklung und DevOps

Mit Klick auf „Newsletter abonnieren“ erkläre ich mich mit der Verarbeitung und Nutzung meiner Daten gemäß Einwilligungserklärung (bitte aufklappen für Details) einverstanden und akzeptiere die Nutzungsbedingungen. Weitere Informationen finde ich in unserer Datenschutzerklärung.

Aufklappen für Details zu Ihrer Einwilligung

(ID:48493314)