Skip to content
Merged
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
97 changes: 97 additions & 0 deletions .github/workflows/buildx.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
name: Build & Push Docker image (GHCR)

on:
push:
branches: [ "main" ]
tags: [ "v*", "release-*" ]
pull_request:
branches: [ "main" ]

permissions:
contents: read
packages: write
attestations: write
id-token: write

env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
PLATFORMS: linux/arm64
DOCKERFILE: dockerfiles/Dockerfile.base
TARGET: archarm
TAG_SUFFIX: minimal-aarch64

jobs:
build:
name: Build${{ github.event_name == 'pull_request' && ' (no push)' || '' }}
runs-on: ubuntu-latest

concurrency:
group: docker-${{ github.ref }}
cancel-in-progress: true

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Set up QEMU (for cross-compiling images)
uses: docker/setup-qemu-action@v3

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Log in to GHCR
if: github.event_name != 'pull_request'
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.CI_TOKEN }}

- name: Derive image name
id: img
run: |
echo "IMAGE=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}" >> $GITHUB_OUTPUT

- name: Extract Docker metadata (tags, labels)
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ steps.img.outputs.IMAGE }}
flavor: |
suffix=-${{ env.TAG_SUFFIX }},onlatest=true
# Tag strategy:
# - main branch -> :latest and :sha
# - tags like v1.2.3 -> :1.2.3 and :1.2 and :1
# - PRs -> :pr-<num>-<sha>
tags: |
type=raw,value=latest,enable={{is_default_branch}}
type=sha,format=short,prefix=,suffix=,enable={{is_default_branch}}
type=ref,event=tag
type=ref,event=pr

- name: Build (and push when not a PR)
id: buildx
uses: docker/build-push-action@v6
with:
context: .
file: ${{ env.DOCKERFILE }}
target: ${{ env.TARGET }}
platforms: ${{ env.PLATFORMS }}
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }} # mirrors: -t $(IMAGE):minimal-aarch64 (+ semver / sha variants)
labels: ${{ steps.meta.outputs.labels }}
# Your local command used --load; in CI we push instead. (--load is single-arch only and not suited for multi-arch CI.)
cache-from: type=gha
cache-to: type=gha,mode=max
provenance: true
sbom: true

# Optional: attest the pushed image (supply chain)
- name: Attest image (SLSA-style)
if: github.event_name != 'pull_request'
uses: actions/attest-build-provenance@v1
with:
subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
subject-digest: ${{ steps.buildx.outputs.digest }}
push-to-registry: true