Blog

8 Schritte zum Software-Release-Management für Agile Teams

APR 11, 2018

In einigen Teamkonstellationen, insbesondere bei Teams, die neu mit Agile arbeiten, fehlen etablierte DevOps-Prinzipien und Infrastrukturentwickler, die beim Release einer neuen Produktversion unterstützen können.

Lucas Mancini

Außerdem sehen wir in größeren Unternehmen, die zuvor mit traditionelleren Wasserfallmethoden gearbeitet haben, häufig Informationssilos entstehen. Agile Arbeitsweisen sind entscheidend, um diese Silos aufzubrechen, doch das geschieht nicht über Nacht. Ein Team weiß nicht immer, woran ein anderes arbeitet; die Prozesse eines Teams könnten für ein anderes äußerst hilfreich sein, aber dieses weiß schlicht nichts davon. Wenn Wissen nicht gründlich dokumentiert wird, kann dies meiner Ansicht nach zu Verwirrung und Ineffizienz führen.

In diesem Artikel gebe ich einige Tipps dazu, wie ihr den Release-Prozess formalisieren könnt – insbesondere aus Sicht der Entwickler.

Abschnitt 1: Checkliste für das Software-Release-Management

Abschnitt 2: Best Practices nutzen

Abschnitt 3: Continuous Integration

Die Checkliste für das Software-Release-Management

In diesem Abschnitt schlage ich einige Schritte vor, mit denen ihr eure eigene Checkliste für den Release-Prozess erstellen könnt. Einige dieser Schritte sind keineswegs verpflichtend. Jede App ist anders und jedes Team arbeitet auf seine eigene Weise. Passt die Checkliste daher gerne an und nehmt Änderungen vor, die besser zu eurem Workflow passen.

1. Einen Release-Branch erstellen

Wahrscheinlich kennt ihr das Konzept eines Git-Workflows oder die Idee von Release-Branches.

Idealerweise solltet ihr mindestens drei Branches haben:

  • master: Dieser Branch sollte den aktuellen Stand der Produktionsumgebung widerspiegeln. Jeder neue Commit auf master sollte ausschließlich ein neues Release enthalten.

  • develop: Dieser Branch sollte die fertiggestellten (und getesteten) kommenden Features enthalten. Üblicherweise wird für jedes Feature ein separater Branch erstellt, der anschließend mit develop zusammengeführt wird, sobald das Feature fertig ist.

  • release: release-Branches enthalten eine Sammlung von Commits, die bereit für die Produktionsumgebung sind, sowie kleinere Bugfixes für das Release.

Beachtet, dass release-Branches nach Abschluss des Releases gelöscht werden sollten. Anders als master oder develop, die stets bestehen bleiben, werden diese Branches daher laufend erstellt und wieder gelöscht.

Um in eurem Git-Terminal einen neuen release-Branch aus dem develop-Branch zu erstellen, gebt Folgendes ein:

$ git checkout -b release/x.y.z

Es ist sinnvoll, eine Namenskonvention wie die oben definierte zu verwenden und x.y.z je nach Bedarf durch die Versionsnummer major.minor.patch zu ersetzen. Diese Regelung solltet ihr im Team festlegen und konsequent einhalten.

Wichtig ist außerdem: Wenn ihr Bugfixes im Release-Branch implementiert, solltet ihr nicht vergessen, sie auch wieder mit develop zusammenzuführen. Der Hauptzweck des Release-Branches besteht darin, eine Vorschau darauf zu erhalten, wie sich die App nach dem Deployment in die Produktionsumgebung verhalten soll.

Toptal

Das Organisieren und Nachverfolgen verschiedener Release-Branches ist ein entscheidender Aspekt des Release-Managements.

2. Versionsnummer erhöhen

Im nächsten Schritt erhöht oder ändert ihr die Versionsnummer im release-Branch.

Öffnet AndroidManifest.xml / package.json / pom.xml / oder die Datei, in der die Version der App in eurem Projekt gespeichert ist (das kann je nach Projekt variieren), aktualisiert die Versionsnummer und committet die Änderungen anschließend in den aktuellen release-Branch.

Die Aktualisierung der Versionsnummer ist aus zwei Gründen wichtig.

Erstens könnt ihr nachvollziehen und zuordnen, welche Features in welcher Version eingeführt wurden. Zweitens kennt ihr die verwendete Version, falls Nutzer Fehler beheben müssen oder euch für Support kontaktieren. Bei einer mobilen App wird die Versionsnummer, die ihr in diesem Schritt aktualisiert, üblicherweise auf Nutzerseite im Bereich Über oder in Google Play beziehungsweise im Apple App Store angezeigt. Dieser Schritt bietet auch eine gute Gelegenheit, konfigurationsdateien für die jeweilige Umgebung zu aktualisieren – wobei ich empfehlen würde, diese in einem separaten Repository zu verwalten. Dazu kann beispielsweise gehören, dass der Branch auf die Produktionsdatenbank verweist, oder andere Anpassungen, die für den Build-Prozess erforderlich sind.

Abschließend empfiehlt es sich, den release-Branch zu origin zu pushen, damit er euren anderen Entwicklern zur Verfügung steht:

$ git push -u origin release/x.y.z

3.a) Den Release-Branch in master mergen und taggen

Für die Produktion sollte nur der Branch master deployed werden. Daher müssen wir in diesem Schritt den Branch release in master mergen.

$ git checkout master
																				$ git merge --no-ff release/x.y.z
																				$ git push

Das Flag --no-ff ist optional. Seine Verwendung wird jedoch empfohlen, um die Erstellung eines neuen Commit-Objekts zu erzwingen, auch wenn der Merge mit der Fast-Forward-Technik durchgeführt werden kann.

Als Nächstes ist es Zeit, das Release auf dem Branch master zu taggen:

$ git tag -a x.y.z -m 'description of new version, features or fixes included'

Tags sind nützlich, weil sie diesen bestimmten Punkt in der Historie des Git-Repositorys festhalten. Später könnt ihr darauf zurückkommen, um einen separaten Branch für einen bestimmten Tag zu erstellen.

3.b) Einen Pull Request verwenden, um den Release-Branch zu mergen

Eine weitere häufig genutzte Möglichkeit ist, einen Pull Request zu verwenden, um den Branch release in master zu mergen.

Dieser Ansatz bietet zahlreiche Vorteile. Er schafft einen neuen Raum für die Zusammenarbeit, den das Team nutzen kann, um verschiedene Themen rund um das Release zu besprechen. Außerdem ist dies ein guter Zeitpunkt, einen zusätzlichen Gate für einen Code-Review-Prozess einzuführen: Mehr Augen prüfen den einzuführenden Code und können mögliche Änderungen diskutieren.

Tools wie GitHub und Bitbucket ermöglichen es euch, Pull Requests in eure Workflows zu integrieren. Mit diesen Tools gebt ihr Git-Befehle nicht manuell ein. Stattdessen verwendet ihr eine Weboberfläche, um den Quell-Branch (release) und den Ziel-Branch (master) festzulegen. Anschließend fügt ihr einen oder mehrere Reviewer hinzu, die Inline-Kommentare zu den neuen Änderungen schreiben, Verbesserungen vorschlagen und mehr können.

Nachdem alle Reviewer den Pull Request genehmigt haben, könnt ihr die Änderungen automatisch in master mergen, indem ihr einfach auf eine Schaltfläche in der Benutzeroberfläche klickt.

4. master in die Produktionsumgebung deployen

In dieser Phase ist es Best Practice, vor dem Deployment einen Tester im Team einen Smoke Test durchführen zu lassen. Dieser kann in einer separaten Checkliste definiert sein. Sinnvoll ist es, den Branch master in einer separaten Testumgebung zu deployen. Der Tester kann dann einige grundlegende Aktionen ausführen, um sicherzustellen, dass nach dem Merge im neuesten Build nichts schiefgelaufen ist. Wie ein Smoke Test durchgeführt wird, würde den Rahmen dieses Artikels sprengen, aber im Web findet ihr viele Informationen dazu. Das Ergebnis des Smoke Tests kann in die Release-Checkliste oder -Tabelle aufgenommen werden, um aufgetretene Probleme zu dokumentieren.

Jetzt könnt ihr die Änderungen deployen und live schalten. Deployt den Branch master.

Features and Branches

Vergesst nicht zu prüfen, ob das Deployment erfolgreich war und alles wie erwartet funktioniert.

5. Zurück in develop mergen und den Release-Branch löschen

Das Release ist nun fast abgeschlossen. Ihr solltet den Branch release in develop mergen, um die Versionsnummer dort zu aktualisieren und alle Bugfixes in den Hauptentwicklungs-Branch zu übertragen:

$ git checkout develop
																				$ git merge release/x.y.z

Jetzt ist es Zeit, den Branch release zu entfernen:

$ git branch -d release/x.y.z

6. Changelog-Erstellung

Im Stammverzeichnis eures Projekts sollte sich eine Datei namens CHANGELOG.md (oder eine gleichwertige Datei) befinden. Bei jedem neuen Release solltet ihr dort einen neuen Eintrag hinzufügen, um alles zu dokumentieren, was darin enthalten ist: Bugfixes, neue Features, bekannte Probleme und weitere relevante Informationen in Form von Release Notes. Das ist für Nutzer und Mitwirkende besonders hilfreich, um zu sehen, welche Änderungen zwischen den einzelnen Releases (oder Versionen) des Projekts vorgenommen wurden.

Der Changelog-Eintrag enthält das Datum, die Versionsnummer und einige Hinweise zum Release. Die Einträge sollten in umgekehrt chronologischer Reihenfolge geführt werden. Hier ist eine einfache Vorlage, die ich verwendet habe und die ihr an euer Projekt anpassen könnt:

<app's name or component released>  |
																				<developer's name in charge of release> | <developer's email>
																				Features:
																				* <ticket/issue number>: <ticket/issue summary> ()
																				* ...
																				Bugs fixed:
																				* <ticket/issue number>: <ticket/issue summary> ()
																				* ...
																				Enhancements:
																				* <ticket/issue number>: <ticket/issue summary> ()
																				* ...
																				Optional: known issues plus other release notes.

Außerdem lässt sich dieser Schritt vollständig automatisieren, indem ihr ein einfaches Skript schreibt, das das Git-Log durchläuft und den Changelog-Eintrag automatisch erstellt. Beachtet jedoch, dass der Grad der Automatisierung direkt von der Strenge eures Commit-Message-Formats abhängt. Ich halte es stets für Best Practice, sich im Team auf ein bestimmtes Format für Commit Messages zu einigen. Wenn ihr Richtlinien für den Stil der Commit Messages befolgt, lassen sie sich einfacher parsen und die Erstellung des Changelogs lässt sich mit höherer Wahrscheinlichkeit automatisieren.

7. Mit Stakeholdern kommunizieren

Wichtig ist vor allem, nicht zu vergessen, zu kommunizieren, dass ein neues Release verfügbar ist.

Ihr könnt eure Teams beispielsweise über ein internes Messaging-Tool wie HipChat darüber informieren, dass ein neues Release abgeschlossen wurde. Ich empfehle, einen eigenen Raum (z. B. Releases) einzurichten, der ausschließlich für die Kommunikation von Release-bezogenen Ereignissen vorgesehen ist. Dank der Integration von HipChat mit Dev-Tools wie JIRA und Bitbucket könnt ihr dafür sogar automatisierte Benachrichtigungen einrichten.

Alternativ könnt ihr einen Blogbeitrag schreiben – intern über Confluence oder in eurem öffentlichen Blog – oder das Release über Social Media ankündigen. Je nach Art eurer Organisation sind weitere Maßnahmen möglich.

8. Den Issue Tracker pflegen

Nach einem Release müsst ihr wahrscheinlich den Status einiger Tickets aktualisieren, um den Überblick über die Bugfixes und Features zu behalten, die aktuell in Produktion sind. In der Regel werden dafür einige Tags geändert. Bei kleinen Projekten nutze ich beispielsweise ein release-pending-Tag, das ich nach Abschluss des Releases entferne.

Wenn ihr für jede neue Version Milestones verwendet, müsst ihr deren Status wahrscheinlich aktualisieren oder sie als abgeschlossen markieren. Issue Tracker wie JIRA Software ermöglichen es euch sogar, das Release zu planen und mit Sprints abzustimmen, nachzuverfolgen, ob ein Bug ein Release blockiert, und weitere nützliche Informationen transparent zu machen.

Alles hängt davon ab, wie ihr das Tool nutzt. Ich möchte lediglich darauf hinweisen, dass die Aktualisierung der Informationen im Issue Tracker in eure Release-Checkliste aufgenommen werden sollte.

Zur Automatisierung des Release-Prozesses

Vielleicht ist euch aufgefallen, dass sich – abgesehen vom oben beschriebenen Schritt zum Changelog – viele der zuvor genannten Schritte ebenfalls automatisieren lassen.

Die Möglichkeit, Teile des Release-Prozesses zu automatisieren, ist ein großer Vorteil und spart viel Zeit. Ich empfehle, Skripte zu erstellen oder Wege zu finden, einzelne Schritte zu automatisieren, und dann auf Continuous Delivery hinzuarbeiten. Das kann Risiken und Kosten senken sowie den Zeitaufwand der Entwickler für das Management des Releases reduzieren. Dadurch könnt ihr häufiger Releases bereitstellen und die für die Entwicklung eingeplante Zeit produktiver nutzen.

Der heilige Gral von DevOps ist die Möglichkeit, eine neue Version per Knopfdruck – oder durch Ausführen eines Befehls – bereitzustellen, der den Release-Prozess automatisch auslöst. Noch besser wäre ein System, das zu einem festgelegten Zeitpunkt automatisch eine neue Version eurer Software veröffentlicht. Das ist schwer zu erreichen, weil ihr auch große Teile des Testprozesses automatisieren müsst. Unmöglich oder so weit hergeholt, wie manche glauben, ist es jedoch nicht.

Release

Best Practices nutzen

In diesem Abschnitt beschreibe ich einige empfohlene Praktiken, die sich für mich bewährt haben – entweder um den Release-Prozess reibungsloser zu gestalten oder um Vorsichtsmaßnahmen für den Fall zu treffen, dass etwas schiefgeht.

Am besten geeigneten Tag für das Release wählen

Ich veröffentliche Apps, an denen ich arbeite, normalerweise donnerstags zwischen Mittag und Geschäftsschluss.

Wenn ihr von Montag bis Freitag arbeitet, ist es keine gute Idee, an einem Freitag live zu gehen. Falls nach dem Release etwas nicht funktioniert, habt ihr bis Montag keine Zeit, es zu beheben – es sei denn, ihr möchtet am Wochenende arbeiten. Deshalb sind Releases am Donnerstag praktischer: Am Freitag könnt ihr die neue Version nach dem Deployment überwachen, Probleme beheben oder bei Bedarf ein Rollback durchführen.

Ein weiterer wichtiger Punkt ist die Zeitzone, in der sich die meisten eurer Nutzer befinden. Plant das Release für eine Zeit mit geringem Traffic, um mögliche Schäden zu minimieren, falls etwas fehlschlägt. Wenn eure Nutzer weltweit verteilt sind, kann das schwierig sein. Dennoch solltet ihr immer recherchieren und den besten Zeitpunkt festlegen.

Vor einem neuen Release die Datenbank sichern

Falls ihr eure Datenbank nicht ohnehin regelmäßig sichert, empfehle ich dringend, einen Schritt in euren Release-Prozess aufzunehmen, der euch daran erinnert, vor Beginn des Releases ein Backup zu erstellen.

Gestaffelte Rollouts

Habt ihr euch schon einmal gefragt, warum es Tage oder sogar Wochen dauert, bis eine neue Funktion auf eurem Smartphone verfügbar ist, nachdem ein Anbieter ihre Einführung angekündigt hat? Der Grund ist, dass viele Unternehmen gestaffelte Rollouts einsetzen.

Facebook macht das schon seit Langem. Das Unternehmen testet ein neues Feature zunächst mit fünf oder zehn Prozent seiner Nutzer und erhöht diesen Anteil schrittweise, bis 100 Prozent der Nutzerbasis erreicht sind. Während des gestaffelten Rollouts müsst ihr Nutzerfeedback und Crash-Reports genau beobachten. Auf Grundlage dieser Informationen könnt ihr das Release verschieben oder Fehler beheben, bevor sie alle Nutzer betreffen.

Users

Continuous Integration

Continuous Integration ist aus vielen Gründen eine empfehlenswerte Praxis. Erstens könnt ihr damit Fehler frühzeitig erkennen und die Erfolgsquote eurer Releases erhöhen. Zweitens ist sie der erste logische Schritt vor der Implementierung von Continuous Delivery und vollständiger Automatisierung, wie zuvor beschrieben.

Das Thema ist umfangreich, und es gibt viele Bücher und Blogbeiträge dazu. Ich erwähne es hier jedoch, weil ich überzeugt bin, dass es euch deutlich mehr Vertrauen in eure Abläufe gibt. Zu den vielen Vorteilen von CI gehören geringere Risiken, mehr Transparenz darüber, was funktioniert und was nicht, die frühere Erkennung von Bugs, häufigere Deployments und vieles mehr.

Der erste Schritt zur Einführung von CI ist die Einrichtung eines „Continuous-Integration-Servers“. Empfehlenswerte Tools zum Ausprobieren sind Bamboo, Jenkins und Travis.

Abschluss: Es wird alles gut

Abschließend möchte ich sagen, dass ein klar definierter Release-Prozess sehr wichtig ist – unabhängig von seiner Komplexität, der Nutzerbasis oder der Größe eurer Organisation.

Falls ihr noch keinen habt, solltet ihr euch Gedanken über einige grundlegende Schritte machen. Dieser und ähnliche Leitfäden helfen euch dabei, gemeinsam mit eurem Team Ideen zu sammeln und einen ersten Entwurf zu erstellen. Probiert ihn beim nächsten Release aus und entwickelt ihn anschließend weiter. So entsteht mit der Zeit euer eigener Release-Prozess.

Danach solltet ihr überlegen, wie ihr Teile des Prozesses automatisieren könnt. Identifiziert Bereiche mit Verbesserungspotenzial. Prüft, wie sich die Release-Zeit durch kleine Optimierungen verkürzen lässt. Automatisierung sollte euer langfristiges Ziel sein. Plant sie aber nicht von Anfang an vollständig ein, sonst scheitert ihr möglicherweise an diesem zu großen Sprung. Wie bei jedem Prozess ist es besser, ihn schrittweise zu verbessern.

  • Atlassian
  • Agile

Subscribe to our newsletter