go-git's HTTPS transport does not use the system credential store, so pushes to remotes that require credentials fail silently or with "authentication required" when no token is provided. When token is empty, delegate to the system git binary so that credential helpers, SSH agents, and netrc all work as expected. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
releaser
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 tag+release creation.
How it works
release/1.2 branch
└─ last tag: v1.2.3 (or none → start at v1.2.0)
└─ commits since tag → Conventional Commits analysis
└─ next version: v1.2.4
- Branch parsing — extracts
major.minorfrom branch name (e.g.release/1.2→1.2) - Tag discovery — finds the latest tag matching
major.minor.*on the current branch - Commit analysis — parses Conventional Commits between last tag and HEAD
- Version bump — increments patch (the minor is owned by the branch)
- Release — updates
pom.xml, commits, tags, creates GitLab release
Version bump rules
| Commit type | Bump | Notes |
|---|---|---|
fix: |
patch | |
feat: |
patch | minor is pinned to branch |
feat!: / BREAKING CHANGE |
patch | same — branch defines the minor boundary |
chore:, docs:, etc. |
none | |
| unparseable msg | none | non-strict mode: silently ignored |
Usage
# Simulate next version (no side effects)
releaser --dry-run
# Full release: bump pom.xml, commit, tag, push, GitLab release
releaser
# Commit and tag locally — skip push and GitLab release
releaser --no-push
# Update pom.xml 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
# 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+)$"
Configuration
releaser reads .releaser.yml from the repository root. All fields are optional — missing values fall back to the defaults shown below.
git:
tag_prefix: "v" # set to "" for tags without prefix
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
maven:
pom_path: "pom.xml" # relative to repo root
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
Environment variables
GitLab-related fields are automatically read from the CI environment if not set in the config file:
| Variable | Used for |
|---|---|
GITLAB_TOKEN |
API auth + HTTPS push auth |
CI_SERVER_URL |
GitLab instance URL |
CI_PROJECT_ID |
Project identifier (numeric) |
CI_PROJECT_PATH |
Project identifier (fallback) |
CI integration (GitLab CI example)
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