Skip to content

Commit

Permalink
workflows: split container builds per-arch
Browse files Browse the repository at this point in the history
Signed-off-by: Patrick Stephens <[email protected]>
  • Loading branch information
patrick-stephens committed Jan 27, 2025
1 parent fb57c6b commit 3aaee2f
Showing 1 changed file with 135 additions and 54 deletions.
189 changes: 135 additions & 54 deletions .github/workflows/call-build-images.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,6 @@ on:
type: string
required: false
default: ""
platforms:
description: The platforms to build for
type: string
required: false
default: 'linux/amd64, linux/arm64, linux/arm/v7, linux/s390x'
secrets:
token:
description: The Github token or similar to authenticate with for the registry.
Expand Down Expand Up @@ -74,25 +69,34 @@ jobs:
replace-with: "$1"
flags: "g"

# This is the intended approach to multi-arch image and all the other checks scanning,
# signing, etc only trigger from this.
call-build-images:
needs:
- call-build-images-meta
name: Multiarch container images to GHCR
runs-on: ubuntu-latest-8-cores
environment: ${{ inputs.environment }}
# Taken from https://docs.docker.com/build/ci/github-actions/multi-platform/#distribute-build-across-multiple-runners
# We split this out to make it easier to restart just one of them if it fails and do all in parallel
call-build-single-arch-container-images:
# Allow us to continue to create a manifest if we want
continue-on-error: true
permissions:
contents: read
packages: write
outputs:
production-digest: ${{ steps.build_push.outputs.digest }}
debug-digest: ${{ steps.debug_build_push.outputs.digest }}
strategy:
fail-fast: false
matrix:
platform:
- amd64
- arm64
- arm/v7
- s390x
target:
- production
- debug
name: ${{ matrix.platform }} container image build for ${{ matrix.target }}
# Use GitHub Actions ARM hosted runners
runs-on: ${{ (contains(matrix.platform, 'arm') && 'ubuntu-22.04-arm') || 'ubuntu-latest' }}
steps:
- name: Checkout code for modern style builds
- name: Checkout code
uses: actions/checkout@v4
with:
ref: ${{ inputs.ref }}
token: ${{ secrets.token }}

- name: Set up QEMU
uses: docker/setup-qemu-action@v3
Expand All @@ -103,30 +107,20 @@ jobs:
- name: Log in to the Container registry
uses: docker/login-action@v3
with:
registry: ${{ inputs.registry }}
username: ${{ inputs.username }}
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.token }}

- name: Extract metadata from Github
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ inputs.registry }}/${{ inputs.image }}
tags: |
raw,${{ inputs.version }}
raw,${{ needs.call-build-images-meta.outputs.major-version }}
raw,latest
- name: Build the production images
id: build_push
- name: Build and push by digest the standard ${{ matrix.target }} image
id: build
uses: docker/build-push-action@v6
with:
# Use path context rather than Git context as we want local files
file: ./dockerfiles/Dockerfile
context: .
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
platforms: ${{ inputs.platforms }}
target: production
target: ${{ matrix.target }}
outputs: type=image,name=${{ inputs.registry }}/${{ inputs.image }},push-by-digest=true,name-canonical=true,push=true
platforms: linux/${{ matrix.platform }}
# Must be disabled to provide legacy format images from the registry
provenance: false
push: true
Expand All @@ -135,6 +129,82 @@ jobs:
FLB_NIGHTLY_BUILD=${{ inputs.unstable }}
RELEASE_VERSION=${{ inputs.version }}
- name: Export ${{ matrix.target }} digest
run: |
mkdir -p /tmp/digests
digest="${{ steps.build.outputs.digest }}"
touch "/tmp/digests/${digest#sha256:}"
shell: bash

- name: Upload ${{ matrix.target }} digest
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.target }}-digests-${{ (contains(matrix.platform, 'arm/v7') && 'arm-v7') || matrix.platform }}
path: /tmp/digests/*
if-no-files-found: error
retention-days: 1

# Take the digests and produce a multi-arch manifest from them.
call-build-container-image-manifests:
permissions:
contents: read
packages: write
name: Upload multi-arch container image manifests
runs-on: ubuntu-latest
needs:
- call-build-images-meta
- call-build-single-arch-container-images
steps:
- name: Extract metadata from Github
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ inputs.registry }}/${{ inputs.image }}
tags: |
raw,${{ inputs.version }}
raw,${{ needs.call-build-images-meta.outputs.major-version }}
raw,latest
- name: Download production digests
uses: actions/download-artifact@v4
with:
pattern: production-digests-*
path: /tmp/production-digests
merge-multiple: true

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

- name: Log in to the Container registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.token }}

- name: Create production manifest
run: |
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
$(printf '${{ inputs.registry }}/${{ inputs.image }}@sha256:%s ' *)
shell: bash
working-directory: /tmp/production-digests

- name: Inspect image
run: |
docker buildx imagetools inspect ${{ inputs.registry }}/${{ inputs.image }}:${{ steps.meta.outputs.version }}
shell: bash

# Take the digests and produce a multi-arch manifest from them.
call-build-debug-container-image-manifests:
permissions:
contents: read
packages: write
name: Upload debug multi-arch container image manifests
runs-on: ubuntu-latest
needs:
- call-build-images-meta
- call-build-single-arch-container-images
steps:
- id: debug-meta
uses: docker/metadata-action@v5
with:
Expand All @@ -144,28 +214,39 @@ jobs:
raw,${{ needs.call-build-images-meta.outputs.major-version }}-debug
raw,latest-debug
- name: Build the debug multi-arch images
id: debug_build_push
uses: docker/build-push-action@v6
- name: Download debug digests
uses: actions/download-artifact@v4
with:
file: ./dockerfiles/Dockerfile
context: .
tags: ${{ steps.debug-meta.outputs.tags }}
labels: ${{ steps.debug-meta.outputs.labels }}
platforms: ${{ inputs.platforms }}
# Must be disabled to provide legacy format images from the registry
provenance: false
target: debug
push: true
load: false
build-args: |
FLB_NIGHTLY_BUILD=${{ inputs.unstable }}
RELEASE_VERSION=${{ inputs.version }}
pattern: production-digests-*
path: /tmp/debug-digests
merge-multiple: true

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

- name: Log in to the Container registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.token }}

- name: Create debug manifest
run: |
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
$(printf '${{ inputs.registry }}/${{ inputs.image }}@sha256:%s ' *)
shell: bash
working-directory: /tmp/debug-digests

- name: Inspect image
run: |
docker buildx imagetools inspect ${{ inputs.registry }}/${{ inputs.image }}:${{ steps.debug-meta.outputs.version }}
shell: bash

call-build-images-generate-schema:
needs:
- call-build-images-meta
- call-build-images
- call-build-container-image-manifests
runs-on: ubuntu-latest
environment: ${{ inputs.environment }}
permissions:
Expand Down Expand Up @@ -195,7 +276,7 @@ jobs:
call-build-images-scan:
needs:
- call-build-images-meta
- call-build-images
- call-build-container-image-manifests
name: Trivy + Dockle image scan
runs-on: ubuntu-latest
environment: ${{ inputs.environment }}
Expand Down Expand Up @@ -230,7 +311,7 @@ jobs:
call-build-images-sign:
needs:
- call-build-images-meta
- call-build-images
- call-build-container-image-manifests
name: Deploy and sign multi-arch container image manifests
permissions:
contents: read
Expand Down

0 comments on commit 3aaee2f

Please sign in to comment.