Eine semantisch versionierte Software erleichtert die Pflege und Kommunikation von Änderungen. Dies ist jedoch nicht einfach. Selbst nach dem manuellen Zusammenführen von PRs, dem Taggen von Commits und dem Pushen von Releases müssen Sie immer noch Release-Notizen schreiben. Es gibt viele verschiedene Schritte, und viele sind repetitiv und zeitaufwändig.
Lassen Sie uns betrachten, wie wir einen effizienteren Ablauf schaffen und **unseren Release-Prozess vollständig automatisieren** können, indem wir semantische Versionierung in einen Continuous-Deployment-Prozess integrieren.
Semantische Versionierung
Eine semantische Version ist eine Zahl, die aus drei durch einen Punkt getrennten Zahlen besteht. Zum Beispiel ist 1.4.10 eine semantische Version. Jede der Zahlen hat eine spezifische Bedeutung.
Major-Änderung
Die erste Zahl ist eine Major-Änderung, was bedeutet, dass sie eine Breaking Change beinhaltet.
Minor-Änderung
Die zweite Zahl ist eine Minor-Änderung, was bedeutet, dass sie Funktionalität hinzufügt.
Patch-Änderung
Die dritte Zahl ist eine Patch-Änderung, was bedeutet, dass sie einen Bugfix beinhaltet.
Es ist einfacher, semantische Versionierung als Breaking . Feature . Fix zu betrachten. Es ist eine präzisere Art, eine Versionsnummer zu beschreiben, die keinen Raum für Interpretationen lässt.
Commit-Format
Um sicherzustellen, dass wir die korrekte Version veröffentlichen (durch korrektes Erhöhen der semantischen Versionsnummer), müssen wir unsere Commit-Nachrichten standardisieren. Durch ein standardisiertes Format für Commit-Nachrichten können wir wissen, wann welche Nummer erhöht werden muss, und einfach eine Release-Notiz generieren. Wir werden die Angular Commit-Nachrichten-Konvention verwenden, können dies aber später ändern, falls Sie etwas anderes bevorzugen.
Es funktioniert so
<header>
<optional body>
<optional footer>
Jede Commit-Nachricht besteht aus einem Header, einem Body und einem Footer.
Der Commit-Header

Der Header ist obligatorisch. Er hat ein spezielles Format, das einen Typ, einen optionalen Scope und ein Subject beinhaltet.
Der Typ des Headers ist ein obligatorisches Feld, das angibt, welchen Einfluss der Inhalt des Commits auf die nächste Version hat. Er muss einer der folgenden Typen sein:
- feat: Neue Funktion
- fix: Bugfix
- docs: Änderung an der Dokumentation
- style: Änderungen, die die Bedeutung des Codes nicht beeinflussen (z. B. Leerzeichen, Formatierung, fehlende Semikolons usw.)
- refactor: Änderungen, die weder einen Fehler beheben noch eine Funktion hinzufügen
- perf: Änderung, die die Leistung verbessert
- test: Fehlende Tests hinzufügen oder bestehende korrigieren
- chore: Änderungen am Build-Prozess oder an Hilfswerkzeugen und Bibliotheken, wie z. B. der Generierung von Dokumentationen
Der Scope ist eine Gruppierungseigenschaft, die angibt, welchem Subsystem der Commit zugeordnet ist, z. B. einer API, dem Dashboard einer App oder Benutzerkonten usw. Wenn der Commit mehr als ein Subsystem modifiziert, können wir stattdessen einen Stern (*) verwenden.
Das Subject des Headers sollte eine kurze Beschreibung dessen enthalten, was getan wurde. Es gibt einige Regeln beim Schreiben eines solchen:
- Verwenden Sie den Imperativ im Präsens (z. B. "ändern" statt "geändert" oder "Änderungen").
- Machen Sie den ersten Buchstaben des ersten Wortes klein.
- Lassen Sie den Punkt (
.) am Ende weg. - Vermeiden Sie Subjects, die länger als 80 Zeichen sind. Der Commit-Body.
Ähnlich wie beim Header-Subject verwenden Sie für den Body den Imperativ im Präsens. Er sollte die Motivation für die Änderung enthalten und diese mit dem vorherigen Verhalten kontrastieren.
Der Commit-Footer
Der Footer sollte alle Informationen über Breaking Changes enthalten und ist auch der Ort, um Issues zu referenzieren, die dieser Commit schließt.
Informationen zu Breaking Changes sollten mit BREAKING CHANGE: gefolgt von einem oder zwei Leerzeilen beginnen. Der Rest der Commit-Nachricht folgt hier.
Durchsetzung eines Commit-Formats
Die Arbeit in einem Team ist immer eine Herausforderung, wenn man etwas standardisieren muss, dem alle folgen sollen. Um sicherzustellen, dass jeder den gleichen Commit-Standard verwendet, werden wir Commitizen verwenden.
Commitizen ist ein Befehlszeilenwerkzeug, das die Verwendung eines konsistenten Commit-Formats erleichtert. Ein Repository Commitizen-freundlich zu machen, bedeutet, dass jeder im Team git cz ausführen und eine detaillierte Aufforderung zum Ausfüllen einer Commit-Nachricht erhalten kann.

Generierung eines Releases
Nun, da wir wissen, dass unsere Commits einem konsistenten Standard folgen, können wir mit der Generierung eines Releases und von Release-Notizen beginnen. Dafür verwenden wir ein Paket namens semantic-release. Es ist ein gut gepflegtes Paket mit großartiger Unterstützung für mehrere Continuous Integration (CI)-Plattformen.
semantic-release ist der Schlüssel zu unserer Reise, da es alle notwendigen Schritte für ein Release durchführt, einschließlich:
- Ermittlung der zuletzt veröffentlichten Version
- Bestimmung des Release-Typs basierend auf den Commits, die seit dem letzten Release hinzugefügt wurden
- Generierung von Release-Notizen für Commits, die seit dem letzten Release hinzugefügt wurden
- Aktualisierung einer
package.json-Datei und Erstellung eines Git-Tags, der der neuen Release-Version entspricht - Pushen des neuen Releases
Jede CI funktioniert. Für diesen Artikel verwenden wir GitHub Actions, da ich gerne die vorhandenen Features einer Plattform nutze, bevor ich auf eine Drittanbieterlösung zurückgreife.
Es gibt mehrere Installationsmöglichkeiten für semantic-release, aber wir verwenden semantic-release-cli, da es schrittweise vorgeht. Lassen Sie uns npx semantic-release-cli setup im Terminal ausführen und dann den interaktiven Assistenten ausfüllen.

Das Skript tut ein paar Dinge:
- Es führt
npm addusermit den bereitgestellten NPM-Informationen aus, um eine.npmrczu generieren. - Es erstellt ein GitHub Personal Token.
- Es aktualisiert
package.json.
Nachdem die CLI abgeschlossen ist, fügt sie semantic-release zu package.json hinzu, installiert es aber nicht tatsächlich. Führen Sie npm install aus, um es zusammen mit anderen Projekt-Abhängigkeiten zu installieren.
Das Einzige, was uns bleibt, ist die Konfiguration der CI über GitHub Actions. Wir müssen manuell einen Workflow hinzufügen, der semantic-release ausführt. Lassen Sie uns einen Release-Workflow in .github/workflows/release.yml erstellen.
name: Release
on:
push:
branches:
- main
jobs:
release:
name: Release
runs-on: ubuntu-18.04
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Setup Node.js
uses: actions/setup-node@v1
with:
node-version: 12
- name: Install dependencies
run: npm ci
- name: Release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# If you need an NPM release, you can add the NPM_TOKEN
# NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
run: npm run release
Steffen Brewersdorff leistet bereits hervorragende Arbeit bei der Abdeckung von CI mit GitHub Actions, aber lassen Sie uns kurz darauf eingehen, was hier geschieht.
Dies wartet auf den Push auf den main-Branch und führt erst dann die Pipeline aus. Sie können dies gerne anpassen, um auf einem, zwei oder allen Branches zu funktionieren.
on:
push:
branches:
- main
Dann wird das Repository mit checkout heruntergeladen und Node installiert, damit npm die Projekt-Abhängigkeiten installieren kann. Ein Testschritt könnte hier hinzugefügt werden, wenn Sie das bevorzugen.
- name: Checkout
uses: actions/checkout@v2
- name: Setup Node.js
uses: actions/setup-node@v1
with:
node-version: 12
- name: Install dependencies
run: npm ci
# You can add a test step here
# - name: Run Tests
# run: npm test
Schließlich lassen wir semantic-release die ganze Magie wirken.
- name: Release
run: npm run release
Pushen Sie die Änderungen und schauen Sie sich die Aktionen an.

Nun wird jedes Mal, wenn ein Commit auf einen bestimmten Branch gemacht (oder gemerged) wird, die Aktion ausgeführt und ein Release erstellt, komplett mit Release-Notizen.

Release-Party!
Wir haben erfolgreich einen CI/CD-Workflow für semantische Releases erstellt! Nicht so schmerzhaft, oder? Die Einrichtung ist relativ einfach und es gibt keine Nachteile, einen semantischen Release-Workflow zu haben. Er erleichtert nur die Nachverfolgung von Änderungen erheblich.
semantic-release hat viele Plugins, die noch fortschrittlichere Automatisierungen ermöglichen können. Zum Beispiel gibt es sogar einen Slack-Release-Bot, der in einen Projektkanal posten kann, sobald das Projekt erfolgreich bereitgestellt wurde. Kein Gang zu GitHub mehr, um Updates zu finden!