Konfiguration
Das gesamte Verhalten von semrel wird über eine einzige Konfigurationsdatei im Wurzelverzeichnis deines Repositorys gesteuert. Mit --config kannst du einen anderen Pfad angeben.
Unterstützte Formate
Abschnitt betitelt „Unterstützte Formate“semrel findet die Konfigurationsdatei automatisch in dieser Reihenfolge:
| Datei | Format |
|---|---|
.semrel.yaml / .semrel.yml | YAML |
.semrel.toml | TOML |
.semrel.json | JSON |
YAML verwendet für einige Schlüssel camelCase (z. B. tagPrefix). TOML und JSON verwenden immer snake_case (z. B. tag_prefix).
Konfigurationsinterpolation
Abschnitt betitelt „Konfigurationsinterpolation“Konfigurationswerte können Go-Templates mit Sprouts eingeschränkter env-Funktion verwenden:
tagPrefix: '{{ env "RELEASE_TAG_PREFIX" }}'Es ist ausschließlich der Zugriff auf Umgebungsvariablen verfügbar. Shell-, Dateisystem-, Netzwerk- und andere Funktionen mit Seiteneffekten werden nicht registriert. Die ältere Syntax ${env.VAR_NAME} wird weiterhin unterstützt:
token: '${env.GITHUB_TOKEN}'Beide Formen werden beim Laden der Konfiguration durch semrel ausgewertet, nicht durch GitHub Actions. Eine nicht definierte Umgebungsvariable führt zu einem Fehler beim Laden der Konfiguration.
Vollständiges Beispiel
Abschnitt betitelt „Vollständiges Beispiel“tagPrefix: v
branches: - name: main - name: "*.x" maintenance: true - name: next prerelease: beta
rules: - type: feat bump: minor - type: fix bump: patch - type: perf bump: patch - type: revert bump: patch
commit_changelog: truetag_exists_strategy: update-changelog
version_ceiling: "1.0.0"ceiling_strategy: clamp
plugins: - uses: @semrel/condition-github-actions phase: condition
- uses: @semrel/provider-github phase: release args: token: '${env.GITHUB_TOKEN}' owner: MyOrg repo: my-repo
- uses: gobinary phase: pre-tag args: file: internal/version/version.go var_name: Version
- uses: @semrel/hook-slack args: webhook_url: '${env.SLACK_WEBHOOK}'tag_prefix = "v"commit_changelog = truetag_exists_strategy = "update-changelog"version_ceiling = "1.0.0"ceiling_strategy = "clamp"
[[branches]]name = "main"
[[branches]]name = "*.x"maintenance = true
[[branches]]name = "next"prerelease = "beta"
[[rules]]type = "feat"bump = "minor"
[[rules]]type = "fix"bump = "patch"
[[rules]]type = "perf"bump = "patch"
[[rules]]type = "revert"bump = "patch"
[[plugins]]uses = "github-actions"phase = "condition"
[[plugins]]uses = "github"phase = "release"[plugins.args]token = "${GITHUB_TOKEN}"owner = "MyOrg"repo = "my-repo"
[[plugins]]uses = "gobinary"phase = "pre-tag"[plugins.args]file = "internal/version/version.go"var_name = "Version"
[[plugins]]uses = "slack"[plugins.args]webhook_url = "${SLACK_WEBHOOK}"{ "tag_prefix": "v", "commit_changelog": true, "tag_exists_strategy": "update-changelog", "version_ceiling": "1.0.0", "ceiling_strategy": "clamp", "branches": [ { "name": "main" }, { "name": "*.x", "maintenance": true }, { "name": "next", "prerelease": "beta" } ], "rules": [ { "type": "feat", "bump": "minor" }, { "type": "fix", "bump": "patch" }, { "type": "perf", "bump": "patch" }, { "type": "revert", "bump": "patch" } ], "plugins": [ { "uses": "github-actions", "phase": "condition" }, { "uses": "github", "phase": "release", "args": { "token": "${GITHUB_TOKEN}", "owner": "MyOrg", "repo": "my-repo" } }, { "uses": "gobinary", "phase": "pre-tag", "args": { "file": "internal/version/version.go", "var_name": "Version" } }, { "uses": "slack", "args": { "webhook_url": "${SLACK_WEBHOOK}" } } ]}tagPrefix / tag_prefix
Abschnitt betitelt „tagPrefix / tag_prefix“Das Präfix wird beim Erstellen von git-Tags vor die Versionsnummer gesetzt.
tagPrefix: v # erzeugt Tags wie v1.2.3tagPrefix: "" # erzeugt ausdrücklich Tags wie 1.2.3tag_prefix = "v" # erzeugt Tags wie v1.2.3tag_prefix = "" # erzeugt ausdrücklich Tags wie 1.2.3{ "tag_prefix": "v" }| Wert | Standard | Beschreibung |
|---|---|---|
nicht angegeben (null) | v | Verwendet v, wenn kein Präfix konfiguriert ist |
beliebiger String einschließlich "" | — | Verwendet den konfigurierten Wert; "" deaktiviert das Präfix ausdrücklich |
branches
Abschnitt betitelt „branches“Eine Liste von Branches, aus denen Releases erstellt werden dürfen. Commits auf nicht aufgeführten Branches werden ignoriert.
branches: - name: main - name: "*.x" maintenance: true - name: next prerelease: beta[[branches]]name = "main"
[[branches]]name = "*.x"maintenance = true
[[branches]]name = "next"prerelease = "beta"{ "branches": [ { "name": "main" }, { "name": "*.x", "maintenance": true }, { "name": "next", "prerelease": "beta" } ]}Branch-Felder
Abschnitt betitelt „Branch-Felder“| Feld | Typ | Standard | Beschreibung |
|---|---|---|---|
name | string | — | Branch-Name oder Glob-Muster (z. B. main, "*.x", release/*) |
prerelease | string | — | Pre-Release-Bezeichner, der an die Version angehängt wird (z. B. beta → 1.0.0-beta.1) |
maintenance | bool | false | Beschränkt diesen Branch auf reine Patch-Bumps. Wird auch automatisch aus Mustern wie N.x / N.M.x erkannt |
Ordnet Conventional-Commit-Typen (und optional Scopes) SemVer-Bump-Stufen zu. Wenn du rules: weglässt, verwendet semrel die eingebauten Standardwerte.
rules: - type: feat bump: minor - type: fix bump: patch - type: perf bump: patch - type: revert bump: patch[[rules]]type = "feat"bump = "minor"
[[rules]]type = "fix"bump = "patch"
[[rules]]type = "perf"bump = "patch"
[[rules]]type = "revert"bump = "patch"{ "rules": [ { "type": "feat", "bump": "minor" }, { "type": "fix", "bump": "patch" }, { "type": "perf", "bump": "patch" }, { "type": "revert", "bump": "patch" } ]}Regel-Felder
Abschnitt betitelt „Regel-Felder“| Feld | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
type | string | ja | Conventional-Commit-Typ (z. B. feat, fix, deps) |
scope | string | false | nein | Scope-Filter. Ein String matcht nur Commits mit exakt diesem Scope. false matcht nur Commits ohne Scope. Weglassen matcht jeden Scope. |
bump | string | ja | Einer von major, minor, patch |
hidden | boolean | nein | Hält passende Commits aus generierten Changelogs heraus, wendet ihren Version-Bump aber weiterhin an. |
Scope-basierte Regeln
Abschnitt betitelt „Scope-basierte Regeln“Das optionale Feld scope ermöglicht es, Commits anhand ihres Scopes einem bestimmten Bump-Level zuzuordnen. Das ist nützlich, wenn Tools wie Renovate oder eigene Workflows den gewünschten Bump im Scope kodieren.
Beispiel: deps(major): …, deps(minor): … und deps(patch): … als unterschiedliche Release-Level behandeln:
rules: - type: deps scope: major bump: major - type: deps scope: minor bump: minor - type: deps scope: patch bump: patch - type: feat bump: minor - type: fix bump: patch[[rules]]type = "deps"scope = "major"bump = "major"
[[rules]]type = "deps"scope = "minor"bump = "minor"
[[rules]]type = "deps"scope = "patch"bump = "patch"
[[rules]]type = "feat"bump = "minor"
[[rules]]type = "fix"bump = "patch"{ "rules": [ { "type": "deps", "scope": "major", "bump": "major" }, { "type": "deps", "scope": "minor", "bump": "minor" }, { "type": "deps", "scope": "patch", "bump": "patch" }, { "type": "feat", "bump": "minor" }, { "type": "fix", "bump": "patch" } ]}Matching-Verhalten:
- Eine Regel mit String-Scope greift nur bei Commits, bei denen Typ und Scope exakt übereinstimmen.
- Eine Regel mit
scope: falsegreift nur bei Commits dieses Typs, die keinen Scope tragen. - Eine Regel ohne
scopegreift bei Commits dieses Typs unabhängig von deren Scope. - Der höchste Bump-Level aller passenden Regeln gewinnt.
(type, scope)-Kombinationen müssen eindeutig sein — zwei Regeln für die gleiche Kombination sind ein Konfigurationsfehler.
Standardregeln
Abschnitt betitelt „Standardregeln“Wenn rules: fehlt, verwendet semrel:
| Typ | Bump |
|---|---|
feat | minor |
fix | patch |
perf | patch |
revert | patch |
Commit-Typen, die nicht in rules aufgeführt sind, erzeugen kein Release.
commit_changelog
Abschnitt betitelt „commit_changelog“Steuert, ob semrel CHANGELOG.md mit dem eingebauten Generator schreibt. Alle getrackten Änderungen des eingebauten Generators und der pre-tag-Plugins werden unmittelbar vor dem Release-Tag einmal gemeinsam committet.
commit_changelog: true # defaultcommit_changelog = true{ "commit_changelog": true }| Wert | Verhalten |
|---|---|
true (Standard) | semrel schreibt CHANGELOG.md und nimmt sie in den einmaligen Release-Commit auf |
false | semrel überspringt das eingebaute Schreiben; ein pre-tag-Changelog-Plugin kann die Datei übernehmen, deren Änderungen im selben Release-Commit landen |
tag_exists_strategy
Abschnitt betitelt „tag_exists_strategy“Steuert, was semrel macht, wenn der berechnete Tag der nächsten Version lokal bereits existiert.
tag_exists_strategy: update-changelog # defaulttag_exists_strategy = "update-changelog"{ "tag_exists_strategy": "update-changelog" }| Strategie | Verhalten |
|---|---|
update-changelog (Standard) | Aktualisiert und committet CHANGELOG.md für die vorhandene Version und beendet sich dann ohne Fehler. Idempotent — praktisch für Reparaturläufe. |
skip | Beendet sich stillschweigend ohne Änderungen. |
error | Beendet sich mit einem Exit-Code ungleich null. Verwende das, wenn du strikte One-Shot-Pipelines willst. |
Beispielszenario: Du hast v0.1.0 manuell erstellt, um das Projekt zu bootstrappen. Der nächste Pipeline-Lauf erkennt, dass der Tag bereits existiert, und erzeugt mit der Standardstrategie den Changelog für diese Version neu und committet ihn — es wird kein doppeltes Release erstellt.
version_ceiling
Abschnitt betitelt „version_ceiling“Verhindert, dass semrel auf oder oberhalb dieser Version releast. Praktisch, wenn du ein Projekt unter 1.0.0 halten willst, bis du es bewusst auf stabil hebst.
version_ceiling: "1.0.0"ceiling_strategy: clampversion_ceiling = "1.0.0"ceiling_strategy = "clamp"{ "version_ceiling": "1.0.0", "ceiling_strategy": "clamp"}| Wert | Effekt |
|---|---|
| Nicht gesetzt | Keine Obergrenze — semrel erhöht frei |
"1.0.0" | Releases sind niemals >= 1.0.0 |
ceiling_strategy
Abschnitt betitelt „ceiling_strategy“Steuert, was passiert, wenn die berechnete nächste Version version_ceiling erreichen oder überschreiten würde.
| Strategie | Verhalten |
|---|---|
clamp | Stuft den Bump herunter (major → minor → patch), bis die Version unter der Obergrenze bleibt. Schreibt eine Warnung ins Log. |
skip | Tut nichts — gibt einen Hinweis aus und beendet sich ohne Release. |
error | Beendet sich mit einem Exit-Code ungleich null, sodass die Pipeline explizit fehlschlägt. |
Beispiel: aktuell 0.9.5, Breaking-Change-Commit, Obergrenze 1.0.0
clamp→ releast0.9.6(aufpatchheruntergestuft)skip→ kein Release, Exit 0error→ kein Release, Exit 1
Um die Obergrenze zu überschreiten, entferne version_ceiling aus deiner Konfigurationsdatei oder setze sie höher und committe die Änderung.
plugins
Abschnitt betitelt „plugins“Eine geordnete Liste von Plugins, die für die Release Pipeline geladen werden.
| Feld | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
uses | string | ja* | Plugin-Typ oder Installationsname. semrel löst ihn zu semrel-plugin-<uses> auf |
name | string | nein | Optionaler Instanzbezeichner (praktisch, wenn dasselbe Plugin mehrfach vorkommt) |
path | string | nein | Expliziter Pfad zu einer Plugin-Binärdatei (überschreibt die Auflösung über uses) |
args | map | nein | Beliebige Schlüssel-Wert-Paare, die als SEMREL_PLUGIN_*-Umgebungsvariablen an das Plugin übergeben werden |
phase | string | nein | Wann es ausgeführt wird: condition, pre-tag oder release (Standard) |
*Entweder uses oder path muss gesetzt sein.
Plugin-Phasen
Abschnitt betitelt „Plugin-Phasen“| Phase | Wann sie läuft | Typische Verwendung |
|---|---|---|
condition | Nach dem Laden der Konfiguration, vor jeder Commit-Analyse oder Tag-Erstellung | github-actions, gitlab-ci — abbrechen, wenn die Umgebung nicht passt |
pre-tag | Nach Versionsberechnung und Changelog-Schreiben, bevor der git-Tag erstellt wird | gobinary — Versionsdatei aktualisieren und committen, damit der getaggte Quellcode die echte Version enthält |
release | Nachdem der Tag erstellt wurde (Standard) | github, hook-slack, updater-npm — veröffentlichen und benachrichtigen |
plugins: # Gate: abort if not running in GitHub Actions - uses: @semrel/condition-github-actions phase: condition
# Pre-tag: update Go version variable before tagging - uses: gobinary phase: pre-tag args: file: internal/version/version.go var_name: Version
# Release: create GitHub release with changelog - uses: @semrel/provider-github phase: release # default, can be omitted args: token: '${env.GITHUB_TOKEN}' owner: MyOrg repo: my-repo
# Hook: notify Slack after release - uses: @semrel/hook-slack args: webhook_url: '${env.SLACK_WEBHOOK}'[[plugins]]uses = "github-actions"phase = "condition"
[[plugins]]uses = "gobinary"phase = "pre-tag"[plugins.args]file = "internal/version/version.go"var_name = "Version"
[[plugins]]uses = "github"phase = "release"[plugins.args]token = "${GITHUB_TOKEN}"owner = "MyOrg"repo = "my-repo"
[[plugins]]uses = "slack"[plugins.args]webhook_url = "${SLACK_WEBHOOK}"{ "plugins": [ { "uses": "github-actions", "phase": "condition" }, { "uses": "gobinary", "phase": "pre-tag", "args": { "file": "internal/version/version.go", "var_name": "Version" } }, { "uses": "github", "phase": "release", "args": { "token": "${GITHUB_TOKEN}", "owner": "MyOrg", "repo": "my-repo" } }, { "uses": "slack", "args": { "webhook_url": "${SLACK_WEBHOOK}" } } ]}Plugin-Auflösung
Abschnitt betitelt „Plugin-Auflösung“Wenn path: fehlt, löst semrel Plugins in dieser Reihenfolge auf:
~/.semrel/plugins/semrel-plugin-<uses>semrel-plugin-<uses>aus$PATH
Verwende path:, wenn du eine bestimmte lokale Binärdatei statt des Standard-Discovery-Flows pinnen willst.
Plugin-Argumente als Umgebungsvariablen
Abschnitt betitelt „Plugin-Argumente als Umgebungsvariablen“Jeder Schlüssel in args: wird dem Plugin-Prozess als Umgebungsvariable mit dem Präfix SEMREL_PLUGIN_ bereitgestellt.
plugins: - uses: @semrel/provider-github args: token: '${env.GITHUB_TOKEN}' owner: MyOrg repo: my-repo[[plugins]]uses = "github"[plugins.args]token = "${GITHUB_TOKEN}"owner = "MyOrg"repo = "my-repo"{ "plugins": [{ "uses": "github", "args": { "token": "${GITHUB_TOKEN}", "owner": "MyOrg", "repo": "my-repo" } }]}Das Plugin erhält:
| Konfigurationsschlüssel | Umgebungsvariable |
|---|---|
token | SEMREL_PLUGIN_TOKEN |
owner | SEMREL_PLUGIN_OWNER |
repo | SEMREL_PLUGIN_REPO |
Plugins erhalten den Release-Kontext außerdem über Standard-Umgebungsvariablen:
| Variable | Beschreibung |
|---|---|
SEMREL_CURRENT_VERSION | Die Version vor diesem Release |
SEMREL_NEXT_VERSION | Die neue Version, die releast wird |
SEMREL_TAG_NAME | Der vollständige Tag-Name inklusive Präfix (z. B. v1.2.3) |
SEMREL_CHANGELOG | Generierter Changelog-/Release-Notes-Text |
SEMREL_DRY_RUN | true, wenn semrel mit --dry-run aufgerufen wurde |
SEMREL_COMMITS | JSON-Array der rohen Commit-Messages im aktuellen Release-Fenster |
SEMREL_CONTRIBUTORS | JSON-Array der Contributor-Metadaten für das aktuelle Release-Fenster, nach Commit-Anzahl absteigend sortiert |
semrel-Plugins sind einfache ausführbare Dateien, die als Unterprozesse gestartet werden. Sie verwenden kein gRPC.
Editor-Validierung mit JSON Schema
Abschnitt betitelt „Editor-Validierung mit JSON Schema“Die semrel Registry stellt JSON Schema-Dokumente für .semrel.yaml und jedes Plugin bereit. Wenn du einen $schema-Kommentar hinzufügst, bekommst du Inline-Validierung und Autovervollständigung in VS Code, JetBrains IDEs, Neovim (mit LSP) und jedem anderen Editor, der yaml-language-server unterstützt.
Schema für die Core-Konfiguration
Abschnitt betitelt „Schema für die Core-Konfiguration“Füge den $schema-Kommentar als erste Zeile deiner .semrel.yaml hinzu:
# yaml-language-server: $schema=https://registry.semrel.io/schemas/core/v1.jsonschemaVersion: 1tagPrefix: "v"
plugins: - uses: @semrel/analyzer-conventional - uses: @semrel/generator-changelog-md - uses: @semrel/provider-githubDein Editor markiert jetzt unbekannte Schlüssel, warnt vor fehlenden Pflichtfeldern und bietet Autovervollständigung für alle bekannten Optionen.
Schemas für Plugin-Konfigurationen
Abschnitt betitelt „Schemas für Plugin-Konfigurationen“Jeder args:-Block eines Plugins kann unabhängig validiert werden. Platziere den Schema-Kommentar direkt über dem args:-Schlüssel:
# yaml-language-server: $schema=https://registry.semrel.io/schemas/core/v1.jsonplugins: - uses: @semrel/provider-github # yaml-language-server: $schema=https://registry.semrel.io/schemas/plugins/provider-github/latest.json args: token: '${env.GITHUB_TOKEN}' owner: MyOrg repo: my-repoSchema-URLs
Abschnitt betitelt „Schema-URLs“| Ressource | URL |
|---|---|
| Core-Konfiguration | https://registry.semrel.io/schemas/core/v1.json |
| Plugin (nach Name) | https://registry.semrel.io/schemas/plugins/{name}/v1.json |
| Plugin (neueste Version) | https://registry.semrel.io/schemas/plugins/{name}/latest.json |
| Plugin mit Namespace | https://registry.semrel.io/schemas/plugins/@semrel/{name}/v1.json |
latest.json leitet immer (HTTP 301) auf die neueste stabile Schema-Version weiter.
Selbst gehostete Registry
Abschnitt betitelt „Selbst gehostete Registry“Wenn du eine private semrel-registry-Instanz betreibst, ersetze registry.semrel.io durch deine eigene Basis-URL:
# yaml-language-server: $schema=https://my-registry.example.com/schemas/core/v1.jsonÜber die CLI validieren
Abschnitt betitelt „Über die CLI validieren“Du kannst deine Konfiguration mit semrel config validate auch gegen das veröffentlichte Schema validieren:
semrel config validate# ✓ Config is valid (schema version 1)Die vollständige Befehlsreferenz findest du unter semrel config.