Skip to main content

CI Integration

PR & branch workflow

PR comment overrides

When relctl runs in CI with pull-requests: write permission, it posts a help comment to the PR and watches all comments for override commands. The last matching comment wins and is applied during the release.

CommentEffect
relctl_patch_level: majorForce a MAJOR bump (overrides branch-derived level)
relctl_patch_level: minorForce a MINOR bump
relctl_patch_level: patchForce a PATCH bump
relctl_version_override: 2.1.0Pin the next version to exactly 2.1.0 (must be valid SemVer)

relctl_version_override takes precedence over relctl_patch_level. Both commands must appear at the start of a comment body with the exact spacing shown above.

Required GitHub Actions permissions

permissions:
contents: write # create releases
pull-requests: write # post help comment + read override commands

Without pull-requests: write the help comment is silently skipped and no overrides are evaluated.

Disable the help comment

Set RELCTL_SILENT=true in your workflow to suppress the automated PR comment entirely while still evaluating override commands that are already present:

env:
RELCTL_SILENT: "true"

CI release pipeline

GitHub Actions

Minimal setup

Install relctl via the official action, then use it in your steps:

- uses: layer87-labs/relctl-action@main
with:
github-token: ${{ secrets.GITHUB_TOKEN }}

- name: Create release
run: relctl release create --merge-sha ${{ github.sha }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Reusable workflows (all-in-one)

relctl-action ships two ready-made reusable workflows that cover the most common CI patterns — no boilerplate needed.

generate-build-infos — PR metadata for build jobs

Use this on every pull request to derive the build version, SHA, branch, and semver bump level:

.github/workflows/ci.yaml
jobs:
build-info:
uses: layer87-labs/relctl-action/.github/workflows/generate-build-infos.yml@main
secrets:
token: ${{ secrets.GITHUB_TOKEN }}

build:
needs: build-info
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Build
run: make VERSION="${{ needs.build-info.outputs.version }}"

Available outputs: pr, sha, sha-short, branch, owner, repo, patch-level, version (<next>-pr-<number>), latest-version, next-version.

create-release — Full release from merged PR

Runs relctl pr info + relctl release create in one job:

.github/workflows/release.yaml
jobs:
release:
uses: layer87-labs/relctl-action/.github/workflows/create-release.yml@main
secrets:
token: ${{ secrets.GITHUB_TOKEN }}

publish:
needs: release
runs-on: ubuntu-latest
steps:
- uses: layer87-labs/relctl-action@main
with:
github-token: ${{ secrets.GITHUB_TOKEN }}

- name: Publish release
run: |
relctl release publish \
--release-id "${{ needs.release.outputs.release-id }}" \
--asset "file=out/myapp_${{ needs.release.outputs.version }}_linux-amd64"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

create-release with CalVer

For repos using CalVer (.relctl.yaml or --version-scheme calver), the reusable workflow works identically — the versioning is handled inside relctl, no workflow changes needed.

.relctl.yaml (in repo root)
version_scheme: calver
.github/workflows/release.yaml
jobs:
release:
uses: layer87-labs/relctl-action/.github/workflows/create-release.yml@main
secrets:
token: ${{ secrets.GITHUB_TOKEN }}
# ... publish as usual

Available outputs: release-id, sha, sha-short, owner, repo, version, latest-version, next-version.


Full release workflow (manual steps)

Three-job pattern: create draft → build matrix → publish with assets.

.github/workflows/release.yaml
name: Publish Release

on:
push:
branches:
- main

jobs:
create_release:
runs-on: ubuntu-latest
outputs:
release-id: ${{ steps.tag.outputs.RELCTL_RELEASE_ID }}
version: ${{ steps.tag.outputs.RELCTL_NEXT_VERSION }}
steps:
- uses: actions/checkout@v6

- uses: layer87-labs/relctl-action@main
with:
github-token: ${{ secrets.GITHUB_TOKEN }}

- name: Create release
id: tag
run: relctl release create --merge-sha ${{ github.sha }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

build:
runs-on: ubuntu-latest
needs: create_release
strategy:
matrix:
arch: [amd64, arm64]
steps:
- uses: actions/checkout@v6

- uses: actions/setup-go@v5
with:
go-version-file: go.mod

- name: Build ${{ matrix.arch }}
run: make VERSION="${{ needs.create_release.outputs.version }}"
env:
GOOS: linux
GOARCH: ${{ matrix.arch }}

- uses: actions/cache@v4
with:
path: out/
key: build-${{ github.sha }}-${{ matrix.arch }}

publish_release:
runs-on: ubuntu-latest
needs: [create_release, build]
steps:
- uses: actions/checkout@v6

- uses: layer87-labs/relctl-action@main
with:
github-token: ${{ secrets.GITHUB_TOKEN }}

- uses: actions/cache@v4
with:
path: out/
key: build-${{ github.sha }}-amd64

- uses: actions/cache@v4
with:
path: out/
key: build-${{ github.sha }}-arm64

- name: Publish release
run: |
relctl release publish \
--release-id "$RELCTL_RELEASE_ID" \
--asset "file=out/myapp_${{ needs.create_release.outputs.version }}_linux-amd64" \
--asset "file=out/myapp_${{ needs.create_release.outputs.version }}_linux-arm64"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
RELCTL_RELEASE_ID: ${{ needs.create_release.outputs.release-id }}

Step outputs

After relctl release create, these outputs are set in $GITHUB_OUTPUT:

VariableDescription
RELCTL_NEXT_VERSIONComputed next SemVer version
RELCTL_RELEASE_IDGitHub release ID of the draft
RELCTL_PR_SHAFull merge commit SHA
RELCTL_PR_SHA_SHORTShort (7-char) merge commit SHA

Hotfix release

- name: Create hotfix release
run: relctl release create --hotfix --merge-sha ${{ github.sha }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Force a specific bump

- name: Create release (force minor bump)
run: relctl release create --patch-level minor --merge-sha ${{ github.sha }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Jenkins Pipeline

pipeline {
environment {
GITHUB_REPOSITORY = 'my-org/my-repo'
GITHUB_TOKEN = credentials('github-token')
}
stages {
stage('Install relctl') {
steps {
sh '''
curl -fsSL -o relctl \
https://github.com/layer87-labs/relctl/releases/latest/download/relctl_linux-amd64
chmod +x relctl
mv relctl /usr/local/bin/relctl
'''
}
}
stage('Create Release') {
steps {
sh 'relctl release create'
}
}
}
}

Required Jenkins environment variables:

VariableSource
CISet automatically by Jenkins
JENKINS_URLSet automatically by Jenkins
GIT_URLSet by the GitHub Plugin
GITHUB_REPOSITORYMust be set manually (owner/repo)
GITHUB_TOKENSet via credentials binding