mirror of
https://github.com/lukaszraczylo/shared-actions.git
synced 2026-10-12 04:54:48 +00:00
A caller can grant narrower permissions than the release job needs. The release then fails at the end, when it creates the tag or pushes an image. The preflight job now declares the same contents and packages permissions as the release job and probes with the real token. A git push dry run checks that the token can create the tag and release. A ghcr.io token request and a blob upload session check that the token can push the image. The upload session creates no package. The release-cgo workflow probes ghcr only when the GoReleaser config builds ghcr.io images. The release workflow probes it when docker-enabled is true and the registry is ghcr.io. A probe that cannot reach a verdict warns and does not fail.
213 lines
7.3 KiB
YAML
213 lines
7.3 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
|
|
permissions:
|
|
contents: write
|
|
packages: write
|
|
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
|
|
release-write: "true"
|
|
ghcr-push: ${{ inputs.docker-enabled && inputs.docker-registry == 'ghcr.io' && 'true' || 'false' }}
|
|
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 }}
|