2026-07-07 00:07:53 +02:00
# releaser
2026-07-11 21:47:39 +02:00

2026-07-07 00:07:53 +02:00
A CI-friendly release automation tool for GitFlow workflows using Conventional Commits.
## Problem
Standard tools like `semantic-release` are designed for trunk-based development. In a GitFlow setup with versioned release branches (`release/1.1` , `release/1.2` ), they either fail to respect the branch's version range or require brittle configuration.
2026-07-11 00:15:09 +02:00
`releaser` is built for this exact workflow: it reads the branch name to pin the `major.minor` , parses Conventional Commits to determine the patch increment, and handles everything from `pom.xml` update to GitLab/GitHub tag+release creation.
2026-07-07 00:07:53 +02:00
## How it works
```
release/1.2 branch
2026-07-11 00:15:09 +02:00
└─ last tag: 1.2.3 (or none → start at 1.2.0)
2026-07-07 00:07:53 +02:00
└─ commits since tag → Conventional Commits analysis
2026-07-11 00:15:09 +02:00
└─ next version: 1.2.4
2026-07-07 00:07:53 +02:00
```
1. **Branch parsing** — extracts `major.minor` from branch name (e.g. `release/1.2` → `1.2` )
2. **Tag discovery** — finds the latest tag matching `major.minor.*` on the current branch
3. **Commit analysis** — parses Conventional Commits between last tag and HEAD
4. **Version bump** — increments patch (the minor is owned by the branch)
2026-07-11 17:59:13 +02:00
5. **Release** — updates `pom.xml` / `package.json` / `build.gradle` , commits, tags, creates GitLab or GitHub release
2026-07-07 00:07:53 +02:00
## Version bump rules
2026-07-11 16:59:28 +02:00
By default, all releasable commits bump the **patch** component (minor is pinned to the branch). You can override this per commit type via `git.bump_rules` in `.releaser.yml` :
| Commit type | Default | Configurable via `bump_rules` |
|------------------|---------|------------------------------------------------|
| `fix:` | patch | `fix: "minor"` to bump minor instead |
| `feat:` | patch | `feat: "minor"` to bump minor instead |
| `feat!:` / `BREAKING CHANGE` | patch | `breaking: "minor"` to bump minor |
| `chore:` , `docs:` , etc. | none | — |
| unparseable msg | none | non-strict mode: silently ignored |
2026-07-07 00:07:53 +02:00
## Usage
```bash
2026-07-07 11:18:27 +02:00
# Scaffold a default .releaser.yml in the current repository
releaser --init
2026-07-07 00:07:53 +02:00
# Simulate next version (no side effects)
releaser --dry-run
2026-07-11 00:15:09 +02:00
# Full release: update pom.xml + CHANGELOG.md, commit, tag, push, create release
2026-07-07 00:07:53 +02:00
releaser
2026-07-11 00:15:09 +02:00
# Commit and tag locally — skip push and release creation
2026-07-07 00:07:53 +02:00
releaser --no-push
2026-07-11 00:15:09 +02:00
# Push commit and tag but skip creating the release
2026-07-07 11:18:27 +02:00
releaser --no-release
# Update files but stop before committing (review first)
2026-07-07 00:07:53 +02:00
releaser --no-commit
# … then commit manually and re-run:
releaser --tag-only
# Explicitly target a branch (useful in detached HEAD CI)
releaser --branch release/1.2
2026-07-07 11:18:27 +02:00
# Write changelog to a custom file
releaser --changelog-file CHANGES.md
2026-07-07 11:35:22 +02:00
# Show configuration sources, commit list, and version decision
releaser --verbose --dry-run
2026-07-07 00:07:53 +02:00
# Target a specific pom.xml
releaser --pom path/to/pom.xml
# Override tag prefix from CLI (empty = no prefix)
releaser --tag-prefix ""
# Override branch pattern (e.g. also match hotfix/ branches)
releaser --branch-pattern "^(?:.*/)?(?:release|hotfix)/(\d+)\.(\d+) $"
2026-07-11 00:15:09 +02:00
# Write dotenv artifact to a custom path (or "" to disable)
releaser --release-env-file deploy/version.env
2026-07-07 00:07:53 +02:00
```
## Configuration
`releaser` reads `.releaser.yml` from the repository root. All fields are optional — missing values fall back to the defaults shown below.
```yaml
git :
2026-07-07 11:58:29 +02:00
tag_prefix : "" # default: no prefix; set to "v" for v-prefixed tags
2026-07-07 00:07:53 +02:00
branch_pattern : "^(?:.*/)?release/(\\d+)\\.(\\d+)$" # two capture groups: major, minor
commit_message : "chore(release): {version} [skip ci]"
author_name : "" # defaults to git config user.name
author_email : "" # defaults to git config user.email
2026-07-11 00:15:09 +02:00
releasable_types : # default: all three
- fix
- feat
- breaking
2026-07-11 16:59:28 +02:00
bump_rules : # which version component each type bumps
breaking : "patch" # "minor" to bump minor on breaking changes
feat : "patch"
fix : "patch"
2026-07-07 00:07:53 +02:00
maven :
2026-07-11 16:59:28 +02:00
pom_path : "pom.xml" # single pom.xml, relative to repo root
# pom_paths: # multi-module: list overrides pom_path
# - "pom.xml"
# - "module-a/pom.xml"
# - "module-b/pom.xml"
node : # opt-in — no default; omit to skip
# package_json: "package.json" # single path
# package_jsons: # monorepo: list overrides package_json
# - "packages/frontend/package.json"
# - "packages/backend/package.json"
2026-07-07 00:07:53 +02:00
2026-07-11 17:59:13 +02:00
gradle : # opt-in — no default; omit to skip
# build_file: "build.gradle" # Groovy or Kotlin DSL; single path
# build_files: # multi-module: list overrides build_file
# - "build.gradle"
# - "module-a/build.gradle"
2026-07-07 00:07:53 +02:00
gitlab :
url : "https://gitlab.example.com" # or env CI_SERVER_URL
token : "" # env GITLAB_TOKEN (never commit this)
project : "" # env CI_PROJECT_ID or CI_PROJECT_PATH
2026-07-11 00:15:09 +02:00
github :
token : "" # env GITHUB_TOKEN (never commit this)
repo : "" # "owner/repo" format
2026-07-07 00:07:53 +02:00
```
### Environment variables
2026-07-11 00:15:09 +02:00
| Variable | Used for |
|--------------------|-----------------------------------|
| `GITLAB_TOKEN` | GitLab API auth + HTTPS push auth |
| `CI_SERVER_URL` | GitLab instance URL |
| `CI_PROJECT_ID` | GitLab project identifier (numeric) |
| `CI_PROJECT_PATH` | GitLab project identifier (fallback) |
| `GITHUB_TOKEN` | GitHub API auth |
2026-07-07 00:07:53 +02:00
2026-07-11 00:15:09 +02:00
When both `github.*` and `gitlab.*` are configured, GitHub takes precedence.
2026-07-07 00:07:53 +02:00
## CI integration (GitLab CI example)
```yaml
release :
stage : release
image : registry.example.com/releaser:latest
rules :
- if : $CI_COMMIT_BRANCH =~ /^release\/.+$/
variables :
GITLAB_TOKEN : $RELEASE_TOKEN # project/group CI variable with api + write_repository scope
script :
- releaser
2026-07-11 00:15:09 +02:00
artifacts :
reports :
dotenv : release.env # exposes NEXT_VERSION to downstream jobs
2026-07-07 00:07:53 +02:00
```