mirror of
https://github.com/docker/build-push-action.git
synced 2026-01-14 16:23:06 +08:00
Compare commits
2 Commits
05596d50d0
...
af563b8251
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
af563b8251 | ||
|
|
1f530c4b33 |
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
@ -1541,7 +1541,7 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
distribute:
|
distribute:
|
||||||
uses: ./.github/workflows/distribute.yml
|
uses: ./.github/workflows/reusable-distribute.yml
|
||||||
with:
|
with:
|
||||||
push: false
|
push: false
|
||||||
meta-image: user/app
|
meta-image: user/app
|
||||||
|
|||||||
@ -1,4 +1,6 @@
|
|||||||
name: distribute
|
# Reusable workflow to distribute multi-platform builds efficiently
|
||||||
|
# https://docs.docker.com/build/ci/github-actions/multi-platform/#distribute-build-across-multiple-runners
|
||||||
|
name: reusable-distribute
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_call:
|
workflow_call:
|
||||||
@ -14,6 +16,16 @@ on:
|
|||||||
description: "Push image to registry"
|
description: "Push image to registry"
|
||||||
required: false
|
required: false
|
||||||
default: false
|
default: false
|
||||||
|
set-meta-annotations:
|
||||||
|
type: boolean
|
||||||
|
description: "Set metadata-action annotations"
|
||||||
|
required: false
|
||||||
|
default: false
|
||||||
|
set-meta-labels:
|
||||||
|
type: boolean
|
||||||
|
description: "Set metadata-action labels"
|
||||||
|
required: false
|
||||||
|
default: false
|
||||||
setup-qemu:
|
setup-qemu:
|
||||||
type: boolean
|
type: boolean
|
||||||
description: "Install QEMU static binaries"
|
description: "Install QEMU static binaries"
|
||||||
@ -59,7 +71,7 @@ on:
|
|||||||
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, call, context, load, 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)"
|
||||||
@ -166,6 +178,19 @@ on:
|
|||||||
type: string
|
type: string
|
||||||
description: "Ulimit options (e.g., nofile=1024:1024)"
|
description: "Ulimit options (e.g., nofile=1024:1024)"
|
||||||
required: false
|
required: false
|
||||||
|
secrets:
|
||||||
|
login-username:
|
||||||
|
description: 'Username used to log against the Docker registry'
|
||||||
|
required: false
|
||||||
|
login-password:
|
||||||
|
description: "Password or personal access token used to log against the Docker registry"
|
||||||
|
required: false
|
||||||
|
github-token:
|
||||||
|
description: "GitHub Token used to authenticate against a repository for Git context"
|
||||||
|
required: false
|
||||||
|
|
||||||
|
env:
|
||||||
|
ACTIONS_TOOLKIT_VERSION: "0.54.0"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
prepare:
|
prepare:
|
||||||
@ -174,33 +199,42 @@ jobs:
|
|||||||
includes: ${{ steps.set.outputs.includes }}
|
includes: ${{ steps.set.outputs.includes }}
|
||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Validate
|
name: Install npm dependencies
|
||||||
uses: actions/github-script@v7
|
uses: actions/github-script@v7
|
||||||
with:
|
with:
|
||||||
script: |
|
script: |
|
||||||
const metaImage = `${{ inputs.meta-image }}` ? `${{ inputs.meta-image }}`.split(/[\r?\n,]+/).filter(Boolean) : [];
|
await exec.exec('npm', ['install',
|
||||||
if (metaImage.length > 1) {
|
'@docker/actions-toolkit@${{ env.ACTIONS_TOOLKIT_VERSION }}'
|
||||||
throw new Error('Only one meta-image is allowed');
|
]);
|
||||||
}
|
|
||||||
|
|
||||||
const platforms = `${{ inputs.build-platforms }}` ? `${{ inputs.build-platforms }}`.split(/[\r?\n,]+/).filter(Boolean) : [];
|
|
||||||
if (platforms.length > 100) {
|
|
||||||
throw new Error('Too many platforms');
|
|
||||||
} else if (platforms.length <= 1) {
|
|
||||||
throw new Error('At least 2 platforms are required');
|
|
||||||
}
|
|
||||||
core.exportVariable('BUILD_PLATFORMS', platforms.join(','));
|
|
||||||
-
|
-
|
||||||
name: Set includes
|
name: Set includes
|
||||||
id: set
|
id: set
|
||||||
uses: actions/github-script@v7
|
uses: actions/github-script@v7
|
||||||
|
env:
|
||||||
|
INPUT_RUNNER: ${{ inputs.runner }}
|
||||||
|
INPUT_META-IMAGE: ${{ inputs.meta-image }}
|
||||||
|
INPUT_BUILD-PLATFORMS: ${{ inputs.build-platforms }}
|
||||||
|
GITHUB_TOKEN: ${{ secrets.github-token || github.token }}
|
||||||
with:
|
with:
|
||||||
script: |
|
script: |
|
||||||
|
const { Util } = require('@docker/actions-toolkit/lib/util');
|
||||||
|
|
||||||
|
if (Util.getInputList('meta-image').length > 1) {
|
||||||
|
throw new Error('Only one meta-image is allowed');
|
||||||
|
}
|
||||||
|
|
||||||
|
const inpRunner = core.getInput('runner');
|
||||||
|
const inpBuildPlatforms = Util.getInputList('build-platforms');
|
||||||
|
if (inpBuildPlatforms.length > 100) {
|
||||||
|
throw new Error('Too many platforms');
|
||||||
|
} else if (inpBuildPlatforms.length <= 1) {
|
||||||
|
throw new Error('At least 2 platforms are required');
|
||||||
|
}
|
||||||
|
|
||||||
await core.group(`Set includes`, async () => {
|
await core.group(`Set includes`, async () => {
|
||||||
const platforms = `${{ env.BUILD_PLATFORMS }}`.split(',');
|
|
||||||
let includes = [];
|
let includes = [];
|
||||||
platforms.forEach((platform, index) => {
|
inpBuildPlatforms.forEach((platform, index) => {
|
||||||
let runner = `${{ inputs.runner }}`;
|
let runner = inpRunner;
|
||||||
if (runner === 'auto') {
|
if (runner === 'auto') {
|
||||||
runner = platform.startsWith('linux/arm') ? 'ubuntu-24.04-arm' : 'ubuntu-latest';
|
runner = platform.startsWith('linux/arm') ? 'ubuntu-24.04-arm' : 'ubuntu-latest';
|
||||||
}
|
}
|
||||||
@ -342,7 +376,7 @@ jobs:
|
|||||||
if: ${{ inputs.push }}
|
if: ${{ inputs.push }}
|
||||||
with:
|
with:
|
||||||
registry: ${{ inputs.login-registry }}
|
registry: ${{ inputs.login-registry }}
|
||||||
username: ${{ inputs.login-username }}
|
username: ${{ inputs.login-username || secrets.login-username }}
|
||||||
password: ${{ secrets.login-password }}
|
password: ${{ secrets.login-password }}
|
||||||
-
|
-
|
||||||
name: Set up QEMU
|
name: Set up QEMU
|
||||||
@ -353,6 +387,31 @@ jobs:
|
|||||||
-
|
-
|
||||||
name: Set up Docker Buildx
|
name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@v3
|
uses: docker/setup-buildx-action@v3
|
||||||
|
-
|
||||||
|
name: Set build inputs
|
||||||
|
id: build-inputs
|
||||||
|
uses: actions/github-script@v7
|
||||||
|
env:
|
||||||
|
INPUT_SET-META-ANNOTATIONS: ${{ inputs.set-meta-annotations }}
|
||||||
|
INPUT_SET-META-LABELS: ${{ inputs.set-meta-labels }}
|
||||||
|
INPUT_BUILD-ANNOTATIONS: ${{ inputs.build-annotations }}
|
||||||
|
INPUT_BUILD-LABELS: ${{ inputs.build-labels }}
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
const inpSetMetaAnnotations = core.getBooleanInput('set-meta-annotations');
|
||||||
|
const inpSetMetaLabels = core.getBooleanInput('set-meta-labels');
|
||||||
|
|
||||||
|
let inpBuildAnnotations = core.getInput('build-annotations');
|
||||||
|
if (inpSetMetaAnnotations) {
|
||||||
|
inpBuildAnnotations += `\n${{ steps.meta.outputs.annotations }}`;
|
||||||
|
}
|
||||||
|
let inpBuildLabels = core.getInput('build-labels');
|
||||||
|
if (inpSetMetaLabels) {
|
||||||
|
inpBuildLabels += `\n${{ steps.meta.outputs.labels }}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
core.setOutput('annotations', inpBuildAnnotations);
|
||||||
|
core.setOutput('labels', inpBuildLabels);
|
||||||
-
|
-
|
||||||
name: Build
|
name: Build
|
||||||
id: build
|
id: build
|
||||||
@ -360,9 +419,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
add-hosts: ${{ inputs.build-add-hosts }}
|
add-hosts: ${{ inputs.build-add-hosts }}
|
||||||
allow: ${{ inputs.build-allow }}
|
allow: ${{ inputs.build-allow }}
|
||||||
annotations: |
|
annotations: ${{ steps.build-inputs.outputs.annotations }}
|
||||||
${{ steps.meta.outputs.annotations }}
|
|
||||||
${{ inputs.build-annotations }}
|
|
||||||
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 }}
|
||||||
@ -371,9 +428,7 @@ jobs:
|
|||||||
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: |
|
labels: ${{ steps.build-inputs.outputs.labels }}
|
||||||
${{ steps.meta.outputs.labels }}
|
|
||||||
${{ inputs.build-labels }}
|
|
||||||
network: ${{ inputs.build-network }}
|
network: ${{ inputs.build-network }}
|
||||||
no-cache: ${{ inputs.build-no-cache }}
|
no-cache: ${{ inputs.build-no-cache }}
|
||||||
no-cache-filters: ${{ inputs.build-no-cache-filters }}
|
no-cache-filters: ${{ inputs.build-no-cache-filters }}
|
||||||
@ -415,15 +470,13 @@ jobs:
|
|||||||
images: ${{ inputs.meta-image }}
|
images: ${{ inputs.meta-image }}
|
||||||
tags: ${{ inputs.meta-tags }}
|
tags: ${{ inputs.meta-tags }}
|
||||||
flavor: ${{ inputs.meta-flavor }}
|
flavor: ${{ inputs.meta-flavor }}
|
||||||
labels: ${{ inputs.meta-labels }}
|
|
||||||
annotations: ${{ inputs.meta-annotations }}
|
|
||||||
-
|
-
|
||||||
name: Login to registry
|
name: Login to registry
|
||||||
uses: docker/login-action@v3
|
uses: docker/login-action@v3
|
||||||
if: ${{ inputs.push }}
|
if: ${{ inputs.push }}
|
||||||
with:
|
with:
|
||||||
registry: ${{ inputs.login-registry }}
|
registry: ${{ inputs.login-registry }}
|
||||||
username: ${{ inputs.login-username }}
|
username: ${{ inputs.login-username || secrets.login-username }}
|
||||||
password: ${{ secrets.login-password }}
|
password: ${{ secrets.login-password }}
|
||||||
-
|
-
|
||||||
name: Set up Docker Buildx
|
name: Set up Docker Buildx
|
||||||
@ -432,8 +485,14 @@ jobs:
|
|||||||
-
|
-
|
||||||
name: Create manifest list
|
name: Create manifest list
|
||||||
uses: actions/github-script@v7
|
uses: actions/github-script@v7
|
||||||
|
env:
|
||||||
|
INPUT_PUSH: ${{ inputs.push }}
|
||||||
|
INPUT_META-IMAGE: ${{ inputs.meta-image }}
|
||||||
with:
|
with:
|
||||||
script: |
|
script: |
|
||||||
|
const inpPush = core.getBooleanInput('push');
|
||||||
|
const inpMetaImage = core.getInput('meta-image');
|
||||||
|
|
||||||
let digests = [];
|
let digests = [];
|
||||||
await core.group(`Digests`, async () => {
|
await core.group(`Digests`, async () => {
|
||||||
digests = Object.values(JSON.parse(`${{ toJSON(needs.build.outputs) }}`));
|
digests = Object.values(JSON.parse(`${{ toJSON(needs.build.outputs) }}`));
|
||||||
@ -451,10 +510,10 @@ jobs:
|
|||||||
createArgs.push(`-t`, tag);
|
createArgs.push(`-t`, tag);
|
||||||
}
|
}
|
||||||
for (const digest of digests) {
|
for (const digest of digests) {
|
||||||
createArgs.push(`${{ inputs.meta-image }}@${digest}`);
|
createArgs.push(`${inpMetaImage}@${digest}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (${{ inputs.push }}) {
|
if (inpPush) {
|
||||||
if (tags.length === 0) {
|
if (tags.length === 0) {
|
||||||
throw new Error('No tags to create manifest list');
|
throw new Error('No tags to create manifest list');
|
||||||
}
|
}
|
||||||
@ -466,7 +525,7 @@ jobs:
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
await core.group(`Inspect image`, async () => {
|
await core.group(`Inspect image`, async () => {
|
||||||
await exec.getExecOutput('docker', ['buildx', 'imagetools', 'inspect', `${{ inputs.meta-image }}:${tags[0]}`], {
|
await exec.getExecOutput('docker', ['buildx', 'imagetools', 'inspect', `${inpMetaImage}:${tags[0]}`], {
|
||||||
ignoreReturnCode: true
|
ignoreReturnCode: true
|
||||||
}).then(res => {
|
}).then(res => {
|
||||||
if (res.stderr.length > 0 && res.exitCode != 0) {
|
if (res.stderr.length > 0 && res.exitCode != 0) {
|
||||||
Loading…
x
Reference in New Issue
Block a user