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
108 changes: 97 additions & 11 deletions .github/workflows/docker-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,36 +11,122 @@ env:

jobs:
build:
runs-on: ubuntu-latest
# We use a matrix to run each docker container build for a specific platform on it's own native runner.
# This avoids using virtualization and massively speeds up builds.
strategy:
matrix:
platform: [linux/amd64, linux/arm64]
include:
- platform: linux/amd64
runner: ubuntu-latest
- platform: linux/arm64
runner: ubuntu-24.04-arm


name: Build ${{ matrix.platform }}
runs-on: ${{ matrix.runner }}
steps:
- name: Checkout
- name: Code checkout
uses: actions/checkout@v4

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

- name: Get source version
run: echo "SOURCE_VERSION=$(grep VERSION compose.yaml | awk {'print $2'})" >> "$GITHUB_ENV"
run: echo "SOURCE_VERSION=$(grep VERSION compose.yaml | awk '{print $2}')" >> "$GITHUB_ENV"

- name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
flavor: |
latest=false
tags: |
type=ref,event=branch
type=semver,pattern={{version}}
- name: Login to registry ${{ env.REGISTRY }}
type=ref,event=branch,pattern={{branch}}
type=semver,pattern={{version}},value=${{ env.SOURCE_VERSION }}

- name: Derive arch-suffixed tags as output
id: archtags
run: |
set -euo pipefail
ARCH="$(echo '${{ matrix.platform }}' | cut -d/ -f2)"
T="$(printf '%s\n' "${{ steps.meta.outputs.tags }}" | sed "s/$/-${ARCH}/")"
{
echo 'tags<<EOF'
echo "$T"
echo 'EOF'
echo "arch=$ARCH"
} >> "$GITHUB_OUTPUT"

- name: Login to ${{ env.REGISTRY }}
if: github.event_name != 'pull_request'
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build and push
uses: docker/build-push-action@v5

- name: Build & push ${{ matrix.platform }}
uses: docker/build-push-action@v6
with:
context: .
platforms: ${{ matrix.platform }}
push: ${{ github.event_name != 'pull_request' }}
build-args: |
VERSION=${{ env.SOURCE_VERSION }}
platforms: linux/amd64,linux/arm64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
tags: ${{ steps.archtags.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}

# In order to have a single tag that covers both archtectures we run one more job to create a multi-arch manifest
# under a single tag.
manifest:
name: Create multi-arch manifest
runs-on: ubuntu-latest
needs: build
steps:
- name: Code checkout
uses: actions/checkout@v4

- name: Get source version
run: echo "SOURCE_VERSION=$(grep VERSION compose.yaml | awk '{print $2}')" >> "$GITHUB_ENV"

- name: Docker meta (same base tags)
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
flavor: |
latest=false
tags: |
type=ref,event=branch,pattern={{branch}}
type=semver,pattern={{version}},value=${{ env.SOURCE_VERSION }}

- name: Login
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}

- name: Create manifest for each base tag
if: github.event_name != 'pull_request'
run: |
set -euo pipefail
while IFS= read -r BASE; do
echo "Preparing manifest for $BASE"
AMD="${BASE}-amd64"
ARM="${BASE}-arm64"
# Skip if one arch is missing
docker buildx imagetools inspect "$AMD"
docker buildx imagetools inspect "$ARM"

docker buildx imagetools create \
--tag "$BASE" \
"$AMD" \
"$ARM"

echo "OK: $BASE now points to $AMD + $ARM"
done <<'EOF'
${{ steps.meta.outputs.tags }}
EOF
Loading