mirror of
https://github.com/immich-app/devtools.git
synced 2026-09-30 13:23:00 +08:00
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
180 lines
5.9 KiB
YAML
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)
|