Skip to content

feat: valkey

feat: valkey #995

Workflow file for this run

---
name: Docker
on:
push:
tags: [v*]
pull_request:
branches: [main, 'v[0-9]+.[0-9]+.[0-9]+*']
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
DOCKER_BUILD_SUMMARY: true
DOCKER_BUILD_CHECKS_ANNOTATIONS: true
# renovate: datasource=python-version depName=python
PYTHON_VERSION: 3.13.11
SHA_PREFIX_LENGTH: 7
VALIDATE_TIMEOUT_MINUTES: 10
BUILD_TIMEOUT_MINUTES: 15
DOCKER_IMAGE_TITLE: Tux
DOCKER_IMAGE_DESCRIPTION: Tux - The all in one discord bot for the All Things Linux
Community
DOCKER_IMAGE_SOURCE: https://github.com/allthingslinux/tux
DOCKER_IMAGE_LICENSE: GPL-3.0
DOCKER_IMAGE_AUTHORS: All Things Linux
DOCKER_IMAGE_VENDOR: All Things Linux
DOCKER_IMAGE_DOCS: https://github.com/allthingslinux/tux/blob/main/README.md
jobs:
changes:
name: File Detection
runs-on: ubuntu-latest
permissions:
contents: read
outputs:
# For tags (immutable), always return true to allow build
# For other events, use the actual changed-files output
# Note: workflow_dispatch sets github.ref to refs/heads/<tag>, so check ref_name instead
docker: >-
${{ (startsWith(github.ref, 'refs/tags/')
|| (github.event_name == 'workflow_dispatch' && startsWith(github.ref_name,
'v')))
&& 'true' || steps.docker_changes.outputs.any_changed }}
steps:
- name: Checkout
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
fetch-depth: 0
- name: Check Docker
uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47
id: docker_changes
with:
files: |
Containerfile
compose.yaml
.dockerignore
docker/**
validate:
name: Validate
needs: [changes]
if: github.event_name == 'workflow_dispatch' || (github.event_name == 'pull_request'
&& needs.changes.outputs.docker == 'true')
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
packages: write # Required for registry cache backend
steps:
- name: Checkout
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
# Set up Docker Buildx for advanced build features
# Uses docker/setup-buildx-action@v3 to create and boot a builder
# Docs: https://github.com/docker/setup-buildx-action
#
# Default behavior (no explicit config needed):
# - Creates builder with docker-container driver (enables BuildKit features)
# - Supports registry cache and GitHub Actions cache for faster builds
# - Caches buildx binary to GitHub Actions cache backend
# - Automatically cleans up builder and temp files at end of job
# - Switches to this builder instance for subsequent build steps
#
# Why we use Buildx:
# - Required for docker/build-push-action@v6 advanced features
# - Enables hybrid cache (registry + GHA cache) for better cache persistence
# - Supports build-time features (secrets, remote cache, etc.)
# - Future-proof for multi-platform builds if needed
#
# Optional enhancements (not currently needed):
# - Multi-platform: Add docker/setup-qemu-action@v3 for ARM support
# - Version pinning: Add version: v0.x.x to pin Buildx version
# - Custom builder name: Add name: my-builder for persistent builders
- name: Setup Buildx
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3
# Login to registry for registry cache access and Docker Scout (read/write cache, not pushing images)
# Docker Scout requires authentication to access environments and compare images
- name: Login to Registry
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
# Extract Docker image metadata for PR validation builds
# Uses docker/metadata-action@v5 to generate tags and labels
# Docs: https://github.com/docker/metadata-action
#
# Purpose: Generate consistent metadata (tags/labels) for PR validation builds
# - PR builds use simple tags (pr-123) for identification
# - Full OCI labels for image metadata and traceability
# - Labels follow Open Containers Initiative (OCI) specification
#
# Tag strategy for PR builds:
# - type=ref,event=pr: Auto-generates pr-<number> tag from PR event
#
# Label strategy:
# - Custom OCI labels using environment variables
# - Overrides default generated labels with our custom values
# - Includes: title, description, source, license, authors, vendor, revision, docs
#
# Note: Image name is local-only (tux) since PR builds don't push to registry
- name: Extract metadata
id: meta
uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5
with:
# Local image name (no registry prefix needed for validation builds)
images: tux
tags: |
type=ref,event=pr
labels: |
org.opencontainers.image.title=${{ env.DOCKER_IMAGE_TITLE }}
org.opencontainers.image.description=${{ env.DOCKER_IMAGE_DESCRIPTION }}
org.opencontainers.image.source=${{ env.DOCKER_IMAGE_SOURCE }}
org.opencontainers.image.licenses=${{ env.DOCKER_IMAGE_LICENSE }}
org.opencontainers.image.authors=${{ env.DOCKER_IMAGE_AUTHORS }}
org.opencontainers.image.vendor=${{ env.DOCKER_IMAGE_VENDOR }}
org.opencontainers.image.revision=${{ github.sha }}
org.opencontainers.image.documentation=${{ env.DOCKER_IMAGE_DOCS }}
- name: Generate PR Version
id: pr_version
run: ./.github/scripts/docker.sh generate-pr-version "${{ github.event.number }}"
"${{ github.sha }}" "${{ env.SHA_PREFIX_LENGTH }}"
- name: Generate Build Date
id: build_date
run: echo "date=$(./.github/scripts/docker.sh generate-build-date)" >> "$GITHUB_OUTPUT"
# Build Docker image for validation (does not push to registry)
# Uses docker/build-push-action@v6 with Buildx for advanced features
# Docs: https://github.com/docker/build-push-action
# Features used:
# - Hybrid cache (registry + GHA) for faster builds with better persistence
# - Load into Docker daemon (load: true) for image scanning
# - Build metadata (tags/labels) for image identification
# - Build-time variables for versioning and traceability
- name: Build
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6
timeout-minutes: 10
with:
# Build context directory (current directory)
context: .
# Path to Containerfile (Dockerfile)
file: Containerfile
# Target stage to build (production stage in Containerfile)
target: production
# Don't push to registry (validation builds only)
push: false
# Load image into Docker daemon for scanning with Docker Scout
load: true
# Hybrid cache: Registry cache (persistent, shared) + GHA cache (fast fallback)
# Registry cache persists across all builds/branches/PRs for better cache hits
# GHA cache provides fast local fallback if registry cache unavailable
cache-from: |
type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache
type=gha
cache-to: |
type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache,mode=max
type=gha,mode=max
# Image tags for identification (from metadata extraction step)
tags: ${{ steps.meta.outputs.tags }}
# OCI labels for image metadata (title, description, source, etc.)
labels: ${{ steps.meta.outputs.labels }}
# Disable attestations to prevent unknown/unknown architecture in GHCR UI
# See: https://github.com/orgs/community/discussions/45969
provenance: false
sbom: false
# Build-time variables passed to Containerfile
build-args: |
VERSION=${{ steps.pr_version.outputs.version }}
GIT_SHA=${{ github.sha }}
BUILD_DATE=${{ steps.build_date.outputs.date }}
# Check if Docker Hub secrets are configured (secrets context not allowed in steps.if)
- name: Check Docker Hub secrets
id: docker_hub_check
run: |
if [ -n "${DOCKER_USER:-}" ] && [ -n "${DOCKER_PAT:-}" ]; then
echo "enabled=true" >> "$GITHUB_OUTPUT"
else
echo "enabled=false" >> "$GITHUB_OUTPUT"
fi
env:
DOCKER_USER: ${{ secrets.DOCKER_USER }}
DOCKER_PAT: ${{ secrets.DOCKER_PAT }}
# Authenticate to Docker Hub (required for Docker Scout when using a non-Docker-Hub registry like GHCR)
# See: https://docs.docker.com/scout/integrations/ci/gha/
- name: Authenticate to Docker Hub
if: steps.docker_hub_check.outputs.enabled == 'true'
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3
with:
username: ${{ secrets.DOCKER_USER }}
password: ${{ secrets.DOCKER_PAT }}
# Run Docker Scout analysis for vulnerability scanning
# For PRs: Compare against production environment to show what changed
# For other events: Run quickview and recommendations for general analysis
- name: Docker Scout Compare
if: github.event_name == 'pull_request'
uses: docker/scout-action@f8c776824083494ab0d56b8105ba2ca85c86e4de # v1
continue-on-error: true
with:
command: compare
image: ${{ steps.meta.outputs.tags }}
to-env: production
ignore-unchanged: true
only-severities: critical,high
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Docker Scout Quickview
if: github.event_name != 'pull_request'
uses: docker/scout-action@f8c776824083494ab0d56b8105ba2ca85c86e4de # v1
continue-on-error: true
with:
command: quickview
image: ${{ steps.meta.outputs.tags }}
only-severities: critical,high
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Docker Scout Recommendations
if: github.event_name != 'pull_request'
uses: docker/scout-action@f8c776824083494ab0d56b8105ba2ca85c86e4de # v1
continue-on-error: true
with:
command: recommendations
image: ${{ steps.meta.outputs.tags }}
github-token: ${{ secrets.GITHUB_TOKEN }}
build:
name: Build & Push
runs-on: ubuntu-latest
needs: [changes]
# Run for tag pushes or workflow_dispatch on version tags (v*)
# Note: workflow_dispatch sets github.ref to refs/heads/<tag> instead of refs/tags/<tag>
# So we check github.ref_name (just the tag name) instead
if: |
(github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')) ||
(github.event_name == 'workflow_dispatch' && startsWith(github.ref_name, 'v'))
permissions:
contents: read
packages: write
# Required for BuildKit provenance signing (provenance: mode=max) via OIDC
id-token: write
steps:
- name: Checkout
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
# Set up Docker Buildx for advanced build features
# Uses docker/setup-buildx-action@v3 to create and boot a builder
# Docs: https://github.com/docker/setup-buildx-action
#
# Default behavior (no explicit config needed):
# - Creates builder with docker-container driver (enables BuildKit features)
# - Supports registry cache and GitHub Actions cache for faster builds
# - Caches buildx binary to GitHub Actions cache backend
# - Automatically cleans up builder and temp files at end of job
# - Switches to this builder instance for subsequent build steps
#
# Why we use Buildx:
# - Required for docker/build-push-action@v6 advanced features
# - Enables hybrid cache (registry + GHA cache) for better cache persistence
# - Supports build-time features (secrets, remote cache, etc.)
# - Future-proof for multi-platform builds if needed
#
# Optional enhancements (not currently needed):
# - Multi-platform: Add docker/setup-qemu-action@v3 for ARM support
# - Version pinning: Add version: v0.x.x to pin Buildx version
# - Custom builder name: Add name: my-builder for persistent builders
- name: Setup Buildx
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3
- name: Login to Registry
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
# Extract Docker image metadata for production release builds
# Uses docker/metadata-action@v5 to generate tags and labels
# Docs: https://github.com/docker/metadata-action
#
# Purpose: Generate consistent metadata (tags/labels) for production images
# - Semantic versioning tags from Git tags (v1.2.3 → 1.2.3, 1.2, latest)
# - Full OCI labels for image metadata and traceability
# - Labels follow Open Containers Initiative (OCI) specification
#
# Tag strategy for release builds:
# - type=semver,pattern={{version}}: Full version tag (e.g., 1.2.3)
# - type=semver,pattern={{major}}.{{minor}}: Minor version tag (e.g., 1.2)
# - type=raw,value=latest,enable={{is_default_branch}}: Latest tag only for default branch
#
# Semver tag behavior:
# - Git tag v1.2.3 generates: 1.2.3 (full version), 1.2 (minor), latest (if default branch)
# - Pre-release tags (alpha, beta, rc) only generate full version tag (not minor/major)
# - Tags are automatically sanitized to comply with Docker tag specifications
#
# Label strategy:
# - Custom OCI labels using environment variables
# - Overrides default generated labels with our custom values
# - Includes: title, description, source, license, authors, vendor, revision, docs
# - Auto-generated by metadata-action: created (build timestamp), version (from semver)
#
# Best practices:
# - Full registry path (ghcr.io/owner/repo) for production images
# - Multiple tags for flexibility (full version, minor version, latest)
# - Comprehensive OCI labels for traceability and compliance
#
# Note: We extract metadata twice - once for validation (manifest-only annotations
# since index annotations aren't supported when loading to Docker daemon) and once
# for push (manifest+index annotations for full registry support).
- name: Extract metadata for validation
id: meta_validate
uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5
with:
# Full registry path for production images (ghcr.io/owner/repo)
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=raw,value=latest
labels: |
org.opencontainers.image.title=${{ env.DOCKER_IMAGE_TITLE }}
org.opencontainers.image.description=${{ env.DOCKER_IMAGE_DESCRIPTION }}
org.opencontainers.image.source=${{ env.DOCKER_IMAGE_SOURCE }}
org.opencontainers.image.licenses=${{ env.DOCKER_IMAGE_LICENSE }}
org.opencontainers.image.authors=${{ env.DOCKER_IMAGE_AUTHORS }}
org.opencontainers.image.vendor=${{ env.DOCKER_IMAGE_VENDOR }}
org.opencontainers.image.revision=${{ github.sha }}
org.opencontainers.image.documentation=${{ env.DOCKER_IMAGE_DOCS }}
# GHCR often reads description from OCI annotations (manifest/index)
# rather than only image config labels, especially when Buildx produces
# an OCI index (e.g. when provenance/attestations are attached).
# For validation builds (load: true), we only use manifest annotations
# since index annotations aren't supported for single-platform Docker exports.
annotations: |
org.opencontainers.image.title=${{ env.DOCKER_IMAGE_TITLE }}
org.opencontainers.image.description=${{ env.DOCKER_IMAGE_DESCRIPTION }}
org.opencontainers.image.source=${{ env.DOCKER_IMAGE_SOURCE }}
org.opencontainers.image.licenses=${{ env.DOCKER_IMAGE_LICENSE }}
org.opencontainers.image.authors=${{ env.DOCKER_IMAGE_AUTHORS }}
org.opencontainers.image.vendor=${{ env.DOCKER_IMAGE_VENDOR }}
org.opencontainers.image.revision=${{ github.sha }}
org.opencontainers.image.documentation=${{ env.DOCKER_IMAGE_DOCS }}
env:
# Only manifest annotations for validation builds (load: true)
# Index annotations aren't supported when loading to Docker daemon
DOCKER_METADATA_ANNOTATIONS_LEVELS: manifest
- name: Extract metadata for push
id: meta_push
uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5
with:
# Full registry path for production images (ghcr.io/owner/repo)
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=raw,value=latest
labels: |
org.opencontainers.image.title=${{ env.DOCKER_IMAGE_TITLE }}
org.opencontainers.image.description=${{ env.DOCKER_IMAGE_DESCRIPTION }}
org.opencontainers.image.source=${{ env.DOCKER_IMAGE_SOURCE }}
org.opencontainers.image.licenses=${{ env.DOCKER_IMAGE_LICENSE }}
org.opencontainers.image.authors=${{ env.DOCKER_IMAGE_AUTHORS }}
org.opencontainers.image.vendor=${{ env.DOCKER_IMAGE_VENDOR }}
org.opencontainers.image.revision=${{ github.sha }}
org.opencontainers.image.documentation=${{ env.DOCKER_IMAGE_DOCS }}
# GHCR often reads description from OCI annotations (manifest/index)
# rather than only image config labels, especially when Buildx produces
# an OCI index (e.g. when provenance/attestations are attached).
annotations: |
org.opencontainers.image.title=${{ env.DOCKER_IMAGE_TITLE }}
org.opencontainers.image.description=${{ env.DOCKER_IMAGE_DESCRIPTION }}
org.opencontainers.image.source=${{ env.DOCKER_IMAGE_SOURCE }}
org.opencontainers.image.licenses=${{ env.DOCKER_IMAGE_LICENSE }}
org.opencontainers.image.authors=${{ env.DOCKER_IMAGE_AUTHORS }}
org.opencontainers.image.vendor=${{ env.DOCKER_IMAGE_VENDOR }}
org.opencontainers.image.revision=${{ github.sha }}
org.opencontainers.image.documentation=${{ env.DOCKER_IMAGE_DOCS }}
env:
# Place annotations on both the manifest and (when present) the index.
# Index annotations are supported when pushing to registry.
DOCKER_METADATA_ANNOTATIONS_LEVELS: manifest,index
- name: Generate Release Version
id: release_version
run: ./.github/scripts/docker.sh generate-release-version "${{ github.ref_name }}"
- name: Validate Build Configuration
run: ./.github/scripts/docker.sh validate-build-config "${{ github.sha }}"
# docker.sh handles empty commit timestamp (e.g. workflow_dispatch has no head_commit)
# by using repository.created_at or date +%s as fallback.
- name: Calculate SOURCE_DATE_EPOCH
id: source_date
run: ./.github/scripts/docker.sh calculate-source-date-epoch "${{ github.event.head_commit.timestamp }}"
"${{ github.event.repository.created_at }}"
- name: Generate Build Date
id: build_date
run: echo "date=$(./.github/scripts/docker.sh generate-build-date)" >> "$GITHUB_OUTPUT"
# Build Docker image for validation (does not push to registry)
# Test-before-push pattern: Build, validate, then push only if validation passes
# Uses docker/build-push-action@v6 with Buildx for advanced features
# Docs: https://github.com/docker/build-push-action
# Features used:
# - Hybrid cache (registry + GHA) for faster builds
# - Load into Docker daemon (load: true) for image scanning
# - Build metadata (tags/labels) for image identification
# - Build-time variables for versioning and traceability
- name: Build for Validation
id: build_validate
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6
timeout-minutes: 15
env:
# Set SOURCE_DATE_EPOCH for reproducible builds
SOURCE_DATE_EPOCH: ${{ steps.source_date.outputs.epoch }}
with:
# Build context directory (current directory)
context: .
# Path to Containerfile (Dockerfile)
file: Containerfile
# Target stage to build (production stage in Containerfile)
target: production
# Don't push to registry yet (validation builds only)
push: false
# Load image into Docker daemon for scanning with Docker Scout
load: true
# Hybrid cache: Registry cache (persistent, shared) + GHA cache (fast fallback)
# Registry cache persists across all builds/branches/PRs for better cache hits
# GHA cache provides fast local fallback if registry cache unavailable
cache-from: |
type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache
type=gha
cache-to: |
type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache,mode=max
type=gha,mode=max
# Image tags for identification (semver versions + latest from metadata extraction)
# Multiple tags created: v1.2.3, 1.2, 1, latest (for default branch)
tags: ${{ steps.meta_validate.outputs.tags }}
# OCI labels for image metadata (title, description, source, license, etc.)
labels: ${{ steps.meta_validate.outputs.labels }}
# OCI annotations for registry UIs (e.g. GHCR package description)
# Using manifest-only annotations since index annotations aren't supported when loading
annotations: ${{ steps.meta_validate.outputs.annotations }}
# Disable attestations for validation build (faster validation, attestations added in push step)
# Note: Attestations (SBOM/provenance) are only generated when pushing, not when loading to daemon
provenance: false
sbom: false
# Always pull base images to ensure we get latest security updates
pull: true
# Build-time variables passed to Containerfile
build-args: |
VERSION=${{ steps.release_version.outputs.version }}
GIT_SHA=${{ github.sha }}
BUILD_DATE=${{ steps.build_date.outputs.date }}
# Check if Docker Hub secrets are configured (secrets context not allowed in steps.if)
- name: Check Docker Hub secrets
id: docker_hub_check
run: |
if [ -n "${DOCKER_USER:-}" ] && [ -n "${DOCKER_PAT:-}" ]; then
echo "enabled=true" >> "$GITHUB_OUTPUT"
else
echo "enabled=false" >> "$GITHUB_OUTPUT"
fi
env:
DOCKER_USER: ${{ secrets.DOCKER_USER }}
DOCKER_PAT: ${{ secrets.DOCKER_PAT }}
# Authenticate to Docker Hub (required for Docker Scout when using GHCR)
# See: https://docs.docker.com/scout/integrations/ci/gha/
- name: Authenticate to Docker Hub
if: steps.docker_hub_check.outputs.enabled == 'true'
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3
with:
username: ${{ secrets.DOCKER_USER }}
password: ${{ secrets.DOCKER_PAT }}
# Validate image before pushing (test-before-push pattern)
# Run Docker Scout CVE scan to ensure image is safe before pushing to registry
# Fails the workflow if critical or high-severity vulnerabilities are found
# Note: continue-on-error allows workflow to proceed if Docker Scout authentication fails
# Note: image input requires a single image reference, so we construct it from registry, image name, and version
- name: Docker Scout CVEs Before Push
uses: docker/scout-action@f8c776824083494ab0d56b8105ba2ca85c86e4de # v1
continue-on-error: true
with:
command: cves
image: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.release_version.outputs.version
}}
only-severities: critical,high
exit-code: 1
github-token: ${{ secrets.GITHUB_TOKEN }}
summary: true
format: json
write-comment: true
# Push validated image to GitHub Container Registry (GHCR) with SBOM and provenance
# Only runs if validation step passed (implicit dependency via step order)
# Rebuild with push enabled to generate and push SBOM/provenance attestations
# This second build will be fast due to BuildKit cache from validation build
- name: Push Validated Image with Attestations
if: success()
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6
timeout-minutes: 5
env:
# Set SOURCE_DATE_EPOCH for reproducible builds
SOURCE_DATE_EPOCH: ${{ steps.source_date.outputs.epoch }}
with:
# Build context directory (current directory)
context: .
# Path to Containerfile (Dockerfile)
file: Containerfile
# Target stage to build (production stage in Containerfile)
target: production
# Push image to GitHub Container Registry (ghcr.io)
push: true
# Don't load into Docker daemon (just push)
load: false
# Hybrid cache: Registry cache (persistent, shared) + GHA cache (fast fallback)
# Registry cache persists across all builds/branches/PRs for better cache hits
# GHA cache provides fast local fallback if registry cache unavailable
cache-from: |
type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache
type=gha
cache-to: |
type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache,mode=max
type=gha,mode=max
# Image tags for identification (semver versions + latest from metadata extraction)
# Multiple tags created: v1.2.3, 1.2, 1, latest (for default branch)
tags: ${{ steps.meta_push.outputs.tags }}
# OCI labels for image metadata (title, description, source, license, etc.)
labels: ${{ steps.meta_push.outputs.labels }}
# OCI annotations for registry UIs (e.g. GHCR package description)
# Using manifest+index annotations for full registry support
annotations: ${{ steps.meta_push.outputs.annotations }}
# Enable SBOM and provenance for supply chain security
# SBOM: Software Bill of Materials for dependency tracking
# Provenance: Build attestations for supply chain security (mode=max includes all metadata)
provenance: mode=max
sbom: true
# Always pull base images to ensure we get latest security updates
pull: true
# Build-time variables passed to Containerfile
build-args: |-
VERSION=${{ steps.release_version.outputs.version }}
GIT_SHA=${{ github.sha }}
BUILD_DATE=${{ steps.build_date.outputs.date }}