Tipps für Bamboo in DVCS-Teams

Der Hauptzweck von Bamboo besteht darin, Code zu bauen, diesen zu testen und Benachrichtigungen über Fehler oder Bruchstellen auszugeben – das Stichwort lautet Continuous Integration.

Bamboo bildet den kompletten Build-, Test- und Notification-Prozess ab und ermöglicht es, ganz einfach zu fehlgeschlagenen Tests zu navigieren, Build-Logs zu lesen oder durch die Build History zu browsen. Es genügt ein Browser, um all diese Daten in einer einzelnen Anwendung einzusehen. Das könnte wie im folgenden Screenshot aussehen:

Aus dem obigen Screenshot ist auf einen Blick ersichtlich, wer etwas kaputt gemacht hat, wie schwerwiegend das Problem ist und was betroffen ist. Mit Bamboo können Entwicklungsteams aber noch ganz andere Dinge tun.

Branching

Stellen wir uns eine gängige Situation vor: Entwickler arbeiten in einem durchschnittlich großen Team an einem durchschnittlich großen Projekt mit vielen automatischen Tests. Mehrere Entwickler sind zur selben Zeit an derselben Code-Basis aktiv. In einer solchen Umgebung ist es durchaus möglich, dass mehrere Leute gleichzeitig schadhaften Code einchecken, der sich später in Form von fehlerhaften Tests oder Build-Fehlern auswirkt.

Wenn diese Personen die kaputten Dinge nicht schnell fixen, könnte das die anderen Entwickler negativ beeinflussen – beispielsweise indem diese „unsichtbare“ Bugs einschleppen, die sich nicht zu erkennen geben, ehe das initiale Problem nicht behoben ist. Oder die fehlgeschlagenen Tests blocken das Release. In jedem Fall müssen einige Leute warten, bis andere die Probleme gelöst haben.

Eine mögliche Gegenmaßnahme ist das Arbeiten mit Branches. Mit modernen DVCS-Systemen wie Git oder Mercurial sind Branches schnelle und kostengünstige Operationen. So können Entwickler Branches nutzen, um ihre Arbeit von der der anderen Leute zu separieren. Damit unterbricht der Programmierer nicht das ganze Team, wenn er schadhaften Code eincheckt und der Test oder sogar der ganze Build fehlschlägt.

Der Entwickler kann die Fehler im Branch reparieren, diesen schließlich (wenn alle Tests grün sind) upstream mergen und für die nächste Aufgabe einen neuen Branch starten. Solange ein Team nicht nach dem Branching-by-Fork-Prinzip verfährt, erkennt Bamboo neue Branches in der Repository und lässt die Tests automatisch gegen sie laufen. Man kann sogar JIRA-Vorgänge mit den relevanten Builds verknüpfen, wenn man Branches für Features nutzt:

So weit, so gut. Wenn nun mehrere Entwickler an einzelnen Branches arbeiten, ist es möglich, dass all diese Branches grün bleiben, wenn sie separat getestet werden.

Wenn sie dann jedoch allezusammen gemergt werden, schlagen einige Tests fehl – etwa weil Änderungen von Branch A die Änderungen von Branch B beeinträchtigen, und noch schlimmer: Diese beiden beeinträchtigen die Tests, die in Branch C hinzugefügt wurden. Würde man diese Merges manuell und ohne Trockenlauf-Tests durchführen, würde man den Upstream-Build unweigerlich kaputt machen und wieder in die oben beschriebene Situation kommen: Einige Leute warten, bis die Kollegen ihre Sachen gefixt haben. Wie lässt sich dies vermeiden?

Gatekeeping

Ist die Code-Basis in einer einzelnen Repository gespeichert, kann Bamboo so konfiguriert werden, dass es Trockenlauf-Tests durchführt, ehe der Merge in die Repository übergeben wird. Immer, wenn ein neuer Checkin in den Branch vorgenommen wird, nimmt Bamboo also den Code aus dem neuen Branch, versucht, ihn (ohne zu committen!) gegen den Upstream-Branch zu mergen und den Test-Plan gegen das trocken gemergte Ergebnis auszuführen:

Auf diese Weise lassen sich Überraschungen vermeiden, wenn künftig manuelle Merges durchgeführt werden. Wenn sich ein Branch zu weit vom Haupt-Code entfernt hat (und beispielsweise einige Tests kaputt gemacht hat, die von einem anderen, fertiggestellten Branch gemergt wurden), wird man sich dessen beim nächsten Branch-Build bewusst sein, sodass vorher alles in Ordnung gebracht werden kann.

Darüber hinaus kann manuelles Mergen gelegentlich dazu führen, dass zwei Entwickler ihre Branches gleichzeitig mergen; ein Teil des Codes, der zum Upstream-Branch geht, wird damit nicht im Trockenlauf getestet. Hier kann Bamboo genutzt werden, um den Merge automatisch zur Build-Zeit durchzuführen, der Merge wird nur dann zurück in die Repository geschickt, wenn der Build erfolgreich läuft.

Ist der Entwickler der Ansicht, dass seine Arbeit am Branch erledigt ist, kann er sich in Bamboo einloggen und einen angepassten Build laufen lassen. Wenn der Branch sauber mit dem Upstream mergt und es keine Testfehler gibt, pusht Bamboo den Merge ans Ende des Builds.

So lässt es sich komplett vermeiden, dass Branches ungetestet in den Upstream gemergt werden. Das hat aber seinen Preis: In der Situation, in der mehrere Entwickler den individuellen Build gleichzeitig ausführen, wird einer von ihnen abgelehnt und muss den Branch erneut laufen lassen.

Diese Technik ist vorteilhaft für Teams, in denen Branch-Merges mehrmals am Tag stattfinden. Müssen Branches allerdings mehrmals pro Stunde gemergt werden und sollen sie den Upstream so schnell wie möglich erreichen, ist diese Methode nicht praktikabel, speziell wenn die Test-Suite sehr lange läuft. (Verlängerte Laufzeiten erhöhen die Wahrscheinlichkeit, dass zwei Leute ihre Sachen während des einen Run Cycles mergen wollen.)

Branch Updater

Aktuell laufen die Bamboo-Builds in einen Branch, wenn es in diesem Branch einen neuen Commit gibt. Das schont einiges an Rechenkraft und beruht auf der Annahme, dass Bruchstellen in dem gemergten Code (Dev-Branch und Upstream-Branch) normalerweise von fehlerhaftem Code im Branch verursacht werden und nicht von Code vom Upstream.

Allerdings macht man sich möglicherweise Sorgen um die Abweichung zwischen den Feature-Branches und dem Upstream-Branch. Daher entsteht mitunter der Wunsch, neuen Code, der in den Upstream-Branch geschickt wird, immer irgendwie mit den Entwicklungs-Branches zu testen. Das vermeidet Überraschungen, wenn ein älterer Branch (keine Commits über einige Tage oder Wochen), der auf Grün steht, allmählich so stark vom Upstream abweicht, dass er ohne zusätzliche Arbeit nicht mehr in den Upstream-Branch gemergt werden kann. Oder man wünscht, dass, wann immer ein neuer Commit im Upstream-Branch ankommt, der Branch wieder trocken gegen die Upstream-Head-Revision getestet wird.

Anleitungen dazu finden sich in der Bamboo-Dokumentation, aber es gibt hier einen kleinen Trick, um die Dinge zum Laufen zu bringen: Man fügt eine duplizierte Repository in der Plan-Konfiguration hinzu, die auf denselben Upstream-Branch zeigt.

Zusammen mit der automatischen Branch Detection und der Gatekeeper-Strategie wird dies zu einem mächtigen Werkzeug, um Entwicklungs-Branches “mergebar” mit dem Upstream zu halten.

Um noch mehr Ressourcen zu schonen, kann man sogar exakt festlegen, welche Branches diese spezielle Behandlung erhalten sollten. Vielleicht sollen nicht alle Branches auf „Abgestandenheit“ überwacht werden, weil einige von ihnen zu einem Slacktime-Projekt oder ähnlichem gehören, das nicht so wichtig ist wie ein kommerzielles Projekt.

Der Nachteil ist, dass Bamboo (wenig überraschend) anfängt, doppelte Commits für die Plans zu reporten. Das ist nicht sehr praktisch, richtet aber andererseits auch keinen Schaden an.

Bamboo einführen und/oder lizenzieren? Wir sind Ihr Partner!

Interessieren Sie sich für Bamboo von Atlassian als Integrations-Server? Wir sind offizieller Atlassian-Vertriebspartner: Gerne beraten wir Sie und unterstützen Sie bei der Lizenzierung. Wenn Sie Lizenzen für Atlassian-Produkte bei //SEIBERT/MEDIA kaufen, gewähren wir Ihnen übrigens einen Naturalrabatt in Höhe von 10% in Form von Dienstleistungen. Bitte sprechen Sie uns an.

Ausführliche Infos über Bamboo, seine Features und sein Lizenzmodell in unserer Infothek
Bamboo: Wie viele Build Agents braucht mein Projekt?
Continuous Integration: Zehn Argumente für Bamboo
Stash von Atlassian ist da: Git-Repository-Management für Unternehmen
Der Eclipse Connector von Atlassian: JIRA, Bamboo und FishEye in der IDE