Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .github/actionlint.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# SPDX-FileCopyrightText: © 2026 OpenCHAMI a Series of LF Projects, LLC
# SPDX-License-Identifier: MIT

# actionlint doesn't recognize GitHub's self-repository `uses: $/...` syntax
# yet. Remove this once it does.
paths:
.github/workflows/0-local-ci.yml:
ignore:
- 'reusable workflow call "\$/'
25 changes: 25 additions & 0 deletions .github/workflows/0-local-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# SPDX-FileCopyrightText: © 2025 OpenCHAMI a Series of LF Projects, LLC
# SPDX-License-Identifier: MIT

name: 0-local-ci

# Local to this repo: CI for github-actions itself. Not a reusable workflow;
# do not call it from other repos. See "Workflow naming" in the README.

on:
pull_request:
push:
branches: [ main ]

permissions:
contents: read # baseline for checkout

jobs:
lint:
uses: $/.github/workflows/lint-ci.yml
permissions:
contents: read # baseline for checkout
security-events: write # zizmor SARIF upload to GHAS

lint-renovate:
uses: $/.github/workflows/lint-renovate.yml
128 changes: 128 additions & 0 deletions .github/workflows/build-check-goreleaser.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
# SPDX-FileCopyrightText: © 2026 OpenCHAMI a Series of LF Projects, LLC
# SPDX-License-Identifier: MIT

name: build-check-goreleaser

# Reusable workflow that proves the caller's GoReleaser config builds
# everything (binaries, archives, packages, images) without publishing
# anything: `goreleaser release --snapshot`. Read-only and secret-free, so it
# is safe for fork PRs. Use build-release-goreleaser to publish.
#
# Sets the same environment as build-release-goreleaser (GIT_STATE,
# BUILD_HOST, GO_VERSION, BUILD_USER, IS_PR_BUILD=true, GPG_KEY_PATH empty) so
# the same .goreleaser.yaml works in both.

on:
workflow_call:
inputs:
go-version:
description: 'Go version to use (e.g. "1.26.7", "stable"). Mutually exclusive with go-version-file.'
required: false
type: string
go-version-file:
description: 'Path to a go.mod or .go-version file containing the Go version. Mutually exclusive with go-version.'
required: false
type: string
goreleaser-version:
description: 'GoReleaser version to run'
required: false
type: string
default: 'v2.18.2'
build-deps:
description: 'Space-separated apt packages to install before building (e.g. "gcc-aarch64-linux-gnu libc6-dev-arm64-cross")'
required: false
type: string
default: ''
cgo-enabled:
description: 'Value for CGO_ENABLED'
required: false
type: number
default: 0
skip:
description: 'Comma-separated GoReleaser pipes to skip (e.g. "docker")'
required: false
type: string
default: ''
dist-artifact-name:
description: 'Artifact name for the packages, archives, and checksums in dist/ (e.g. for validate-packages); empty skips the upload'
required: false
type: string
default: 'goreleaser-dist'

permissions:
contents: read # baseline for checkout

jobs:
build-check-goreleaser:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
fetch-tags: true
persist-credentials: false
- name: Install build dependencies
if: ${{ inputs.build-deps != '' }}
env:
BUILD_DEPS: ${{ inputs.build-deps }}
run: |
sudo apt-get update
# shellcheck disable=SC2086 # intentional word splitting
sudo apt-get install -y --no-install-recommends ${BUILD_DEPS}
- uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
with:
go-version: ${{ inputs.go-version || (inputs.go-version-file == '' && 'stable' || '') }}
go-version-file: ${{ inputs.go-version-file || '' }}
cache: false # published artifacts must not come from a poisonable cache
- uses: docker/setup-qemu-action@99012661954931238ded8c8b007157a8430204e1 # v4.4.0
- uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1

- name: Set build environment
id: build-env
run: |
git_state=dirty
if git diff-index --quiet HEAD -- >/dev/null 2>&1; then
git_state=clean
fi
{
echo "git-state=${git_state}"
echo "build-host=$(hostname)"
echo "go-version=$(go version | awk '{print $3}')"
echo "build-user=$(whoami)"
} >> "$GITHUB_OUTPUT"
- name: Assemble GoReleaser arguments
id: args
env:
SKIP: ${{ inputs.skip }}
run: |
args="release --snapshot --clean"
[[ -n "$SKIP" ]] && args+=" --skip=${SKIP}"
echo "GoReleaser arguments: ${args}"
echo "args=${args}" >> "$GITHUB_OUTPUT"
- name: Run GoReleaser (snapshot)
uses: goreleaser/goreleaser-action@f06c13b6b1a9625abc9e6e439d9c05a8f2190e94 # v7.2.3
env:
CGO_ENABLED: ${{ inputs.cgo-enabled }}
IS_PR_BUILD: 'true'
GIT_STATE: ${{ steps.build-env.outputs.git-state }}
BUILD_HOST: ${{ steps.build-env.outputs.build-host }}
GO_VERSION: ${{ steps.build-env.outputs.go-version }}
BUILD_USER: ${{ steps.build-env.outputs.build-user }}
GPG_KEY_PATH: ''
with:
distribution: goreleaser
version: ${{ inputs.goreleaser-version }}
args: ${{ steps.args.outputs.args }}

- name: Upload dist
if: ${{ inputs.dist-artifact-name != '' }}
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: ${{ inputs.dist-artifact-name }}
path: |
dist/*.rpm
dist/*.deb
dist/*.tar.gz
dist/*.zip
dist/*checksums.txt
if-no-files-found: warn
65 changes: 38 additions & 27 deletions .github/workflows/build-publish-container-goreleaser.yml
Original file line number Diff line number Diff line change
@@ -1,44 +1,52 @@
# Copyright © 2026 OpenCHAMI a Series of LF Projects, LLC
# SPDX-License-Identifier: MIT
#
# ############################################################################
# # DEPRECATED WORKFLOW -- DO NOT USE IN NEW CALLERS
# #
# # build-publish-container-goreleaser is replaced by build-release-goreleaser.yml (build-only: build-check-goreleaser.yml).
# # It is kept only so callers pinned to older refs keep working, and will be
# # removed in a future major release. See README.md for migration notes.
# ############################################################################
#
# Reusable workflow: builds and publishes a container image via GoReleaser,
# with multi-arch builds, build provenance attestation, and PR snapshot
# support.

name: Build and publish container using goreleaser
name: build-publish-container-goreleaser
on:
workflow_call:
inputs:
build_deps:
build-deps:
type: string
required: false
description: 'Space-separated list of apt packages to install before building (e.g. "gcc-aarch64-linux-gnu libc6-dev-arm64-cross").'
cgo_enabled:
cgo-enabled:
type: number
required: false
default: 0
go_version:
go-version:
type: string
required: false
description: 'Go version to use (e.g. "1.26.7", "stable"). Mutually exclusive with go_version_file.'
go_version_file:
description: 'Go version to use (e.g. "1.26.7", "stable"). Mutually exclusive with go-version-file.'
go-version-file:
type: string
required: false
description: 'Path to a go.mod or .go-version file containing the Go version. Mutually exclusive with go_version.'
release_draft:
description: 'Path to a go.mod or .go-version file containing the Go version. Mutually exclusive with go-version.'
release-draft:
type: boolean
required: false
default: false
description: 'Create the release as a draft, overriding release.draft in .goreleaser.yml'
is_pr_build:
is-pr-build:
type: boolean
required: false
default: false
pr_number:
pr-number:
type: number
required: false
default: ${{ github.event.number || 0 }}
registry_subject_name:
registry-subject-name:
type: string
required: true

Expand All @@ -49,27 +57,30 @@ permissions:
attestations: write # write build provenance attestations

jobs:
container_build_publish:
container-build-publish:
runs-on: ubuntu-latest
steps:
- name: Deprecation warning
run: |
echo "::warning title=Deprecated workflow::build-publish-container-goreleaser.yml is deprecated; migrate to build-release-goreleaser.yml (build-only: build-check-goreleaser.yml)."
- name: Checkout
uses: actions/checkout@v6.0.2
with:
fetch-tags: true
fetch-depth: 0
- name: Install build dependencies
if: ${{ inputs.build_deps != '' }}
if: ${{ inputs.build-deps != '' }}
env:
BUILD_DEPS: ${{ inputs.build_deps }}
BUILD_DEPS: ${{ inputs.build-deps }}
run: |
sudo apt update
# shellcheck disable=SC2086 # intentional word splitting
sudo apt install -y --no-install-recommends ${BUILD_DEPS}
- name: Set up Go
uses: actions/setup-go@v6.4.0
with:
go-version: ${{ inputs.go_version || (inputs.go_version_file == '' && 'stable' || '') }}
go-version-file: ${{ inputs.go_version_file || '' }}
go-version: ${{ inputs.go-version || (inputs.go-version-file == '' && 'stable' || '') }}
go-version-file: ${{ inputs.go-version-file || '' }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
Expand Down Expand Up @@ -107,17 +118,17 @@ jobs:
echo "BUILD_HOST=$(hostname)"
echo "GO_VERSION=$(go version | awk '{print $3}')"
echo "BUILD_USER=$(whoami)"
echo "CGO_ENABLED=${{ inputs.cgo_enabled }}"
echo "IS_PR_BUILD=${{ inputs.is_pr_build }}"
echo "CGO_ENABLED=${{ inputs.cgo-enabled }}"
echo "IS_PR_BUILD=${{ inputs.is-pr-build }}"
} >> "${GITHUB_ENV}"
- name: Create Tag for PR
if: ${{ inputs.is_pr_build }}
if: ${{ inputs.is-pr-build }}
run: |
git config --global user.name "github-actions[bot]"
git config --global user.email "github-actions[bot]@users.noreply.github.com"
git tag -f -a pr-${{ inputs.pr_number }} -m "PR Release"
git tag -f -a pr-${{ inputs.pr-number }} -m "PR Release"
- name: Generate release notes
if: ${{ !inputs.is_pr_build }}
if: ${{ !inputs.is-pr-build }}
env:
GITHUB_TOKEN: ${{ github.token }}
run: gh api "repos/${GITHUB_REPOSITORY}/releases/generate-notes" -F tag_name="${{ github.ref_name }}" --jq .body > ../notes.md
Expand All @@ -127,11 +138,11 @@ jobs:
GITHUB_TOKEN: ${{ github.token }}
with:
version: '~> 2'
args: release --clean ${{ inputs.is_pr_build && '--skip=announce,validate,archive' || '' }}${{ env.SKIP_CONTAINER_PUBLISH == 'true' && (inputs.is_pr_build && ',publish' || '--skip=publish') || '' }} ${{ inputs.release_draft && '--draft' || '' }} ${{ !inputs.is_pr_build && '--release-notes ../notes.md' || '' }}
args: release --clean ${{ inputs.is-pr-build && '--skip=announce,validate,archive' || '' }}${{ env.SKIP_CONTAINER_PUBLISH == 'true' && (inputs.is-pr-build && ',publish' || '--skip=publish') || '' }} ${{ inputs.release-draft && '--draft' || '' }} ${{ !inputs.is-pr-build && '--release-notes ../notes.md' || '' }}
id: goreleaser
- name: Process goreleaser output
if: env.SKIP_CONTAINER_PUBLISH == 'false'
id: process_goreleaser_output
id: process-goreleaser-output
run: |
node - <<'EOF'
const fs = require('fs');
Expand All @@ -149,14 +160,14 @@ jobs:
echo "digest=$(cat digest.txt)" >> "${GITHUB_OUTPUT}"
fi
- name: Attest Binaries
if: ${{ (env.SKIP_CONTAINER_PUBLISH == 'false') && (inputs.is_pr_build == false) }}
if: ${{ (env.SKIP_CONTAINER_PUBLISH == 'false') && (inputs.is-pr-build == false) }}
uses: actions/attest-build-provenance@v4.1.0
with:
subject-path: dist/**
- name: generate build provenance
if: ${{ (env.SKIP_CONTAINER_PUBLISH == 'false') && (inputs.is_pr_build == false) }}
if: ${{ (env.SKIP_CONTAINER_PUBLISH == 'false') && (inputs.is-pr-build == false) }}
uses: actions/attest-build-provenance@v4.1.0
with:
subject-name: ${{ inputs.registry_subject_name }}
subject-digest: ${{ steps.process_goreleaser_output.outputs.digest }}
subject-name: ${{ inputs.registry-subject-name }}
subject-digest: ${{ steps.process-goreleaser-output.outputs.digest }}
push-to-registry: true
Loading
Loading