Für einen großen Kunden aus der Industrie entwickelt die Scandio seit mehr als 12 Monaten ein auf Golang basiertes Gateway System zur Anbindung von einigen Millionen IoT Geräten. Das Gateway ist somit Single Point of Contact für alle Zugriffe auf Cloud Services beim Kunden. Für das komplexe Release Management musste durch das signifikante Wachstum des Projektes und die Abhängigkeit zu anderen Softwarekomponenten ein neues, vollständig automatisiertes Tooling entwickelt werden.

Bisher wurde ein neues Release mittels Git Tagging auf dem Master Branch eingeleitet. Dabei bestimmte der Tag Name (33.0.0), der auf dem jeweiligen Sprint basierte, die Version. Das war inhaltlich falsch und die Version hat keinen Aufschluss über den tatsächlichen Inhalt ermöglicht.

Aus diesem Grund hat sich das Team für die Einführung von Sematic Versioning entschieden.


Die Lösung

Semantic-Release im Tandem mit Commitlint

Semantic-Release automatisiert das Erstellen von Releases und ersetzt das manuelle Taggen, indem es basierend auf den seit der letzten Version angesammelten Commits eine neue Versionsnummer vergibt und als Git Tag erstellt. Dabei nutzt es den Titel der Commit Messages, um die Versionsnummer von minor oder patch zu erhöhen. Dazu muss der Titel jeder Commit Message einem festen Format folgen und mit einer Typ-Angabe beginnen. Damit diese Regeln eingehalten werden, kommt Commitlint ins Spiel.

Beispielhaft sind hier die Konfigurationen des aktuellen Websocket-Managers angeheftet:

Semantic Release

.commitlintrc.yaml

Diese Konfigurationsdatei von Commitlint enthält eine Übersicht über die möglichen Commit-Typen und basiert auf dem Regelset von Config-Conventional.

Um Commitlint auszuführen, verwenden wir in Bamboo diesen Befehl:

npx commitlint --from master

Zuvor muss lediglich der aktuelle Stand ausgecheckt werden.

Der Output sieht dann beispielsweise wie folgt aus:

Semantic Release

Hier wurde der Typ (subject) vergessen, weswegen der Input direkt mit “Add…” losgeht.


.relaserc.yaml

Die Konfigurationsdatei von Semantic-Release mapped zunächst “releaseRules”. Commit-Typen werden Release-Typen zugeordnet.

Der nächste Block erstellt Links zu zugehörigen Issues und für Vergleiche (diffs) der neuen und der bisherigen Version, welche dann in den Changelog eingebunden werden.

Semantic-Release kann ebenfalls verwendet werden, um einfache bash-Scripte auszuführen. In unserem Fall verwenden wir ein Inline-Script, um die neue Version auch in unseren Helm Charts zu pflegen.

Semantic-Release kann hier noch weitaus mehr, diese Features werden aktuell jedoch nicht verwendet. Zum Beispiel können neue Versionen via npm veröffentlicht werden.

Um Semantic-Release in Bamboo auszuführen wurde ein Docker Container gebaut, auf dem die nötigen npm Pakete vorinstalliert sind. Um das Tool dann in Bamboo auszuführen, wird die Build Stage in diesem Container gestartet und folgender Befehl ausgeführt:

npx semantic-release

Das neue Changelog wird ebenfalls automatisiert befüllt. Dank unserem Kollegen Joschi, der uns immer wieder auf diesen Blogpost über aussagekräftige Commit-Messages hingewiesen hat, schreiben wir schon länger wertvolle Commit Messages. Das sorgt dafür, dass wir nun ein von Menschen lesbares Changelog erhalten. In Zukunft können wir dann Fragen von Partnern wie “Welche Version des Websocket-Managers habt ihr denn deployed? Ist da unser Feature Request schon dabei?” mit einem Verweis auf das Changelog beantworten.

Semantic Release

Nach dem Erhöhen der Version und den Änderungen an Dateien wird ein neuer Commit vom Semantic-Release Bot erstellt und gepusht. Bamboo triggert daraufhin einen weiteren Build, von welchem dann ein Release in Bamboo erstellt und ein Deployment durchgeführt werden kann.