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.
| Comment | Effect |
|---|---|
relctl_patch_level: major | Force a MAJOR bump (overrides branch-derived level) |
relctl_patch_level: minor | Force a MINOR bump |
relctl_patch_level: patch | Force a PATCH bump |
relctl_version_override: 2.1.0 | Pin the next version to exactly 2.1.0 (must be valid SemVer) |
relctl_version_overridetakes precedence overrelctl_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:
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:
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.
version_scheme: calver
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.
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:
| Variable | Description |
|---|---|
RELCTL_NEXT_VERSION | Computed next SemVer version |
RELCTL_RELEASE_ID | GitHub release ID of the draft |
RELCTL_PR_SHA | Full merge commit SHA |
RELCTL_PR_SHA_SHORT | Short (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:
| Variable | Source |
|---|---|
CI | Set automatically by Jenkins |
JENKINS_URL | Set automatically by Jenkins |
GIT_URL | Set by the GitHub Plugin |
GITHUB_REPOSITORY | Must be set manually (owner/repo) |
GITHUB_TOKEN | Set via credentials binding |