mirror of
https://github.com/docker/build-push-action.git
synced 2026-07-01 12:01:38 +00:00
Compare commits
21 Commits
77c42afd59
...
849fc78eb6
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
849fc78eb6 | ||
|
|
805f538ac7 | ||
|
|
eb14fefafa | ||
|
|
94f8f8c2ee | ||
|
|
22f4433c58 | ||
|
|
6721c56015 | ||
|
|
4367da978b | ||
|
|
0883ebe52d | ||
|
|
76e5c2d6ea | ||
|
|
29d67824d8 | ||
|
|
c382f710d3 | ||
|
|
5a5b70d974 | ||
|
|
dc24cf9e25 | ||
|
|
667cb22c52 | ||
|
|
d880b1964b | ||
|
|
e51051ad0b | ||
|
|
86c2bd0031 | ||
|
|
268d2b1611 | ||
|
|
2b8dc7f529 | ||
|
|
840c12be17 | ||
|
|
26368743c0 |
23
.github/workflows/ci.yml
vendored
23
.github/workflows/ci.yml
vendored
@ -1344,3 +1344,26 @@ jobs:
|
||||
name: Check docker
|
||||
run: |
|
||||
docker image inspect localhost:5000/name/app:latest
|
||||
|
||||
disable-summary:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
path: action
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
with:
|
||||
version: ${{ inputs.buildx-version || env.BUILDX_VERSION }}
|
||||
driver-opts: |
|
||||
image=${{ inputs.buildkit-image || env.BUILDKIT_IMAGE }}
|
||||
-
|
||||
name: Build
|
||||
uses: ./action
|
||||
with:
|
||||
file: ./test/Dockerfile
|
||||
env:
|
||||
DOCKER_BUILD_NO_SUMMARY: true
|
||||
|
||||
2
.github/workflows/test.yml
vendored
2
.github/workflows/test.yml
vendored
@ -20,7 +20,7 @@ jobs:
|
||||
uses: actions/checkout@v4
|
||||
-
|
||||
name: Test
|
||||
uses: docker/bake-action@v4
|
||||
uses: docker/bake-action@v5
|
||||
with:
|
||||
targets: test
|
||||
-
|
||||
|
||||
2
.github/workflows/validate.yml
vendored
2
.github/workflows/validate.yml
vendored
@ -40,6 +40,6 @@ jobs:
|
||||
uses: actions/checkout@v4
|
||||
-
|
||||
name: Validate
|
||||
uses: docker/bake-action@v4
|
||||
uses: docker/bake-action@v5
|
||||
with:
|
||||
targets: ${{ matrix.target }}
|
||||
|
||||
15
README.md
15
README.md
@ -37,6 +37,7 @@ ___
|
||||
* [Customizing](#customizing)
|
||||
* [inputs](#inputs)
|
||||
* [outputs](#outputs)
|
||||
* [environment variables](#environment-variables)
|
||||
* [Troubleshooting](#troubleshooting)
|
||||
* [Contributing](#contributing)
|
||||
|
||||
@ -89,7 +90,7 @@ jobs:
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
-
|
||||
name: Build and push
|
||||
uses: docker/build-push-action@v5
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
push: true
|
||||
tags: user/app:latest
|
||||
@ -114,7 +115,7 @@ to the default Git context:
|
||||
uses: docker/setup-buildx-action@v3
|
||||
-
|
||||
name: Build and push
|
||||
uses: docker/build-push-action@v5
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: "{{defaultContext}}:mysubdir"
|
||||
push: true
|
||||
@ -129,7 +130,7 @@ named `GIT_AUTH_TOKEN` to be able to authenticate against it with Buildx:
|
||||
```yaml
|
||||
-
|
||||
name: Build and push
|
||||
uses: docker/build-push-action@v5
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
push: true
|
||||
tags: user/app:latest
|
||||
@ -168,7 +169,7 @@ jobs:
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
-
|
||||
name: Build and push
|
||||
uses: docker/build-push-action@v5
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
push: true
|
||||
@ -256,6 +257,12 @@ The following outputs are available:
|
||||
| `digest` | String | Image digest |
|
||||
| `metadata` | JSON | Build result metadata |
|
||||
|
||||
### environment variables
|
||||
|
||||
| Name | Type | Description |
|
||||
|---------------------------|------|-------------------------------------------------------------------------------------------------------------------|
|
||||
| `DOCKER_BUILD_NO_SUMMARY` | Bool | If `true`, [build summary](https://docs.docker.com/build/ci/github-actions/build-summary/) generation is disabled |
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
See [TROUBLESHOOTING.md](TROUBLESHOOTING.md)
|
||||
|
||||
@ -59,7 +59,7 @@ jobs:
|
||||
uses: crazy-max/ghaction-setup-containerd@v2
|
||||
-
|
||||
name: Build Docker image
|
||||
uses: docker/build-push-action@v5
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64
|
||||
@ -112,7 +112,7 @@ to generate sanitized tags:
|
||||
tags: latest
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v5
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
push: true
|
||||
@ -130,7 +130,7 @@ Or a dedicated step to sanitize the slug:
|
||||
script: return 'ghcr.io/${{ github.repository }}'.toLowerCase()
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v5
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
push: true
|
||||
|
||||
@ -799,6 +799,27 @@ ANOTHER_SECRET=ANOTHER_SECRET_ENV`]
|
||||
'.'
|
||||
]
|
||||
],
|
||||
[
|
||||
34,
|
||||
'0.14.1',
|
||||
new Map<string, string>([
|
||||
['context', '.'],
|
||||
['load', 'false'],
|
||||
['no-cache', 'false'],
|
||||
['push', 'false'],
|
||||
['pull', 'false'],
|
||||
['cache-to', 'type=gha'],
|
||||
['github-token', `abcd1234`],
|
||||
]),
|
||||
[
|
||||
'build',
|
||||
'--cache-to', 'type=gha,repository=docker/build-push-action,ghtoken=abcd1234',
|
||||
'--iidfile', imageIDFilePath,
|
||||
'--attest', `type=provenance,mode=min,inline-only=true,builder-id=https://github.com/docker/build-push-action/actions/runs/123456789/attempts/1`,
|
||||
'--metadata-file', metadataJson,
|
||||
'.'
|
||||
]
|
||||
],
|
||||
])(
|
||||
'[%d] given %p with %p as inputs, returns %p',
|
||||
async (num: number, buildxVersion: string, inputs: Map<string, string>, expected: Array<string>) => {
|
||||
|
||||
4
dist/index.js
generated
vendored
4
dist/index.js
generated
vendored
File diff suppressed because one or more lines are too long
2
dist/index.js.map
generated
vendored
2
dist/index.js.map
generated
vendored
File diff suppressed because one or more lines are too long
2
dist/licenses.txt
generated
vendored
2
dist/licenses.txt
generated
vendored
@ -2807,7 +2807,7 @@ minimatch
|
||||
ISC
|
||||
The ISC License
|
||||
|
||||
Copyright (c) Isaac Z. Schlueter and Contributors
|
||||
Copyright (c) 2011-2023 Isaac Z. Schlueter and Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
|
||||
@ -27,7 +27,7 @@
|
||||
"packageManager": "yarn@3.6.3",
|
||||
"dependencies": {
|
||||
"@actions/core": "^1.10.1",
|
||||
"@docker/actions-toolkit": "0.25.1",
|
||||
"@docker/actions-toolkit": "0.26.1",
|
||||
"handlebars": "^4.7.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@ -79,6 +79,25 @@ export async function getInputs(): Promise<Inputs> {
|
||||
};
|
||||
}
|
||||
|
||||
export function sanitizeInputs(inputs: Inputs) {
|
||||
const res = {};
|
||||
for (const key of Object.keys(inputs)) {
|
||||
if (key === 'github-token') {
|
||||
continue;
|
||||
}
|
||||
const value: string | string[] | boolean = inputs[key];
|
||||
if (typeof value === 'boolean' && value === false) {
|
||||
continue;
|
||||
} else if (Array.isArray(value) && value.length === 0) {
|
||||
continue;
|
||||
} else if (!value) {
|
||||
continue;
|
||||
}
|
||||
res[key] = value;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
export async function getArgs(inputs: Inputs, toolkit: Toolkit): Promise<Array<string>> {
|
||||
const context = handlebars.compile(inputs.context)({
|
||||
defaultContext: Context.gitContext()
|
||||
@ -120,7 +139,7 @@ async function getBuildArgs(inputs: Inputs, context: string, toolkit: Toolkit):
|
||||
args.push('--cache-from', cacheFrom);
|
||||
});
|
||||
await Util.asyncForEach(inputs['cache-to'], async cacheTo => {
|
||||
args.push('--cache-to', cacheTo);
|
||||
args.push('--cache-to', Build.resolveCacheToAttrs(cacheTo, inputs['github-token']));
|
||||
});
|
||||
if (inputs['cgroup-parent']) {
|
||||
args.push('--cgroup-parent', inputs['cgroup-parent']);
|
||||
|
||||
71
src/main.ts
71
src/main.ts
@ -4,11 +4,14 @@ import * as stateHelper from './state-helper';
|
||||
import * as core from '@actions/core';
|
||||
import * as actionsToolkit from '@docker/actions-toolkit';
|
||||
|
||||
import {Buildx} from '@docker/actions-toolkit/lib/buildx/buildx';
|
||||
import {History as BuildxHistory} from '@docker/actions-toolkit/lib/buildx/history';
|
||||
import {Context} from '@docker/actions-toolkit/lib/context';
|
||||
import {Docker} from '@docker/actions-toolkit/lib/docker/docker';
|
||||
import {Exec} from '@docker/actions-toolkit/lib/exec';
|
||||
import {GitHub} from '@docker/actions-toolkit/lib/github';
|
||||
import {Toolkit} from '@docker/actions-toolkit/lib/toolkit';
|
||||
import {Util} from '@docker/actions-toolkit/lib/util';
|
||||
|
||||
import {ConfigFile} from '@docker/actions-toolkit/lib/types/docker/docker';
|
||||
|
||||
@ -17,8 +20,10 @@ import * as context from './context';
|
||||
actionsToolkit.run(
|
||||
// main
|
||||
async () => {
|
||||
const startedTime = new Date();
|
||||
const inputs: context.Inputs = await context.getInputs();
|
||||
core.debug(`inputs: ${JSON.stringify(inputs)}`);
|
||||
stateHelper.setInputs(inputs);
|
||||
|
||||
const toolkit = new Toolkit();
|
||||
|
||||
@ -78,6 +83,7 @@ actionsToolkit.run(
|
||||
await core.group(`Builder info`, async () => {
|
||||
const builder = await toolkit.builder.inspect(inputs.builder);
|
||||
core.info(JSON.stringify(builder, null, 2));
|
||||
stateHelper.setBuilder(builder);
|
||||
});
|
||||
|
||||
const args: string[] = await context.getArgs(inputs, toolkit);
|
||||
@ -87,11 +93,12 @@ actionsToolkit.run(
|
||||
core.debug(`buildCmd.command: ${buildCmd.command}`);
|
||||
core.debug(`buildCmd.args: ${JSON.stringify(buildCmd.args)}`);
|
||||
|
||||
let err: Error | undefined;
|
||||
await Exec.getExecOutput(buildCmd.command, buildCmd.args, {
|
||||
ignoreReturnCode: true
|
||||
}).then(res => {
|
||||
if (res.stderr.length > 0 && res.exitCode != 0) {
|
||||
throw new Error(`buildx failed with: ${res.stderr.match(/(.*)\s*$/)?.[0]?.trim() ?? 'unknown error'}`);
|
||||
err = Error(`buildx failed with: ${res.stderr.match(/(.*)\s*$/)?.[0]?.trim() ?? 'unknown error'}`);
|
||||
}
|
||||
});
|
||||
|
||||
@ -118,9 +125,52 @@ actionsToolkit.run(
|
||||
core.setOutput('metadata', metadatadt);
|
||||
});
|
||||
}
|
||||
await core.group(`Reference`, async () => {
|
||||
const ref = await buildRef(toolkit, startedTime, inputs.builder);
|
||||
if (ref) {
|
||||
core.info(ref);
|
||||
stateHelper.setBuildRef(ref);
|
||||
} else {
|
||||
core.warning('No build ref found');
|
||||
}
|
||||
});
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
},
|
||||
// post
|
||||
async () => {
|
||||
if (stateHelper.buildRef.length > 0) {
|
||||
await core.group(`Generating build summary`, async () => {
|
||||
if (process.env.DOCKER_BUILD_NO_SUMMARY && Util.parseBool(process.env.DOCKER_BUILD_NO_SUMMARY)) {
|
||||
core.info('Summary disabled');
|
||||
return;
|
||||
}
|
||||
if (stateHelper.builder && stateHelper.builder.driver === 'cloud') {
|
||||
core.info('Summary is not yet supported with Docker Build Cloud');
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const buildxHistory = new BuildxHistory();
|
||||
const exportRes = await buildxHistory.export({
|
||||
refs: [stateHelper.buildRef]
|
||||
});
|
||||
core.info(`Build record exported to ${exportRes.dockerbuildFilename} (${Util.formatFileSize(exportRes.dockerbuildSize)})`);
|
||||
const uploadRes = await GitHub.uploadArtifact({
|
||||
filename: exportRes.dockerbuildFilename,
|
||||
mimeType: 'application/gzip',
|
||||
retentionDays: 90
|
||||
});
|
||||
await GitHub.writeBuildSummary({
|
||||
exportRes: exportRes,
|
||||
uploadRes: uploadRes,
|
||||
inputs: stateHelper.inputs
|
||||
});
|
||||
} catch (e) {
|
||||
core.warning(e.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (stateHelper.tmpDir.length > 0) {
|
||||
await core.group(`Removing temp folder ${stateHelper.tmpDir}`, async () => {
|
||||
fs.rmSync(stateHelper.tmpDir, {recursive: true});
|
||||
@ -128,3 +178,22 @@ actionsToolkit.run(
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
async function buildRef(toolkit: Toolkit, since: Date, builder?: string): Promise<string> {
|
||||
// get ref from metadata file
|
||||
const ref = toolkit.buildxBuild.resolveRef();
|
||||
if (ref) {
|
||||
return ref;
|
||||
}
|
||||
// otherwise, look for the very first build ref since the build has started
|
||||
if (!builder) {
|
||||
const currentBuilder = await toolkit.builder.inspect();
|
||||
builder = currentBuilder.name;
|
||||
}
|
||||
const refs = Buildx.refs({
|
||||
dir: Buildx.refsDir,
|
||||
builderName: builder,
|
||||
since: since
|
||||
});
|
||||
return Object.keys(refs).length > 0 ? Object.keys(refs)[0] : '';
|
||||
}
|
||||
|
||||
@ -1,7 +1,26 @@
|
||||
import * as core from '@actions/core';
|
||||
|
||||
import {BuilderInfo} from '@docker/actions-toolkit/lib/types/buildx/builder';
|
||||
|
||||
import {Inputs, sanitizeInputs} from './context';
|
||||
|
||||
export const tmpDir = process.env['STATE_tmpDir'] || '';
|
||||
export const inputs = process.env['STATE_inputs'] ? JSON.parse(process.env['STATE_inputs']) : undefined;
|
||||
export const builder = process.env['STATE_builder'] ? <BuilderInfo>JSON.parse(process.env['STATE_builder']) : undefined;
|
||||
export const buildRef = process.env['STATE_buildRef'] || '';
|
||||
|
||||
export function setTmpDir(tmpDir: string) {
|
||||
core.saveState('tmpDir', tmpDir);
|
||||
}
|
||||
|
||||
export function setInputs(inputs: Inputs) {
|
||||
core.saveState('inputs', JSON.stringify(sanitizeInputs(inputs)));
|
||||
}
|
||||
|
||||
export function setBuilder(builder: BuilderInfo) {
|
||||
core.saveState('builder', JSON.stringify(builder));
|
||||
}
|
||||
|
||||
export function setBuildRef(buildRef: string) {
|
||||
core.saveState('buildRef', buildRef);
|
||||
}
|
||||
|
||||
26
yarn.lock
26
yarn.lock
@ -1055,9 +1055,9 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@docker/actions-toolkit@npm:0.25.1":
|
||||
version: 0.25.1
|
||||
resolution: "@docker/actions-toolkit@npm:0.25.1"
|
||||
"@docker/actions-toolkit@npm:0.26.1":
|
||||
version: 0.26.1
|
||||
resolution: "@docker/actions-toolkit@npm:0.26.1"
|
||||
dependencies:
|
||||
"@actions/artifact": ^2.1.7
|
||||
"@actions/cache": ^3.2.4
|
||||
@ -1079,7 +1079,7 @@ __metadata:
|
||||
semver: ^7.6.2
|
||||
tar-stream: ^3.1.7
|
||||
tmp: ^0.2.3
|
||||
checksum: 348a7e9807661839840c0f58c143177d2946cab5f97e47281bb25fef7dd9564bb48ec3fd099eac2acc5b603ed9305cb55316109d9051f54f8a53a476cf6e2cd6
|
||||
checksum: 1c1f1294089ad586521f61945b951e2878054df0a887b0e0604967fedd689a7e11b69054c101a68df0d2ffb96cd8f1ddb19be456cc867b8bcf78118527beb942
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@ -2629,11 +2629,11 @@ __metadata:
|
||||
linkType: hard
|
||||
|
||||
"braces@npm:^3.0.1":
|
||||
version: 3.0.2
|
||||
resolution: "braces@npm:3.0.2"
|
||||
version: 3.0.3
|
||||
resolution: "braces@npm:3.0.3"
|
||||
dependencies:
|
||||
fill-range: ^7.0.1
|
||||
checksum: e2a8e769a863f3d4ee887b5fe21f63193a891c68b612ddb4b68d82d1b5f3ff9073af066c343e9867a393fe4c2555dcb33e89b937195feb9c1613d259edfcd459
|
||||
fill-range: ^7.1.1
|
||||
checksum: b95aa0b3bd909f6cd1720ffcf031aeaf46154dd88b4da01f9a1d3f7ea866a79eba76a6d01cbc3c422b2ee5cdc39a4f02491058d5df0d7bf6e6a162a832df1f69
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@ -3149,7 +3149,7 @@ __metadata:
|
||||
resolution: "docker-build-push@workspace:."
|
||||
dependencies:
|
||||
"@actions/core": ^1.10.1
|
||||
"@docker/actions-toolkit": 0.25.1
|
||||
"@docker/actions-toolkit": 0.26.1
|
||||
"@types/node": ^20.12.12
|
||||
"@typescript-eslint/eslint-plugin": ^7.9.0
|
||||
"@typescript-eslint/parser": ^7.9.0
|
||||
@ -3625,12 +3625,12 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"fill-range@npm:^7.0.1":
|
||||
version: 7.0.1
|
||||
resolution: "fill-range@npm:7.0.1"
|
||||
"fill-range@npm:^7.1.1":
|
||||
version: 7.1.1
|
||||
resolution: "fill-range@npm:7.1.1"
|
||||
dependencies:
|
||||
to-regex-range: ^5.0.1
|
||||
checksum: cc283f4e65b504259e64fd969bcf4def4eb08d85565e906b7d36516e87819db52029a76b6363d0f02d0d532f0033c9603b9e2d943d56ee3b0d4f7ad3328ff917
|
||||
checksum: b4abfbca3839a3d55e4ae5ec62e131e2e356bf4859ce8480c64c4876100f4df292a63e5bb1618e1d7460282ca2b305653064f01654474aa35c68000980f17798
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user