headroom/.github/workflows/docker.yml
JerrettDavis bde7aa9c30 fix: align docker image versions with releases
Derive the exact Docker image version from the release tag or manual
workflow input, sync versioned files in the build workspace before the
image build, and publish an explicit matching image tag.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-17 12:17:49 -05:00

128 lines
4.4 KiB
YAML

name: Docker
on:
workflow_dispatch:
inputs:
version:
description: "Version to stamp into the image contents and exact image tag"
required: false
release:
types: [published]
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
permissions:
contents: read
packages: write
id-token: write # For cosign keyless signing via Sigstore OIDC
jobs:
docker-variant-tags:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- variant: ""
bake_target: runtime
- variant: nonroot
bake_target: runtime-nonroot
- variant: code
bake_target: runtime-code
- variant: code-nonroot
bake_target: runtime-code-nonroot
- variant: slim
bake_target: runtime-slim
- variant: slim-nonroot
bake_target: runtime-slim-nonroot
- variant: code-slim
bake_target: runtime-code-slim
- variant: code-slim-nonroot
bake_target: runtime-code-slim-nonroot
steps:
- uses: actions/checkout@v6
- name: Determine image version
id: version
env:
MANUAL_VERSION: ${{ github.event.inputs.version }}
RELEASE_TAG: ${{ github.event.release.tag_name }}
run: |
version="${MANUAL_VERSION#v}"
if [ -z "$version" ] && [ -n "$RELEASE_TAG" ]; then
version="${RELEASE_TAG#v}"
fi
printf 'version=%s\n' "$version" >> "$GITHUB_OUTPUT"
- name: Set up Python
if: steps.version.outputs.version != ''
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Sync versioned files for image build
if: steps.version.outputs.version != ''
run: |
python scripts/version-sync.py --version ${{ steps.version.outputs.version }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
- name: Log in to GHCR
uses: docker/login-action@v4
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata (variant)
id: meta
uses: docker/metadata-action@v6
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch,suffix=${{ matrix.variant != '' && format('-{0}', matrix.variant) || '' }}
type=ref,event=pr,suffix=${{ matrix.variant != '' && format('-{0}', matrix.variant) || '' }}
type=raw,value=${{ steps.version.outputs.version }},enable=${{ steps.version.outputs.version != '' }},suffix=${{ matrix.variant != '' && format('-{0}', matrix.variant) || '' }}
type=semver,pattern={{version}},suffix=${{ matrix.variant != '' && format('-{0}', matrix.variant) || '' }}
type=semver,pattern={{major}}.{{minor}},suffix=${{ matrix.variant != '' && format('-{0}', matrix.variant) || '' }}
type=semver,pattern={{major}},suffix=${{ matrix.variant != '' && format('-{0}', matrix.variant) || '' }}
type=sha,prefix=${{ matrix.variant != '' && format('{0}-', matrix.variant) || 'sha-' }}
type=raw,value=${{ matrix.variant }},enable=${{ matrix.variant != '' }}
type=raw,value=latest,enable=${{ matrix.variant == '' }}
- name: Build and push variant (bake)
id: bake
uses: docker/bake-action@v7
with:
files: |
./docker-bake.hcl
cwd://${{ steps.meta.outputs.bake-file-tags }}
cwd://${{ steps.meta.outputs.bake-file-labels }}
targets: ${{ matrix.bake_target }}
push: true
set: |
*.cache-from=type=gha
*.cache-to=type=gha,mode=max
- name: Install cosign
uses: sigstore/cosign-installer@v3
- name: Sign images with cosign (keyless via Sigstore OIDC)
env:
BAKE_META: ${{ steps.bake.outputs.metadata }}
run: |
# Extract all pushed image digests from bake metadata and sign each
echo "$BAKE_META" | jq -r '
to_entries[].value."containerimage.digest" // empty
' | while read -r digest; do
image="${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${digest}"
echo "Signing ${image}"
cosign sign --yes "${image}"
done