Files
devtools/.github/workflows/multi-runner-build.yml
T
Workflow config file is invalid. Please check your config file: getMatrixes: matrix include must be a list of mappings
renovate[bot] 6660072571 chore(deps): update astral-sh/setup-uv action to v10 (#1943)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-09-08 08:53:02 +00:00

180 lines
5.9 KiB
YAML

name: 'Multi-runner container image build'
on:
workflow_call:
inputs:
image:
description: 'Name of the image'
type: string
required: true
context:
description: 'Path to build context'
type: string
required: true
dockerfile:
description: 'Path to Dockerfile'
type: string
required: true
suffixes:
description: 'Comma-separated list of suffixes to append to the image tag'
type: string
default: ''
tags:
description: 'Tag rules for the image, in docker/metadata-action format'
type: string
required: true
build-args:
description: 'Docker build arguments'
type: string
required: false
platforms:
description: 'Platforms to build for'
type: string
runner-mapping:
description: 'Mapping from platforms to runners'
type: string
target:
description: 'Sets the target stage to build'
type: string
secrets:
GITHUB_APP_TOKEN:
required: false
env:
GHCR_IMAGE: ghcr.io/${{ github.repository_owner }}/${{ inputs.image }}
jobs:
matrix:
name: 'Generate matrix'
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.matrix.outputs.matrix }}
key: ${{ steps.artifact-key.outputs.base }}
steps:
- name: Generate build matrix
id: matrix
shell: bash
env:
PLATFORMS: ${{ inputs.platforms || 'linux/amd64,linux/arm64' }}
RUNNER_MAPPING: ${{ inputs.runner-mapping || '{"linux/amd64":"ubuntu-latest","linux/arm64":"ubuntu-24.04-arm"}' }}
run: |
matrix=$(jq -R -c \
--argjson runner_mapping "${RUNNER_MAPPING}" \
'split(",") | map({platform: ., runner: $runner_mapping[.]})' \
<<< "${PLATFORMS}")
echo "matrix=${matrix}" | tee -a $GITHUB_OUTPUT
- name: Determine artifact key
id: artifact-key
shell: bash
env:
IMAGE: ${{ inputs.image }}
SUFFIXES: ${{ inputs.suffixes }}
run: |
# Replace commas with hyphens for the artifact key
suffix_key=$(echo "$SUFFIXES" | tr ',' '-')
base="${IMAGE}${suffix_key}-digests"
echo "base=${base}" | tee -a $GITHUB_OUTPUT
build:
needs: matrix
runs-on: ${{ matrix.runner }}
strategy:
fail-fast: false
matrix:
include: ${{ fromJson(needs.matrix.outputs.matrix) }}
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
token: ${{ secrets.GITHUB_APP_TOKEN || github.token }}
- uses: immich-app/devtools/actions/image-build@236702d8cb0c9dd1ff155b73f9be789b1b2cd620 # image-build-action-v0.1.10
with:
context: ${{ inputs.context }}
dockerfile: ${{ inputs.dockerfile }}
image: ${{ env.GHCR_IMAGE }}
ghcr-token: ${{ secrets.GITHUB_APP_TOKEN || github.token }}
platform: ${{ matrix.platform }}
artifact-key-base: ${{ needs.matrix.outputs.key }}
build-args: ${{ inputs.build-args }}
target: ${{ inputs.target }}
merge:
needs: [matrix, build]
runs-on: ubuntu-latest
if: ${{ !github.event.pull_request.head.repo.fork }}
steps:
- name: Install uv
uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
- name: Download digests
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
path: ${{ runner.temp }}/digests
pattern: ${{ needs.matrix.outputs.key }}-*
merge-multiple: true
github-token: ${{ secrets.GITHUB_APP_TOKEN || github.token }}
- name: Login to GHCR
uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_APP_TOKEN || github.token }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@37fe631027851001ddb9b187196cc803df7f5f0e # v4.3.0
- name: Generate docker image tags
id: meta
uses: docker/metadata-action@dc802804100637a589fabce1cb79ff13a1411302 # v6.2.0
env:
DOCKER_METADATA_PR_HEAD_SHA: 'true'
with:
flavor: |
# Disable latest tag
latest=false
images: ${{ env.GHCR_IMAGE }}
tags: ${{ inputs.tags }}
- name: Create manifest list and push
working-directory: ${{ runner.temp }}/digests
env:
SUFFIXES: ${{ inputs.suffixes }}
shell: uv run --script {0}
run: |
# /// script
# requires-python = ">=3.11"
# dependencies = [
# "python-on-whales>=0.80.0",
# ]
# ///
from python_on_whales import docker
import json
import os
docker_args = {"annotations": {}, "tags": [], "sources": []}
metadata_json = json.loads(os.environ.get("DOCKER_METADATA_OUTPUT_JSON", "{}"))
annotations = metadata_json.get("annotations", [])
for annotation in annotations:
annotation = annotation.replace("manifest:", "index:")
key, value = annotation.split("=", 1)
docker_args["annotations"][key] = value
tags = metadata_json.get("tags", [])
suffixes = os.environ.get("SUFFIXES").split(",")
print(f"{suffixes=}")
for suffix in suffixes:
for tag in tags:
docker_args["tags"].append(f"{tag}{suffix}")
ghcr_image = os.environ['GHCR_IMAGE']
digests = os.listdir(".")
docker_args["sources"] = [f"{ghcr_image}@sha256:{digest}" for digest in digests]
print(json.dumps(docker_args))
docker.buildx.imagetools.create(**docker_args)