Configuration
Dieser Inhalt ist noch nicht in deiner Sprache verfügbar.
All semrel behavior is controlled by a single config file in the root of your repository. You can specify a different path with --config.
Supported formats
Section titled “Supported formats”semrel auto-discovers the config file in this order:
| File | Format |
|---|---|
.semrel.yaml / .semrel.yml | YAML |
.semrel.toml | TOML |
.semrel.json | JSON |
YAML uses camelCase for some keys (e.g. tagPrefix). TOML and JSON always use snake_case (e.g. tag_prefix).
Full example
Section titled “Full example”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: github-actions phase: condition
- uses: 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: 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
Section titled “tagPrefix / tag_prefix”The prefix prepended to the version number when creating git tags.
tagPrefix: v # creates tags like v1.2.3 (default)tagPrefix: "" # creates tags like 1.2.3tag_prefix = "v" # creates tags like v1.2.3 (default)tag_prefix = "" # creates tags like 1.2.3{ "tag_prefix": "v" }| Value | Default | Description |
|---|---|---|
| any string | v | Prepended to every tag semrel creates |
branches
Section titled “branches”A list of branches from which releases can be made. Commits on unlisted branches are ignored.
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 fields
Section titled “Branch fields”| Field | Type | Default | Description |
|---|---|---|---|
name | string | — | Branch name or glob pattern (e.g. main, "*.x", release/*) |
prerelease | string | — | Pre-release identifier appended to the version (e.g. beta → 1.0.0-beta.1) |
maintenance | bool | false | Restricts this branch to patch-only bumps. Also auto-detected from N.x / N.M.x patterns |
Maps conventional commit types to semver bump levels. If omitted, semrel uses the built-in defaults.
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" } ]}Rule fields
Section titled “Rule fields”| Field | Type | Required | Description |
|---|---|---|---|
type | string | yes | Conventional commit type (e.g. feat, fix, perf) |
bump | string | yes | One of major, minor, patch |
Default rules
Section titled “Default rules”When rules: is absent, semrel uses:
| Type | Bump |
|---|---|
feat | minor |
fix | patch |
perf | patch |
revert | patch |
Commit types not listed in rules produce no release.
commit_changelog
Section titled “commit_changelog”Controls whether semrel commits CHANGELOG.md back to the repository before creating the release tag.
commit_changelog: true # defaultcommit_changelog = true{ "commit_changelog": true }| Value | Behaviour |
|---|---|
true (default) | semrel writes CHANGELOG.md, commits it as chore(changelog): update for vX.Y.Z [skip ci], then creates the tag on that commit |
false | semrel writes CHANGELOG.md locally but does not commit it (useful if you manage the changelog externally) |
tag_exists_strategy
Section titled “tag_exists_strategy”Controls what semrel does when the computed next version tag already exists locally.
tag_exists_strategy: update-changelog # defaulttag_exists_strategy = "update-changelog"{ "tag_exists_strategy": "update-changelog" }| Strategy | Behaviour |
|---|---|
update-changelog (default) | Updates and commits CHANGELOG.md for the existing version, then exits without error. Idempotent — useful for repair runs. |
skip | Exits silently without any changes. |
error | Exits with a non-zero code. Use this if you want strict one-shot pipelines. |
Example scenario: you manually created v0.1.0 to bootstrap the project. The next pipeline run detects the tag exists and, with the default strategy, regenerates and commits the changelog for that version — no duplicate release is created.
version_ceiling
Section titled “version_ceiling”Prevents semrel from releasing at or above this version. Useful for keeping a project below 1.0.0 until you deliberately promote it to stable.
version_ceiling: "1.0.0"ceiling_strategy: clampversion_ceiling = "1.0.0"ceiling_strategy = "clamp"{ "version_ceiling": "1.0.0", "ceiling_strategy": "clamp"}| Value | Effect |
|---|---|
| Not set | No ceiling — semrel bumps freely |
"1.0.0" | Releases are never >= 1.0.0 |
ceiling_strategy
Section titled “ceiling_strategy”Controls what happens when the calculated next version would reach or exceed version_ceiling.
| Strategy | Behaviour |
|---|---|
clamp | Downgrades the bump (major → minor → patch) until the version stays below the ceiling. Logs a warning. |
skip | Does nothing — prints a notice and exits without releasing. |
error | Exits with a non-zero code so the pipeline fails explicitly. |
Example: current 0.9.5, breaking change commit, ceiling 1.0.0
clamp→ releases0.9.6(downgraded to patch)skip→ no release, exit 0error→ no release, exit 1
To promote past the ceiling, remove or raise version_ceiling in your config file and commit.
plugins
Section titled “plugins”An ordered list of plugins to load for the release pipeline.
| Field | Type | Required | Description |
|---|---|---|---|
uses | string | yes* | Plugin type or install name. semrel resolves to semrel-plugin-<uses> |
name | string | no | Optional instance identifier (useful when the same plugin appears multiple times) |
path | string | no | Explicit path to a plugin binary (overrides uses resolution) |
args | map | no | Arbitrary key-value pairs passed to the plugin as SEMREL_PLUGIN_* environment variables |
phase | string | no | When to run: condition, pre-tag, or release (default) |
*Either uses or path must be set.
Plugin phases
Section titled “Plugin phases”| Phase | When it runs | Typical use |
|---|---|---|
condition | After config load, before any commit analysis or tag creation | github-actions, gitlab-ci — abort if environment is wrong |
pre-tag | After version calculation and changelog write, before the git tag is created | gobinary — update version file and commit so the tagged source contains the real version |
release | After the tag is created (default) | github, hook-slack, updater-npm — publish and notify |
plugins: # Gate: abort if not running in GitHub Actions - uses: 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: github phase: release # default, can be omitted args: token: ${{ env.GITHUB_TOKEN }} owner: MyOrg repo: my-repo
# Hook: notify Slack after release - uses: 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 resolution
Section titled “Plugin resolution”If path: is omitted, semrel resolves plugins in this order:
~/.semrel/plugins/semrel-plugin-<uses>semrel-plugin-<uses>from$PATH
Use path: when you want to pin a specific local binary instead of the default discovery flow.
Plugin arguments as environment variables
Section titled “Plugin arguments as environment variables”Every key in args: is exposed to the plugin process as an environment variable prefixed with SEMREL_PLUGIN_.
plugins: - uses: 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" } }]}The plugin receives:
| Config key | Environment variable |
|---|---|
token | SEMREL_PLUGIN_TOKEN |
owner | SEMREL_PLUGIN_OWNER |
repo | SEMREL_PLUGIN_REPO |
Plugins also receive release context through standard environment variables:
| Variable | Description |
|---|---|
SEMREL_CURRENT_VERSION | The version before this release |
SEMREL_NEXT_VERSION | The new version being released |
SEMREL_TAG_NAME | The full tag name including prefix (e.g. v1.2.3) |
SEMREL_CHANGELOG | Path to the written CHANGELOG.md file |
SEMREL_DRY_RUN | true if semrel was invoked with --dry-run |
semrel plugins are plain executables launched as subprocesses. They do not use gRPC.
Editor validation with JSON Schema
Section titled “Editor validation with JSON Schema”The semrel registry serves JSON Schema documents for .semrel.yaml and every plugin. Adding a $schema comment enables inline validation and autocompletion in VS Code, JetBrains IDEs, Neovim (with LSP), and any other editor that supports yaml-language-server.
Core config schema
Section titled “Core config schema”Add the $schema comment as the first line of your .semrel.yaml:
# yaml-language-server: $schema=https://registry.semrel.io/schemas/core/v1.jsonschemaVersion: 1tagPrefix: "v"
plugins: - uses: analyzer-conventional - uses: generator-changelog-md - uses: provider-githubYour editor will now flag unknown keys, warn about missing required fields, and offer autocomplete for all known options.
Plugin config schemas
Section titled “Plugin config schemas”Each plugin’s args: block can be validated independently. Place the schema comment directly above the args: key:
# yaml-language-server: $schema=https://registry.semrel.io/schemas/core/v1.jsonplugins: - uses: 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
Section titled “Schema URLs”| Resource | URL |
|---|---|
| Core config | https://registry.semrel.io/schemas/core/v1.json |
| Plugin (by name) | https://registry.semrel.io/schemas/plugins/{name}/v1.json |
| Plugin (latest) | https://registry.semrel.io/schemas/plugins/{name}/latest.json |
| Namespaced plugin | https://registry.semrel.io/schemas/plugins/@semrel/{name}/v1.json |
latest.json always redirects (HTTP 301) to the newest stable schema version.
Self-hosted registry
Section titled “Self-hosted registry”If you run a private semrel-registry instance, replace registry.semrel.io with your own base URL:
# yaml-language-server: $schema=https://my-registry.example.com/schemas/core/v1.jsonValidating from the CLI
Section titled “Validating from the CLI”You can also validate your config against the published schema using semrel config validate:
semrel config validate# ✓ Config is valid (schema version 1)See semrel config for the full command reference.