mirror of
https://gitea.com/docker/build-push-action.git
synced 2024-11-25 10:59:38 +01:00
Merge pull request #759 from crazy-max/fix-provenance-input
Fix provenance input
This commit is contained in:
commit
d1b0eb0a29
6 changed files with 188 additions and 13 deletions
35
.github/workflows/ci.yml
vendored
35
.github/workflows/ci.yml
vendored
|
@ -523,6 +523,41 @@ jobs:
|
||||||
file: ./test/go/Dockerfile
|
file: ./test/go/Dockerfile
|
||||||
outputs: type=cacheonly
|
outputs: type=cacheonly
|
||||||
|
|
||||||
|
provenance:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
attrs:
|
||||||
|
- ''
|
||||||
|
- mode=max
|
||||||
|
- builder-id=foo
|
||||||
|
- false
|
||||||
|
- true
|
||||||
|
steps:
|
||||||
|
-
|
||||||
|
name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
-
|
||||||
|
name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v2
|
||||||
|
with:
|
||||||
|
version: ${{ inputs.buildx-version || env.BUILDX_VERSION }}
|
||||||
|
driver-opts: |
|
||||||
|
network=host
|
||||||
|
image=${{ inputs.buildkit-image || env.BUILDKIT_IMAGE }}
|
||||||
|
-
|
||||||
|
name: Build
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
context: ./test/go
|
||||||
|
file: ./test/go/Dockerfile
|
||||||
|
target: binary
|
||||||
|
outputs: type=oci,dest=/tmp/build.tar
|
||||||
|
provenance: ${{ matrix.attrs }}
|
||||||
|
cache-from: type=gha,scope=provenance
|
||||||
|
cache-to: type=gha,scope=provenance,mode=max
|
||||||
|
|
||||||
sbom:
|
sbom:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
|
|
|
@ -2,6 +2,7 @@ import {beforeEach, describe, expect, it, jest, test} from '@jest/globals';
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
|
|
||||||
|
import * as buildx from '../src/buildx';
|
||||||
import * as context from '../src/context';
|
import * as context from '../src/context';
|
||||||
|
|
||||||
const pgp = `-----BEGIN PGP PRIVATE KEY BLOCK-----
|
const pgp = `-----BEGIN PGP PRIVATE KEY BLOCK-----
|
||||||
|
@ -127,6 +128,8 @@ jest.spyOn(context, 'tmpNameSync').mockImplementation((): string => {
|
||||||
return path.join('/tmp/.docker-build-push-jest', '.tmpname-jest').split(path.sep).join(path.posix.sep);
|
return path.join('/tmp/.docker-build-push-jest', '.tmpname-jest').split(path.sep).join(path.posix.sep);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
jest.spyOn(buildx, 'satisfiesBuildKitVersion').mockResolvedValueOnce(true);
|
||||||
|
|
||||||
describe('getArgs', () => {
|
describe('getArgs', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
process.env = Object.keys(process.env).reduce((object, key) => {
|
process.env = Object.keys(process.env).reduce((object, key) => {
|
||||||
|
@ -159,7 +162,11 @@ describe('getArgs', () => {
|
||||||
1,
|
1,
|
||||||
'0.4.2',
|
'0.4.2',
|
||||||
new Map<string, string>([
|
new Map<string, string>([
|
||||||
['build-args', 'MY_ARG=val1,val2,val3\nARG=val'],
|
['build-args', `MY_ARG=val1,val2,val3
|
||||||
|
ARG=val
|
||||||
|
"MULTILINE=aaaa
|
||||||
|
bbbb
|
||||||
|
ccc"`],
|
||||||
['load', 'false'],
|
['load', 'false'],
|
||||||
['no-cache', 'false'],
|
['no-cache', 'false'],
|
||||||
['push', 'false'],
|
['push', 'false'],
|
||||||
|
@ -169,6 +176,7 @@ describe('getArgs', () => {
|
||||||
'build',
|
'build',
|
||||||
'--build-arg', 'MY_ARG=val1,val2,val3',
|
'--build-arg', 'MY_ARG=val1,val2,val3',
|
||||||
'--build-arg', 'ARG=val',
|
'--build-arg', 'ARG=val',
|
||||||
|
'--build-arg', `MULTILINE=aaaa\nbbbb\nccc`,
|
||||||
'--iidfile', '/tmp/.docker-build-push-jest/iidfile',
|
'--iidfile', '/tmp/.docker-build-push-jest/iidfile',
|
||||||
'https://github.com/docker/build-push-action.git#refs/heads/test-jest'
|
'https://github.com/docker/build-push-action.git#refs/heads/test-jest'
|
||||||
]
|
]
|
||||||
|
@ -517,7 +525,119 @@ nproc=3`],
|
||||||
'--metadata-file', '/tmp/.docker-build-push-jest/metadata-file',
|
'--metadata-file', '/tmp/.docker-build-push-jest/metadata-file',
|
||||||
'https://github.com/docker/build-push-action.git#refs/heads/test-jest:subdir'
|
'https://github.com/docker/build-push-action.git#refs/heads/test-jest:subdir'
|
||||||
]
|
]
|
||||||
]
|
],
|
||||||
|
[
|
||||||
|
17,
|
||||||
|
'0.8.2',
|
||||||
|
new Map<string, string>([
|
||||||
|
['context', '.'],
|
||||||
|
['load', 'false'],
|
||||||
|
['no-cache', 'false'],
|
||||||
|
['push', 'false'],
|
||||||
|
['pull', 'false'],
|
||||||
|
['provenance', 'true'],
|
||||||
|
]),
|
||||||
|
[
|
||||||
|
'build',
|
||||||
|
'--iidfile', '/tmp/.docker-build-push-jest/iidfile',
|
||||||
|
'--metadata-file', '/tmp/.docker-build-push-jest/metadata-file',
|
||||||
|
'.'
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
18,
|
||||||
|
'0.10.0',
|
||||||
|
new Map<string, string>([
|
||||||
|
['context', '.'],
|
||||||
|
['load', 'false'],
|
||||||
|
['no-cache', 'false'],
|
||||||
|
['push', 'false'],
|
||||||
|
['pull', 'false'],
|
||||||
|
]),
|
||||||
|
[
|
||||||
|
'build',
|
||||||
|
'--iidfile', '/tmp/.docker-build-push-jest/iidfile',
|
||||||
|
"--provenance", `mode=min,inline-only=true,builder-id=https://github.com/docker/build-push-action/actions/runs/123456789`,
|
||||||
|
'--metadata-file', '/tmp/.docker-build-push-jest/metadata-file',
|
||||||
|
'.'
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
19,
|
||||||
|
'0.10.0',
|
||||||
|
new Map<string, string>([
|
||||||
|
['context', '.'],
|
||||||
|
['load', 'false'],
|
||||||
|
['no-cache', 'false'],
|
||||||
|
['push', 'false'],
|
||||||
|
['pull', 'false'],
|
||||||
|
['provenance', 'true'],
|
||||||
|
]),
|
||||||
|
[
|
||||||
|
'build',
|
||||||
|
'--iidfile', '/tmp/.docker-build-push-jest/iidfile',
|
||||||
|
"--provenance", `builder-id=https://github.com/docker/build-push-action/actions/runs/123456789`,
|
||||||
|
'--metadata-file', '/tmp/.docker-build-push-jest/metadata-file',
|
||||||
|
'.'
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
20,
|
||||||
|
'0.10.0',
|
||||||
|
new Map<string, string>([
|
||||||
|
['context', '.'],
|
||||||
|
['load', 'false'],
|
||||||
|
['no-cache', 'false'],
|
||||||
|
['push', 'false'],
|
||||||
|
['pull', 'false'],
|
||||||
|
['provenance', 'mode=max'],
|
||||||
|
]),
|
||||||
|
[
|
||||||
|
'build',
|
||||||
|
'--iidfile', '/tmp/.docker-build-push-jest/iidfile',
|
||||||
|
"--provenance", `mode=max,builder-id=https://github.com/docker/build-push-action/actions/runs/123456789`,
|
||||||
|
'--metadata-file', '/tmp/.docker-build-push-jest/metadata-file',
|
||||||
|
'.'
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
21,
|
||||||
|
'0.10.0',
|
||||||
|
new Map<string, string>([
|
||||||
|
['context', '.'],
|
||||||
|
['load', 'false'],
|
||||||
|
['no-cache', 'false'],
|
||||||
|
['push', 'false'],
|
||||||
|
['pull', 'false'],
|
||||||
|
['provenance', 'false'],
|
||||||
|
]),
|
||||||
|
[
|
||||||
|
'build',
|
||||||
|
'--iidfile', '/tmp/.docker-build-push-jest/iidfile',
|
||||||
|
"--provenance", 'false',
|
||||||
|
'--metadata-file', '/tmp/.docker-build-push-jest/metadata-file',
|
||||||
|
'.'
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
22,
|
||||||
|
'0.10.0',
|
||||||
|
new Map<string, string>([
|
||||||
|
['context', '.'],
|
||||||
|
['load', 'false'],
|
||||||
|
['no-cache', 'false'],
|
||||||
|
['push', 'false'],
|
||||||
|
['pull', 'false'],
|
||||||
|
['provenance', 'builder-id=foo'],
|
||||||
|
]),
|
||||||
|
[
|
||||||
|
'build',
|
||||||
|
'--iidfile', '/tmp/.docker-build-push-jest/iidfile',
|
||||||
|
"--provenance", 'builder-id=foo',
|
||||||
|
'--metadata-file', '/tmp/.docker-build-push-jest/metadata-file',
|
||||||
|
'.'
|
||||||
|
]
|
||||||
|
],
|
||||||
])(
|
])(
|
||||||
'[%d] given %p with %p as inputs, returns %p',
|
'[%d] given %p with %p as inputs, returns %p',
|
||||||
async (num: number, buildxVersion: string, inputs: Map<string, string>, expected: Array<string>) => {
|
async (num: number, buildxVersion: string, inputs: Map<string, string>, expected: Array<string>) => {
|
||||||
|
|
|
@ -68,6 +68,8 @@ FROM docker/buildx-bin:${BUILDX_VERSION} as buildx
|
||||||
FROM deps AS test
|
FROM deps AS test
|
||||||
ENV RUNNER_TEMP=/tmp/github_runner
|
ENV RUNNER_TEMP=/tmp/github_runner
|
||||||
ENV RUNNER_TOOL_CACHE=/tmp/github_tool_cache
|
ENV RUNNER_TOOL_CACHE=/tmp/github_tool_cache
|
||||||
|
ENV GITHUB_REPOSITORY=docker/build-push-action
|
||||||
|
ENV GITHUB_RUN_ID=123456789
|
||||||
RUN --mount=type=bind,target=.,rw \
|
RUN --mount=type=bind,target=.,rw \
|
||||||
--mount=type=cache,target=/src/node_modules \
|
--mount=type=cache,target=/src/node_modules \
|
||||||
--mount=type=bind,from=docker,source=/usr/local/bin/docker,target=/usr/bin/docker \
|
--mount=type=bind,from=docker,source=/usr/local/bin/docker,target=/usr/bin/docker \
|
||||||
|
|
2
dist/index.js
generated
vendored
2
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
|
@ -68,6 +68,10 @@ export function tmpNameSync(options?: tmp.TmpNameOptions): string {
|
||||||
return tmp.tmpNameSync(options);
|
return tmp.tmpNameSync(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function provenanceBuilderID(): string {
|
||||||
|
return `${process.env.GITHUB_SERVER_URL || 'https://github.com'}/${github.context.repo.owner}/${github.context.repo.repo}/actions/runs/${github.context.runId}`;
|
||||||
|
}
|
||||||
|
|
||||||
export async function getInputs(defaultContext: string): Promise<Inputs> {
|
export async function getInputs(defaultContext: string): Promise<Inputs> {
|
||||||
return {
|
return {
|
||||||
addHosts: await getInputList('add-hosts'),
|
addHosts: await getInputList('add-hosts'),
|
||||||
|
@ -88,7 +92,7 @@ export async function getInputs(defaultContext: string): Promise<Inputs> {
|
||||||
noCacheFilters: await getInputList('no-cache-filters'),
|
noCacheFilters: await getInputList('no-cache-filters'),
|
||||||
outputs: await getInputList('outputs', true),
|
outputs: await getInputList('outputs', true),
|
||||||
platforms: await getInputList('platforms'),
|
platforms: await getInputList('platforms'),
|
||||||
provenance: core.getInput('provenance'),
|
provenance: getProvenanceInput('provenance'),
|
||||||
pull: core.getBooleanInput('pull'),
|
pull: core.getBooleanInput('pull'),
|
||||||
push: core.getBooleanInput('push'),
|
push: core.getBooleanInput('push'),
|
||||||
sbom: core.getInput('sbom'),
|
sbom: core.getInput('sbom'),
|
||||||
|
@ -162,9 +166,8 @@ async function getBuildArgs(inputs: Inputs, defaultContext: string, context: str
|
||||||
args.push('--platform', inputs.platforms.join(','));
|
args.push('--platform', inputs.platforms.join(','));
|
||||||
}
|
}
|
||||||
if (buildx.satisfies(buildxVersion, '>=0.10.0')) {
|
if (buildx.satisfies(buildxVersion, '>=0.10.0')) {
|
||||||
const prvBuilderID = `${process.env.GITHUB_SERVER_URL || 'https://github.com'}/${github.context.repo.owner}/${github.context.repo.repo}/actions/runs/${github.context.runId}`;
|
|
||||||
if (inputs.provenance) {
|
if (inputs.provenance) {
|
||||||
args.push('--provenance', getProvenanceAttrs(inputs.provenance, prvBuilderID));
|
args.push('--provenance', inputs.provenance);
|
||||||
} else if ((await buildx.satisfiesBuildKitVersion(inputs.builder, '>=0.11.0', standalone)) && !hasDockerExport(inputs)) {
|
} else if ((await buildx.satisfiesBuildKitVersion(inputs.builder, '>=0.11.0', standalone)) && !hasDockerExport(inputs)) {
|
||||||
// if provenance not specified and BuildKit version compatible for
|
// if provenance not specified and BuildKit version compatible for
|
||||||
// attestation, set default provenance. Also needs to make sure user
|
// attestation, set default provenance. Also needs to make sure user
|
||||||
|
@ -172,12 +175,10 @@ async function getBuildArgs(inputs: Inputs, defaultContext: string, context: str
|
||||||
if (fromPayload('repository.private') !== false) {
|
if (fromPayload('repository.private') !== false) {
|
||||||
// if this is a private repository, we set the default provenance
|
// if this is a private repository, we set the default provenance
|
||||||
// attributes being set in buildx: https://github.com/docker/buildx/blob/fb27e3f919dcbf614d7126b10c2bc2d0b1927eb6/build/build.go#L603
|
// attributes being set in buildx: https://github.com/docker/buildx/blob/fb27e3f919dcbf614d7126b10c2bc2d0b1927eb6/build/build.go#L603
|
||||||
// along the builder-id attribute.
|
args.push('--provenance', getProvenanceAttrs(`mode=min,inline-only=true`));
|
||||||
args.push('--provenance', `mode=min,inline-only=true,builder-id=${prvBuilderID}`);
|
|
||||||
} else {
|
} else {
|
||||||
// for a public repository, we set max provenance mode and the
|
// for a public repository, we set max provenance mode.
|
||||||
// builder-id attribute.
|
args.push('--provenance', getProvenanceAttrs(`mode=max`));
|
||||||
args.push('--provenance', `mode=max,builder-id=${prvBuilderID}`);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (inputs.sbom) {
|
if (inputs.sbom) {
|
||||||
|
@ -298,7 +299,24 @@ function select(obj: any, path: string): any {
|
||||||
return select(obj[key], path.slice(i + 1));
|
return select(obj[key], path.slice(i + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
function getProvenanceAttrs(input: string, builderID: string): string {
|
function getProvenanceInput(name: string): string {
|
||||||
|
const input = core.getInput(name);
|
||||||
|
if (!input) {
|
||||||
|
// if input is not set, default values will be set later.
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
const builderID = provenanceBuilderID();
|
||||||
|
try {
|
||||||
|
return core.getBooleanInput(name) ? `builder-id=${builderID}` : 'false';
|
||||||
|
} catch (err) {
|
||||||
|
// not a valid boolean, so we assume it's a string
|
||||||
|
return getProvenanceAttrs(input);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getProvenanceAttrs(input: string): string {
|
||||||
|
const builderID = provenanceBuilderID();
|
||||||
|
// parse attributes from input
|
||||||
const fields = parse(input, {
|
const fields = parse(input, {
|
||||||
relaxColumnCount: true,
|
relaxColumnCount: true,
|
||||||
skipEmptyLines: true
|
skipEmptyLines: true
|
||||||
|
|
Loading…
Reference in a new issue