Files
shared-actions/.github/workflows/go-release.yaml
T
lukaszraczylo f9b22ef8d9 feat(preflight): fail early when a secret or repository access is missing
A release run used to fail at the GoReleaser step when a secret was
empty, after the tests and the version job had finished.

A new preflight action checks the required names, the .Env references
in the GoReleaser config and push access to optional repositories. It
lists every problem in one run. The release and release-cgo workflows
run it in a first job, so a missing secret fails in seconds.

The release-cgo workflow requires GORELEASER_PRO. The release workflow
requires the secrets that the GoReleaser config references. Set the
preflight input to false to skip the check. Set preflight-repos to check
access to a Homebrew tap or helm-charts repository.
2026-10-02 01:23:56 +01:00

208 lines
7.1 KiB
YAML

name: Go Release
on:
workflow_call:
inputs:
go-version:
description: "Go version to use"
required: false
type: string
default: ">=1.24"
semver-config:
description: "Path to semver config file"
required: false
type: string
default: "semver.yaml"
docker-enabled:
description: "Enable Docker builds"
required: false
type: boolean
default: false
docker-registry:
description: "Docker registry to push to"
required: false
type: string
default: "ghcr.io"
rolling-release-tag:
description: "Create a rolling release tag (e.g., 'v1')"
required: false
type: string
default: ""
lfs:
description: "Enable Git LFS checkout (for repos with large files)"
required: false
type: boolean
default: false
runner:
description: "Runner label, or JSON object such as {\"group\":\"ci\",\"labels\":[\"linux\"]} to select a runner group. Falls back to vars.SHARED_ACTIONS_RUNNER, then ubuntu-latest."
required: false
type: string
default: ""
preflight:
description: "Fail early when a required secret, env var or GoReleaser .Env reference is missing"
required: false
type: boolean
default: true
preflight-repos:
description: "Comma-separated owner/repo list the token must have push access to (e.g. a Homebrew tap or helm-charts repo)"
required: false
type: string
default: ""
outputs:
version:
description: "The calculated version (without v prefix)"
value: ${{ jobs.version.outputs.version }}
version_tag:
description: "The version tag (with v prefix)"
value: ${{ jobs.version.outputs.version_tag }}
concurrency:
group: release-${{ github.repository }}-${{ github.ref }}
cancel-in-progress: false
jobs:
preflight:
name: Preflight
runs-on: ${{ fromJSON(startsWith(inputs.runner || vars.SHARED_ACTIONS_RUNNER || 'ubuntu-latest', '{') && inputs.runner || vars.SHARED_ACTIONS_RUNNER || 'ubuntu-latest' || toJSON(inputs.runner || vars.SHARED_ACTIONS_RUNNER || 'ubuntu-latest')) }}
timeout-minutes: 5
steps:
- name: Checkout
if: inputs.preflight
uses: actions/checkout@v6
with:
lfs: false
- name: Check secrets and access
if: inputs.preflight
uses: lukaszraczylo/shared-actions/.github/actions/preflight@main
with:
require: GITHUB_TOKEN
repo-access: ${{ inputs.preflight-repos }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
HOMEBREW_TAP_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }}
test:
name: Test
needs: preflight
runs-on: ${{ fromJSON(startsWith(inputs.runner || vars.SHARED_ACTIONS_RUNNER || 'ubuntu-latest', '{') && inputs.runner || vars.SHARED_ACTIONS_RUNNER || 'ubuntu-latest' || toJSON(inputs.runner || vars.SHARED_ACTIONS_RUNNER || 'ubuntu-latest')) }}
timeout-minutes: 30
steps:
- name: Checkout
uses: actions/checkout@v6
with:
lfs: ${{ inputs.lfs }}
- name: Run workflow prepare script
shell: bash
run: |
if [ -f "./workflow-prepare.sh" ]; then
chmod +x ./workflow-prepare.sh
./workflow-prepare.sh
fi
- name: Run tests
uses: lukaszraczylo/shared-actions/.github/actions/go-test@main
with:
go-version: ${{ inputs.go-version }}
version:
name: Calculate Version
needs: test
runs-on: ${{ fromJSON(startsWith(inputs.runner || vars.SHARED_ACTIONS_RUNNER || 'ubuntu-latest', '{') && inputs.runner || vars.SHARED_ACTIONS_RUNNER || 'ubuntu-latest' || toJSON(inputs.runner || vars.SHARED_ACTIONS_RUNNER || 'ubuntu-latest')) }}
outputs:
version: ${{ steps.semver.outputs.version }}
version_tag: ${{ steps.semver.outputs.version_tag }}
timeout-minutes: 10
steps:
- name: Checkout
uses: actions/checkout@v6
with:
fetch-depth: 0
lfs: ${{ inputs.lfs }}
- name: Run workflow prepare script
shell: bash
run: |
if [ -f "./workflow-prepare.sh" ]; then
chmod +x ./workflow-prepare.sh
./workflow-prepare.sh
fi
- name: Calculate version
id: semver
uses: lukaszraczylo/shared-actions/.github/actions/semver@main
with:
config-file: ${{ inputs.semver-config }}
release:
name: Release
needs: version
if: needs.version.outputs.version_tag != ''
runs-on: ${{ fromJSON(startsWith(inputs.runner || vars.SHARED_ACTIONS_RUNNER || 'ubuntu-latest', '{') && inputs.runner || vars.SHARED_ACTIONS_RUNNER || 'ubuntu-latest' || toJSON(inputs.runner || vars.SHARED_ACTIONS_RUNNER || 'ubuntu-latest')) }}
permissions:
contents: write
packages: write
id-token: write
timeout-minutes: 60
steps:
- name: Checkout
uses: actions/checkout@v6
with:
fetch-depth: 0
lfs: ${{ inputs.lfs }}
- name: Run workflow prepare script
# Expose the computed release version to a repo-local workflow-prepare.sh
# (e.g. to stamp the version into source for runtimes that cannot resolve
# it at build time, such as Yaegi-interpreted Traefik plugins). Only the
# release job has a version; the test/version jobs run the hook without
# it. VERSION is the bare semver (1.2.3); VERSION_TAG keeps the v prefix.
env:
VERSION: ${{ needs.version.outputs.version }}
VERSION_TAG: ${{ needs.version.outputs.version_tag }}
shell: bash
run: |
if [ -f "./workflow-prepare.sh" ]; then
chmod +x ./workflow-prepare.sh
./workflow-prepare.sh
fi
- name: Setup Go
uses: actions/setup-go@v6
with:
go-version: ${{ inputs.go-version }}
# Docker setup (optional)
- name: Set up QEMU
if: inputs.docker-enabled
uses: docker/setup-qemu-action@v4
- name: Set up Docker Buildx
if: inputs.docker-enabled
uses: docker/setup-buildx-action@v4
- name: Login to GHCR
if: inputs.docker-enabled
uses: docker/login-action@v4
with:
registry: ${{ inputs.docker-registry }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Run GoReleaser
uses: lukaszraczylo/shared-actions/.github/actions/goreleaser@main
with:
version-tag: ${{ needs.version.outputs.version_tag }}
mode: full
github-token: ${{ secrets.GITHUB_TOKEN }}
homebrew-tap-token: ${{ secrets.HOMEBREW_TAP_TOKEN }}
- name: Rolling release
if: inputs.rolling-release-tag != ''
uses: lukaszraczylo/shared-actions/.github/actions/rolling-release@main
with:
tag: ${{ inputs.rolling-release-tag }}
version-tag: ${{ needs.version.outputs.version_tag }}
github-token: ${{ secrets.GITHUB_TOKEN }}