Daniel Schock
13 Oct 2025
Implementierung eines automatisierten Release-Workflows mit Conventional Commits und Semantic Versioning
Manuelle Software-Releases stellen eine häufige Quelle für Belastungen und Ineffizienz in Entwicklungsteams dar. Der Prozess umfasst oft nächtliche Deployments, manuelle Checklisten und die mühsame Erstellung von Changelogs. Dieser risikobehaftete, manuelle Arbeitsablauf birgt nicht nur ein erhebliches Potenzial für menschliche Fehler, sondern kann auch eine „Release Anxiety“ begünstigen, welche agile Entwicklungszyklen verlangsamt. Die Entscheidung, an einem Freitagnachmittag einen kritischen Fix zu mergen, wird dadurch häufig verzögert.

Ein idealer Workflow würde es jedoch ermöglichen, dass jeder Merge in den Main-Branch sicher einen neuen, korrekt versionierten Release auslöst, komplett mit strukturierten, automatisch generierten Release Notes. Dies ist nicht nur ein Prinzip moderner CI/CD-Praktiken, sondern eine erreichbare Realität. Durch die Nutzung einer strukturierten Commit History können Software-Releases zu einem routinierten, vorhersagbaren und vollständig automatisierten Prozess werden.
Dieser Artikel bietet eine technische Anleitung, um dieses Automatisierungsniveau durch die Implementierung der “Conventional Commits”-Spezifikation und des semantic-release-Tools zu erreichen.
Das Kernprinzip: Die Steuerung des Releases durch die Commit History
Der Schlüssel zu dieser Automatisierung liegt in einem konzeptionellen Wandel: Die Git Commit History wird nicht mehr nur als Protokoll von Änderungen betrachtet, sondern als die alleinige Quelle der Wahrheit für die Versionierung. Anstatt dass ein Entwickler entscheidet, ob eine Änderung einen Patch-, Minor- oder Major-Release rechtfertigt, wird diese Entscheidung direkt aus der Historie des Codes abgeleitet.
Der daraus resultierende Vorteil ist signifikant: Der Release-Prozess wird von subjektiven Entscheidungen entkoppelt und zu einer direkten, logischen Konsequenz der geleisteten Arbeit. Jeder Commit trägt eine eigene semantische Bedeutung, wodurch die Versionsnummer zu einem vorhersagbaren Ergebnis anstatt einer Schätzung wird. Diese Philosophie bildet die Grundlage der Automatisierung.
Die Grundlage: Etablierung eines Standards für Commit-Nachrichten
Die Voraussetzung für jede Automatisierung ist die Etablierung einer standardisierten, maschinenlesbaren Sprache für die Kommunikation. Die Conventional Commits-Spezifikation bietet einen solchen Standard, indem sie eine klare und verbindliche Struktur für Git Commit Messages vorschreibt, die Mehrdeutigkeiten beseitigt und die Absicht jeder Änderung explizit macht.
<type>[optionaler scope]: <description>
[optionaler body]
[optionale(r) footer]Der type-Bezeichner ist die entscheidende Komponente, die die Auswirkung eines Commits auf die Versionierung gemäß den Prinzipien des Semantic Versioning diktiert:
- fix: Kennzeichnet eine Fehlerbehebung, die ein Problem in der Codebasis korrigiert. Dies entspricht einem Patch Release (z. B. 1.0.0 -> 1.0.1).
- feat: Bezeichnet die Einführung eines neuen Features, das Funktionalität hinzufügt. Dies entspricht einem Minor Release (z. B. 1.0.1 -> 1.1.0).
- feat! oder fix!: Signalisieren eine nicht abwärtskompatible Änderung (ein „Breaking Change“). Dieser Indikator erfordert einen Major Release (z. B. 1.1.0 -> 2.0.0).
Commits mit anderen Typen wie docs, chore, style, refactor oder test sind für die Wartung der Codebasis unerlässlich, lösen jedoch keine Anpassung der Versionsnummer aus. Diese Unterscheidung ist entscheidend, da sie sicherstellt, dass das für den Benutzer sichtbare Changelog auf wertschöpfende Änderungen, nämlich neue Features und Fehlerbehebungen, konzentriert bleibt. Dieser disziplinierte Ansatz führt zu einer transparenten und vorhersagbaren Git History.
Der Autopilot: Orchestrierung des Release-Prozesses mit semantic-release
Mit einer strukturierten Commit History kann der Release-Prozess mithilfe von Tools wie semantic-release automatisiert werden. Dieses Dienstprogramm fungiert als Orchestrator des Release-Workflows und integriert die Git History mit dem Paketmanager des Projekts und dem Repository-Host.
semantic-release automatisiert den gesamten Package Release Workflow, der die Bestimmung der nächsten Versionsnummer, die Erstellung von Release Notes und die Veröffentlichung des Pakets umfasst.
Das Tool analysiert die Commit History des Projekts, um die nächste semantische Version abzuleiten, und führt anschließend eine konfigurierbare Abfolge von Release-Schritten aus. Obwohl es als Node.js-Paket vertrieben wird, bietet seine plugin-basierte Architektur die Flexibilität, Projekte zu unterstützen, die in allen gängigen Programmiersprache entwickelt wurden. Die folgenden Abschnitte demonstrieren die Anwendung innerhalb eines Spring-Boot-Projekts.
Praktische Implementierung: Eine schrittweise Anleitung
Die Konfiguration lässt sich in drei Hauptschritte unterteilen.
Schritt 1: Vorbereitung des Gradle-Builds (gradle.properties)
Das gradle-semantic-release-plugin benötigt einen festgelegten Ort, um die Version des Projekts zu aktualisieren. Die Datei gradle.properties erfüllt diesen Zweck effektiv. Die Entkopplung der Versionsnummer in eine Properties-Datei ist eine empfohlene Praxis, da sie externen Tools ermöglicht, die Version zu lesen und zu schreiben, ohne komplexe Build-Skripte parsen zu müssen.
gradle.properties
version = 0.0.0Schritt 2: Konfiguration des Release-Workflows (.releaserc.yml)
Diese Konfigurationsdatei definiert die genaue Abfolge der Operationen, die semantic-release ausführen wird.
.releaserc.yml
release:
branches:
- 'main'
preset: 'conventionalcommits'
plugins:
- '@semantic-release/commit-analyzer'
- '@semantic-release/release-notes-generator'
- - '@semantic-release/changelog'
- changelogFile: 'CHANGELOG.md'
changelogTitle: '# Changelog'
- - '@semantic-release/github'
- assets:
- path: 'CHANGELOG.md'
label: 'Changelog'
- 'gradle-semantic-release-plugin'
- - '@semantic-release/git'
- assets:
- 'CHANGELOG.md'
- 'gradle.properties'Die Anweisungen in dieser Datei sind wie folgt zu verstehen:
- branches: Beschränkt die Ausführung des Release-Prozesses auf Commits im main-Branch.
- preset: Ermöglicht das Einbinden von vordefinierten Konfigurationen. Hier wird eine auf die Conventional-Commits-Konvention abgestimmte Konfiguration genutzt.
- plugins: Definiert die geordnete Pipeline von Aktionen:
- commit-analyzer: Analysiert Git-Commits seit dem letzten Release-Tag, um den erforderlichen Release-Typ (Major, Minor oder Patch) zu bestimmen.
- release-notes-generator: Erstellt strukturierte Release Notes aus den relevanten Commit-Nachrichten.
- changelog: Fügt die generierten Notes an eine CHANGELOG.md-Datei an und pflegt so eine beständige Aufzeichnung der Änderungen.
- github: Erstellt einen offiziellen, getaggten Release auf der GitHub-Plattform und fügt angegebene Assets, wie das Changelog, hinzu.
- gradle-semantic-release-plugin: Führt sprachspezifische Aufgaben aus, in diesem Fall die Aktualisierung der Version in gradle.properties und die Ausführung des publish-Tasks.
- git: Committet die geänderten Dateien (CHANGELOG.md, gradle.properties) zurück in das Repository, um dessen Zustand mit dem neuen Release zu synchronisieren.
Schritt 3: CI/CD-Integration (GitHub Actions)
Schließlich ist eine CI-Pipeline erforderlich, um den Release-Workflow bei einem Push in den main-Branch auszulösen. Der folgende GitHub-Actions-Workflow realisiert dies.
.github/workflows/release.yml
name: Release
on:
push:
branches:
- main
permissions:
contents: read
jobs:
release:
name: Release
runs-on: ubuntu-latest
permissions:
contents: write
issues: write
pull-requests: write
id-token: write
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Node einrichten
uses: actions/setup-node@v4
with:
node-version: 'lts/*'
- name: Install dependencies
run: |
npm install -g \
semantic-release \
@semantic-release/git \
@semantic-release/changelog \
conventional-changelog-conventionalcommits \
gradle-semantic-release-plugin
- name: Release durchführen
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: npx semantic-releaseDieser Workflow installiert semantic-release und seine Plugins und führt dann den Release-Prozess aus. Der Parameter fetch-depth: 0 ist von entscheidender Bedeutung, da er sicherstellt, dass die gesamte Git History zur Analyse verfügbar ist. Der permissions-Block gewährt dem Job ausreichende Berechtigungen, um Releases zu erstellen und Dateien zurück in das Repository zu committen.
Fazit: Die strategischen Vorteile der Release-Automatisierung
Die Implementierung dieser automatisierten Release-Pipeline führt zu erheblichen strategischen Vorteilen. Sie eliminiert manuellen Aufwand und das Potenzial für menschliche Fehler im Versionierungs- und Release-Prozess. Die Praxis, Versionsnummern zu schätzen und Changelogs manuell zusammenzustellen, wird durch ein deterministisches, automatisiertes System ersetzt.
Diese Transformation bewirkt mehr als nur eine Zeitersparnis; sie verbessert den Softwareentwicklungszyklus grundlegend. Sie ermöglicht eine höhere Deployment-Frequenz mit größerem Vertrauen, was eine schnellere Bereitstellung von Features und Fehlerbehebungen erlaubt. Die mit Release-Ereignissen verbundene Anspannung wird durch die Effizienz von Continuous Delivery ersetzt. Die Hauptverantwortung des Entwicklungsteams reduziert sich auf die Aufrechterhaltung einer hohen Standard an Commit-Hygiene; der Release-Mechanismus übernimmt die übrigen Aufgaben.

Daniel Schock
Senior Software Engineer
Daniel ist ein erfahrener Fullstack-Entwickler und DevOps-Spezialist mit einem klaren Schwerpunkt auf der Backend-Entwicklung mit Java und Kotlin. Seine Expertise wird durch praktische Erfahrung in der Frontend-Entwicklung mit Vue.js abgerundet. Er verfügt über umfassende Kenntnisse in der Konzeption von CI/CD-Pipelines sowie im Einsatz von Cloud-Technologien wie Kubernetes und AWS, die er erfolgreich in den Branchen Versicherung, Logistik und E-Commerce einsetzte. Daniel arbeitet bevorzugt in agilen Umgebungen und zeichnet sich durch seine analytische Denkweise und hohe Problemlösungskompetenz aus.
Weitere Artikel
Event-Rückblick: Java-Startzeiten optimieren
Vortrag im Office mit Karsten Silz Wie holen wir das Beste aus unseren Java-Anwendungen heraus?…
Wieso ich Retros nicht mehr mag
Und was ich daraus gelernt habe... Retrospektiven gelten als Herzstück agiler Teams – doch was,…
Conventional Commits und Semantic Versioning
Implementierung eines automatisierten Release-Workflows mit Conventional Commits und Semantic Versioning Manuelle Software-Releases stellen eine häufige…

Veränderung, die wirklich trägt: integrale Perspektive
Warum agile Transformationen oft scheitern… …und wie wir sie mit der integralen Perspektive zum Leben…
Ein (halber) Tag im Leben eines Vibecoders
Vier Stunden Vibe-Coding mit Lovable – ein Erfahrungsbericht zwischen Wow-Effekt, Warnsignalen
Erfahrungsbericht Workation
Sonne, Meer und stabile Verbindung – wie fühlt sich Arbeiten von unterwegs wirklich an? In…
Barrierefreiheit als Erfolgsfaktor – Wie Unternehmen langfristig profitieren
Das erwartet Sie in diesem Artikel Dieser Beitrag ist der dritte und letzte Teil unserer…
So wird eine Website barrierefrei – Die wichtigsten Maßnahmen
Das erwartet Sie in diesem Artikel Dieser Beitrag ist der zweite Teil unserer Serie zum…
Warum Barrierefreiheit im Web für Unternehmen immer wichtiger wird
Das erwartet Sie in diesem Artikel Dieser Beitrag ist der Auftakt unserer Serie zum Thema…
Software Architecture Gathering 2024
Das Software Architecture Gathering 2024 des iSAQB [1] fand vom 11. bis 14. November in Berlin im…

