Files
releaser/README.md
T
k3nny 88ed87b095
ci / vet, staticcheck, test, build (push) Successful in 3m5s
ci / vet, staticcheck, test, build (pull_request) Failing after 12s
build(ci): release v1.6.2 — staticcheck in task ci, SA4006 fix
Add go tool staticcheck ./... to the task ci pipeline (between vet and
test), consistent with the Gitea CI workflow. Fix the SA4006 it surfaced
in TestLatestTagTagsIterFails where err from PlainOpen was assigned but
never read before being overwritten.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-11 21:47:39 +02:00

162 lines
6.4 KiB
Markdown

# releaser
![release](https://img.shields.io/badge/release-v1.6.2-blue.svg)
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.
`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.
## How it works
```
release/1.2 branch
└─ last tag: 1.2.3 (or none → start at 1.2.0)
└─ commits since tag → Conventional Commits analysis
└─ next version: 1.2.4
```
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)
5. **Release** — updates `pom.xml` / `package.json` / `build.gradle`, commits, tags, creates GitLab or GitHub release
## Version bump rules
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 |
## Usage
```bash
# Scaffold a default .releaser.yml in the current repository
releaser --init
# Simulate next version (no side effects)
releaser --dry-run
# Full release: update pom.xml + CHANGELOG.md, commit, tag, push, create release
releaser
# Commit and tag locally — skip push and release creation
releaser --no-push
# Push commit and tag but skip creating the release
releaser --no-release
# Update files but stop before committing (review first)
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
# Write changelog to a custom file
releaser --changelog-file CHANGES.md
# Show configuration sources, commit list, and version decision
releaser --verbose --dry-run
# 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+)$"
# Write dotenv artifact to a custom path (or "" to disable)
releaser --release-env-file deploy/version.env
```
## Configuration
`releaser` reads `.releaser.yml` from the repository root. All fields are optional — missing values fall back to the defaults shown below.
```yaml
git:
tag_prefix: "" # default: no prefix; set to "v" for v-prefixed tags
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
releasable_types: # default: all three
- fix
- feat
- breaking
bump_rules: # which version component each type bumps
breaking: "patch" # "minor" to bump minor on breaking changes
feat: "patch"
fix: "patch"
maven:
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"
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"
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
github:
token: "" # env GITHUB_TOKEN (never commit this)
repo: "" # "owner/repo" format
```
### Environment variables
| 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 |
When both `github.*` and `gitlab.*` are configured, GitHub takes precedence.
## 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
artifacts:
reports:
dotenv: release.env # exposes NEXT_VERSION to downstream jobs
```