Compare commits

..

2 Commits

Author SHA1 Message Date
CrazyMax
62a971216d
Merge 1f530c4b33bad46319ebd036f33c1e16e180e011 into 471d1dc4e07e5cdedd4c2171150001c434f0b7a4 2025-02-26 15:49:59 +01:00
CrazyMax
1f530c4b33
reusable workflow to distribute multi-platform builds
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2025-02-17 16:18:33 +01:00
3 changed files with 38 additions and 146 deletions

View File

@ -1544,21 +1544,10 @@ jobs:
fi fi
distribute: distribute:
uses: ./.github/workflows/reusable-distribute-mp.yml uses: ./.github/workflows/reusable-distribute.yml
with: with:
push: false push: false
meta-image: user/app meta-image: user/app
build-context: "{{defaultContext}}:test" build-context: "{{defaultContext}}:test"
build-file: multi.Dockerfile build-file: multi.Dockerfile
build-platforms: linux/amd64,linux/arm64 build-platforms: linux/amd64,linux/arm64
distribute-cache:
uses: ./.github/workflows/reusable-distribute-mp.yml
with:
push: false
cache: true
cache-scope: multi
meta-image: user/app
build-context: "{{defaultContext}}:test"
build-file: multi.Dockerfile
build-platforms: linux/amd64,linux/arm64

View File

@ -1,6 +1,6 @@
# Reusable workflow to distribute multi-platform builds efficiently # Reusable workflow to distribute multi-platform builds efficiently
# https://docs.docker.com/build/ci/github-actions/multi-platform/#distribute-build-across-multiple-runners # https://docs.docker.com/build/ci/github-actions/multi-platform/#distribute-build-across-multiple-runners
name: reusable-distribute-mp name: reusable-distribute
on: on:
workflow_call: workflow_call:
@ -16,20 +16,6 @@ on:
description: "Push image to registry" description: "Push image to registry"
required: false required: false
default: false default: false
cache:
type: boolean
description: "Enable cache to GitHub Actions cache backend"
required: false
default: false
cache-scope:
type: string
description: "Which scope cache object belongs to if cache enabled (default is target name)"
required: false
cache-mode:
type: string
description: "Cache layers to export if cache enabled (min or max)"
required: false
default: 'min'
set-meta-annotations: set-meta-annotations:
type: boolean type: boolean
description: "Set metadata-action annotations" description: "Set metadata-action annotations"
@ -52,66 +38,40 @@ on:
required: true required: true
meta-tags: meta-tags:
type: string type: string
description: "List of tags as key-value pair attributes" description: 'List of tags as key-value pair attributes'
required: false required: false
meta-flavor: meta-flavor:
type: string type: string
description: "Flavors to apply" description: 'Flavors to apply'
required: false required: false
meta-labels: meta-labels:
type: string type: string
description: "List of custom labels" description: 'List of custom labels'
required: false required: false
meta-annotations: meta-annotations:
type: string type: string
description: "List of custom annotations" description: 'List of custom annotations'
required: false
# same as docker/setup-buildx-action inputs (minus driver, install, use, endpoint, append, cleanup)
buildx-version:
type: string
description: "Buildx version. (eg. v0.3.0)"
required: false
buildx-cache-binary:
type: boolean
description: "Cache buildx binary to GitHub Actions cache backend"
default: true
required: false
buildx-driver-opts:
type: string
description: "List of additional docker-container options. (eg. image=moby/buildkit:master)"
required: false
buildkitd-flags:
type: string
description: "BuildKit daemon flags"
required: false
buildkitd-config:
type: string
description: "BuildKit daemon config file"
required: false
buildkitd-config-inline:
type: string
description: "Inline BuildKit daemon config"
required: false required: false
# same as docker/login-action inputs (minus logout) # same as docker/login-action inputs (minus logout)
login-registry: login-registry:
type: string type: string
description: "Server address of Docker registry. If not set then will default to Docker Hub" description: 'Server address of Docker registry. If not set then will default to Docker Hub'
required: false required: false
login-username: login-username:
type: string type: string
description: "Username used to log against the Docker registry" description: 'Username used to log against the Docker registry'
required: false required: false
login-ecr: login-ecr:
type: string type: string
description: "Specifies whether the given registry is ECR (auto, true or false)" description: 'Specifies whether the given registry is ECR (auto, true or false)'
default: 'auto' default: 'auto'
required: false required: false
# same as docker/setup-qemu-action inputs (minus platforms, cache-image) # same as docker/setup-qemu-action inputs (minus platforms, cache-image)
qemu-image: qemu-image:
type: string type: string
description: "QEMU static binaries Docker image (e.g. tonistiigi/binfmt:latest)" description: 'QEMU static binaries Docker image (e.g. tonistiigi/binfmt:latest)'
required: false required: false
# same as docker/build-push-action inputs (minus builder, cache-from, cache-to, call, load, no-cache, no-cache-filters, outputs, platforms, push, tags) # same as docker/build-push-action inputs (minus builder, call, load, outputs, platforms, push, tags)
build-add-hosts: build-add-hosts:
type: string type: string
description: "List of a customs host-to-IP mapping (e.g., docker:10.180.0.1)" description: "List of a customs host-to-IP mapping (e.g., docker:10.180.0.1)"
@ -132,6 +92,14 @@ on:
type: string type: string
description: "List of build-time variables" description: "List of build-time variables"
required: false required: false
build-cache-from:
type: string
description: "List of external cache sources for buildx (e.g., user/app:cache, type=local,src=path/to/dir)"
required: false
build-cache-to:
type: string
description: "List of cache export destinations for buildx (e.g., user/app:cache, type=local,dest=path/to/dir)"
required: false
build-cgroup-parent: build-cgroup-parent:
type: string type: string
description: "Optional parent cgroup for the container used in the build" description: "Optional parent cgroup for the container used in the build"
@ -156,6 +124,15 @@ on:
type: string type: string
description: "Set the networking mode for the RUN instructions during build" description: "Set the networking mode for the RUN instructions during build"
required: false required: false
build-no-cache:
type: boolean
description: "Do not use cache when building the image"
required: false
default: false
build-no-cache-filters:
type: string
description: "Do not cache specified stages"
required: false
build-platforms: build-platforms:
type: string type: string
description: "List of target platforms for build" description: "List of target platforms for build"
@ -213,7 +190,7 @@ on:
required: false required: false
env: env:
ACTIONS_TOOLKIT_VERSION: "0.56.0" ACTIONS_TOOLKIT_VERSION: "0.54.0"
jobs: jobs:
prepare: prepare:
@ -271,57 +248,10 @@ jobs:
core.setOutput('includes', JSON.stringify(includes)); core.setOutput('includes', JSON.stringify(includes));
}); });
warmup:
runs-on: ${{ inputs.runner == 'auto' && 'ubuntu-latest' || inputs.runner }}
steps:
-
name: Set up QEMU
uses: docker/setup-qemu-action@v3
if: ${{ inputs.setup-qemu }}
with:
image: ${{ inputs.qemu-image }}
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
version: ${{ inputs.buildx-version }}
driver-opts: ${{ inputs.buildx-driver-opts }}
buildkitd-flags: ${{ inputs.buildkitd-flags }}
buildkitd-config: ${{ inputs.buildkitd-config }}
buildkitd-config-inline: ${{ inputs.buildkitd-config-inline }}
cache-binary: ${{ inputs.buildx-cache-binary }}
-
name: Warm up cache
uses: docker/build-push-action@v6
if: ${{ inputs.cache }}
with:
add-hosts: ${{ inputs.build-add-hosts }}
allow: ${{ inputs.build-allow }}
build-args: ${{ inputs.build-build-args }}
build-contexts: ${{ inputs.build-contexts }}
cache-from: type=gha,scope=${{ inputs.cache-scope || inputs.target || 'buildkit' }}-warmup
cache-to: type=gha,scope=${{ inputs.cache-scope || inputs.target || 'buildkit' }}-warmup,mode=${{ inputs.cache-mode }}
cgroup-parent: ${{ inputs.build-cgroup-parent }}
context: ${{ inputs.build-context }}
file: ${{ inputs.build-file }}
labels: ${{ steps.build-inputs.outputs.labels }}
network: ${{ inputs.build-network }}
outputs: type=cacheonly
pull: ${{ inputs.build-pull }}
secrets: ${{ inputs.build-secrets }}
secret-envs: ${{ inputs.build-secret-envs }}
secret-files: ${{ inputs.build-secret-files }}
shm-size: ${{ inputs.build-shm-size }}
ssh: ${{ inputs.build-ssh }}
target: ${{ inputs.build-target }}
ulimit: ${{ inputs.build-ulimit }}
github-token: ${{ secrets.github-token || github.token }}
build: build:
runs-on: ${{ matrix.runner }} runs-on: ${{ matrix.runner }}
needs: needs:
- prepare - prepare
- warmup
outputs: outputs:
# needs predefined outputs as we can't use dynamic ones atm: https://github.com/actions/runner/pull/2477 # needs predefined outputs as we can't use dynamic ones atm: https://github.com/actions/runner/pull/2477
# 100 is the maximum number of platforms supported by the matrix strategy # 100 is the maximum number of platforms supported by the matrix strategy
@ -457,50 +387,30 @@ jobs:
- -
name: Set up Docker Buildx name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3 uses: docker/setup-buildx-action@v3
with:
version: ${{ inputs.buildx-version }}
driver-opts: ${{ inputs.buildx-driver-opts }}
buildkitd-flags: ${{ inputs.buildkitd-flags }}
buildkitd-config: ${{ inputs.buildkitd-config }}
buildkitd-config-inline: ${{ inputs.buildkitd-config-inline }}
cache-binary: ${{ inputs.buildx-cache-binary }}
- -
name: Set build inputs name: Set build inputs
id: build-inputs id: build-inputs
uses: actions/github-script@v7 uses: actions/github-script@v7
env: env:
PLATFORM: ${{ matrix.platform }}
INPUT_CACHE: ${{ inputs.cache }}
INPUT_CACHE-SCOPE: ${{ inputs.cache-scope }}
INPUT_CACHE-MODE: ${{ inputs.cache-mode }}
INPUT_SET-META-ANNOTATIONS: ${{ inputs.set-meta-annotations }} INPUT_SET-META-ANNOTATIONS: ${{ inputs.set-meta-annotations }}
INPUT_SET-META-LABELS: ${{ inputs.set-meta-labels }} INPUT_SET-META-LABELS: ${{ inputs.set-meta-labels }}
INPUT_BUILD-ANNOTATIONS: ${{ inputs.build-annotations }} INPUT_BUILD-ANNOTATIONS: ${{ inputs.build-annotations }}
INPUT_BUILD-LABELS: ${{ inputs.build-labels }} INPUT_BUILD-LABELS: ${{ inputs.build-labels }}
INPUT_BUILD-TARGET: ${{ inputs.build-target }}
with: with:
script: | script: |
const platformPair = process.env.PLATFORM.replace(/\//g, '-');
const inpCache = core.getBooleanInput('cache');
const inpCacheScope = core.getInput('cache-scope');
const inpCacheMode = core.getInput('cache-mode');
const inpSetMetaAnnotations = core.getBooleanInput('set-meta-annotations'); const inpSetMetaAnnotations = core.getBooleanInput('set-meta-annotations');
const inpSetMetaLabels = core.getBooleanInput('set-meta-labels'); const inpSetMetaLabels = core.getBooleanInput('set-meta-labels');
let inpBuildAnnotations = core.getInput('build-annotations');
let inpBuildLabels = core.getInput('build-labels');
const inpBuildTarget = core.getInput('build-target');
if (inpCache) { let inpBuildAnnotations = core.getInput('build-annotations');
core.setOutput('cache-from', `type=gha,scope=${inpCacheScope || inpTarget || 'buildkit'}-warmup\ntype=gha,scope=${inpCacheScope || inpTarget}-${platformPair}`);
core.setOutput('cache-to', `type=gha,scope=${inpCacheScope || inpTarget || 'buildkit'}-${platformPair},mode=${inpCacheMode}`);
}
if (inpSetMetaAnnotations) { if (inpSetMetaAnnotations) {
inpBuildAnnotations += `\n${{ steps.meta.outputs.annotations }}`; inpBuildAnnotations += `\n${{ steps.meta.outputs.annotations }}`;
} }
core.setOutput('annotations', inpBuildAnnotations); let inpBuildLabels = core.getInput('build-labels');
if (inpSetMetaLabels) { if (inpSetMetaLabels) {
inpBuildLabels += `\n${{ steps.meta.outputs.labels }}`; inpBuildLabels += `\n${{ steps.meta.outputs.labels }}`;
} }
core.setOutput('annotations', inpBuildAnnotations);
core.setOutput('labels', inpBuildLabels); core.setOutput('labels', inpBuildLabels);
- -
name: Build name: Build
@ -513,13 +423,15 @@ jobs:
attests: ${{ inputs.build-attests }} attests: ${{ inputs.build-attests }}
build-args: ${{ inputs.build-build-args }} build-args: ${{ inputs.build-build-args }}
build-contexts: ${{ inputs.build-contexts }} build-contexts: ${{ inputs.build-contexts }}
cache-from: ${{ steps.build-inputs.outputs.cache-from }} cache-from: ${{ inputs.build-cache-from }}
cache-to: ${{ steps.build-inputs.outputs.cache-to }} cache-to: ${{ inputs.build-cache-to }}
cgroup-parent: ${{ inputs.build-cgroup-parent }} cgroup-parent: ${{ inputs.build-cgroup-parent }}
context: ${{ inputs.build-context }} context: ${{ inputs.build-context }}
file: ${{ inputs.build-file }} file: ${{ inputs.build-file }}
labels: ${{ steps.build-inputs.outputs.labels }} labels: ${{ steps.build-inputs.outputs.labels }}
network: ${{ inputs.build-network }} network: ${{ inputs.build-network }}
no-cache: ${{ inputs.build-no-cache }}
no-cache-filters: ${{ inputs.build-no-cache-filters }}
outputs: | outputs: |
type=image,"name=${{ inputs.meta-image }}",push-by-digest=true,name-canonical=true,push=${{ inputs.push }} type=image,"name=${{ inputs.meta-image }}",push-by-digest=true,name-canonical=true,push=${{ inputs.push }}
platforms: ${{ matrix.platform }} platforms: ${{ matrix.platform }}
@ -533,7 +445,6 @@ jobs:
ssh: ${{ inputs.build-ssh }} ssh: ${{ inputs.build-ssh }}
target: ${{ inputs.build-target }} target: ${{ inputs.build-target }}
ulimit: ${{ inputs.build-ulimit }} ulimit: ${{ inputs.build-ulimit }}
github-token: ${{ secrets.github-token || github.token }}
- -
name: Set digest output name: Set digest output
id: digest id: digest
@ -570,13 +481,7 @@ jobs:
- -
name: Set up Docker Buildx name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3 uses: docker/setup-buildx-action@v3
with: if: ${{ inputs.push }}
version: ${{ inputs.buildx-version }}
driver-opts: ${{ inputs.buildx-driver-opts }}
buildkitd-flags: ${{ inputs.buildkitd-flags }}
buildkitd-config: ${{ inputs.buildkitd-config }}
buildkitd-config-inline: ${{ inputs.buildkitd-config-inline }}
cache-binary: ${{ inputs.buildx-cache-binary }}
- -
name: Create manifest list name: Create manifest list
uses: actions/github-script@v7 uses: actions/github-script@v7

View File

@ -156,7 +156,6 @@ jobs:
## Examples ## Examples
* [Multi-platform image](https://docs.docker.com/build/ci/github-actions/multi-platform/) * [Multi-platform image](https://docs.docker.com/build/ci/github-actions/multi-platform/)
* [Distribute multi-platform build across runners](https://docs.docker.com/build/ci/github-actions/multi-platform/#distribute-multi-platform-build-across-runners)
* [Secrets](https://docs.docker.com/build/ci/github-actions/secrets/) * [Secrets](https://docs.docker.com/build/ci/github-actions/secrets/)
* [Push to multi-registries](https://docs.docker.com/build/ci/github-actions/push-multi-registries/) * [Push to multi-registries](https://docs.docker.com/build/ci/github-actions/push-multi-registries/)
* [Manage tags and labels](https://docs.docker.com/build/ci/github-actions/manage-tags-labels/) * [Manage tags and labels](https://docs.docker.com/build/ci/github-actions/manage-tags-labels/)
@ -171,7 +170,6 @@ jobs:
* [SBOM and provenance attestations](https://docs.docker.com/build/ci/github-actions/attestations/) * [SBOM and provenance attestations](https://docs.docker.com/build/ci/github-actions/attestations/)
* [Annotations](https://docs.docker.com/build/ci/github-actions/annotations/) * [Annotations](https://docs.docker.com/build/ci/github-actions/annotations/)
* [Reproducible builds](https://docs.docker.com/build/ci/github-actions/reproducible-builds/) * [Reproducible builds](https://docs.docker.com/build/ci/github-actions/reproducible-builds/)
* [Build checks](https://docs.docker.com/build/ci/github-actions/checks/#run-checks-with-dockerbuild-push-action)
## Summaries ## Summaries