Skip to content

Latest commit

 

History

332 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Go Report Card GitHub release GitHub go.mod Go version License: Apache-2.0

Publish Release gh-pages

relctl

Description: relctl is a provider-agnostic release management CLI for CI/CD pipelines. It supports three versioning schemes – SemVer (branch-prefix driven), SemVer via Conventional Commits (commit-message driven), and CalVer – and integrates with GitHub, GitHub Enterprise, GitLab, and Jenkins.

  • Technology stack: Go, Cobra CLI
  • Status: Stable
  • Supported environments:
    • GitHub & GitHub Enterprise (GitHub Actions)
    • GitLab (GitLab CI)
    • Jenkins Pipelines
  • Versioning schemes: SemVer (branch-prefix driven) · Conventional Commits (commit-message driven SemVer) · CalVer (date-based, git-tag driven)

Getting Started

Download the latest release and add it to your PATH, or use the layer87-labs/relctl-action in GitHub Actions.

Versioning Schemes

SemVer (default)

relctl derives the SemVer bump level from the source branch name:

Branch prefix Bump
bugfix/, fix/, patch/, dependabot/ Patch
feature/, feat/, minor/ Minor
major/ Major

Conventional Commits

relctl derives the SemVer bump level from the commit messages between the last published release (not draft, not prerelease) and the target commit, following the Conventional Commits specification:

Rule Bump
any commit with ! after type/scope (feat!:, fix(api)!:), or a BREAKING CHANGE: / BREAKING-CHANGE: footer in the body Major
otherwise, at least one feat commit Minor
otherwise, at least one commit of a recognised Conventional Commits type (fix, perf, refactor, docs, style, test, chore, ci, build, revert) Patch
no commit matches any of the above No release – relctl release create fails with a clear error

The commit range and messages come exclusively from the local Git history – no SCM API call for the commits themselves, fully provider-agnostic. Finding the last published release still uses the SCM API, the same way the existing --hotfix flag does.

Prerequisite: the repository must be checked out with full history (fetch-depth: 0), same as CalVer.

Squash merges only: relctl walks the first-parent chain from HEAD down to the last published release. With a squash-merge workflow that chain is the sequence of PR title / squash commit messages, one per merge, each carrying its type directly – this is the supported case. If relctl finds a commit with more than one parent (a real merge commit) in that range, it fails with a clear error (ErrMergeCommitInRange) instead of guessing – a merge commit means the first-parent chain no longer represents "one commit per PR", and silently walking past it could understate the bump. Repositories that bring in multi-commit PRs via a merge commit (rather than squashing) are not supported by this scheme.

--version as an explicit override always takes precedence, exactly like for SemVer and CalVer.

CalVer

Format: YYYY.MM.DD.N – e.g. 2026.06.01.3

  • YYYY.MM.DD – current date in UTC
  • N – monotonically increasing counter per day, 1-based

N is calculated exclusively from local Git tags – no SCM API call, fully provider-agnostic. relctl lists all tags matching YYYY.MM.DD.* for today and sets N to max(N) + 1 (or 1 if no tag exists yet).

Prerequisite: the repository must be checked out with full tag history (fetch-depth: 0). This is already a general relctl requirement.

Configuration

.relctl.yaml (repo-level config file)

Place a .relctl.yaml in your repository root to set project-wide defaults:

version_scheme: calver   # semver (default) | calver | conventional-commits
default_branch: main

The file is optional. When absent, relctl behaves exactly as before (SemVer, main).

Priority: --version-scheme flag > .relctl.yaml > built-in default (SemVer)

CLI Flags

Flag Scope Description
--config <path> relctl, release Override config file path (default: .relctl.yaml)
--version-scheme <scheme> release semver, calver or conventional-commits; overrides config file

Usage

SemVer release (existing workflow, unchanged)

# After merging a PR – relctl reads the PR branch and GitHub API
relctl release create
relctl release publish --release-id "$RELCTL_RELEASE_ID" --asset "file=dist/binary"

Conventional Commits release via flag (no config file needed)

relctl release create --version-scheme conventional-commits --dry-run
# Would create new release with version: 1.3.0

CalVer release via config file

# .relctl.yaml
version_scheme: calver
# No branch prefix or PR context required
relctl release create
# → e.g. 2026.06.01.1

relctl release publish --release-id "$RELCTL_RELEASE_ID" --asset "file=dist/binary"

CalVer release via flag (no config file needed)

relctl release create --version-scheme calver
# → e.g. 2026.06.01.1

# Second release on the same day (git tag 2026.06.01.1 already exists)
relctl release create --version-scheme calver
# → 2026.06.01.2

Dry-run (preview version without creating a release)

relctl release create --version-scheme calver --dry-run
# Would create new release with version: 2026.06.01.1

GitHub Actions example

- uses: actions/checkout@v4
  with:
    fetch-depth: 0   # required: full tag history for N calculation

- name: Create CalVer release
  run: relctl release create --version-scheme calver
  env:
    GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Examples

More examples are available in the examples section of the documentation.

Frequently Asked Questions

See the Q&A section.

Getting Help

Please file an issue in this repository's Issue Tracker.

Community

License

relctl is licensed under the Apache License, Version 2.0. See LICENSE.

Credits

About

Release Control - CLI tool for managing GitHub releases and pull requests in CI/CD pipelines

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages