mirror of
https://github.com/docker/build-push-action
synced 2024-11-22 18:31:40 +00:00
Merge pull request #1086 from crazy-max/fix-attests-provenance-sbom
handle attests correctly with provenance and sbom inputs
This commit is contained in:
commit
c3b570184c
4 changed files with 128 additions and 43 deletions
|
@ -481,7 +481,7 @@ nproc=3`],
|
||||||
[
|
[
|
||||||
'build',
|
'build',
|
||||||
'--iidfile', path.join(tmpDir, 'iidfile'),
|
'--iidfile', path.join(tmpDir, 'iidfile'),
|
||||||
"--provenance", `mode=min,inline-only=true,builder-id=https://github.com/docker/build-push-action/actions/runs/123456789`,
|
'--attest', `type=provenance,mode=min,inline-only=true,builder-id=https://github.com/docker/build-push-action/actions/runs/123456789`,
|
||||||
'--metadata-file', path.join(tmpDir, 'metadata-file'),
|
'--metadata-file', path.join(tmpDir, 'metadata-file'),
|
||||||
'.'
|
'.'
|
||||||
]
|
]
|
||||||
|
@ -500,7 +500,7 @@ nproc=3`],
|
||||||
[
|
[
|
||||||
'build',
|
'build',
|
||||||
'--iidfile', path.join(tmpDir, 'iidfile'),
|
'--iidfile', path.join(tmpDir, 'iidfile'),
|
||||||
"--provenance", `builder-id=https://github.com/docker/build-push-action/actions/runs/123456789`,
|
'--attest', `type=provenance,builder-id=https://github.com/docker/build-push-action/actions/runs/123456789`,
|
||||||
'--metadata-file', path.join(tmpDir, 'metadata-file'),
|
'--metadata-file', path.join(tmpDir, 'metadata-file'),
|
||||||
'.'
|
'.'
|
||||||
]
|
]
|
||||||
|
@ -519,7 +519,7 @@ nproc=3`],
|
||||||
[
|
[
|
||||||
'build',
|
'build',
|
||||||
'--iidfile', path.join(tmpDir, 'iidfile'),
|
'--iidfile', path.join(tmpDir, 'iidfile'),
|
||||||
"--provenance", `mode=max,builder-id=https://github.com/docker/build-push-action/actions/runs/123456789`,
|
'--attest', `type=provenance,mode=max,builder-id=https://github.com/docker/build-push-action/actions/runs/123456789`,
|
||||||
'--metadata-file', path.join(tmpDir, 'metadata-file'),
|
'--metadata-file', path.join(tmpDir, 'metadata-file'),
|
||||||
'.'
|
'.'
|
||||||
]
|
]
|
||||||
|
@ -538,7 +538,7 @@ nproc=3`],
|
||||||
[
|
[
|
||||||
'build',
|
'build',
|
||||||
'--iidfile', path.join(tmpDir, 'iidfile'),
|
'--iidfile', path.join(tmpDir, 'iidfile'),
|
||||||
"--provenance", 'false',
|
'--attest', 'type=provenance,disabled=true',
|
||||||
'--metadata-file', path.join(tmpDir, 'metadata-file'),
|
'--metadata-file', path.join(tmpDir, 'metadata-file'),
|
||||||
'.'
|
'.'
|
||||||
]
|
]
|
||||||
|
@ -557,7 +557,7 @@ nproc=3`],
|
||||||
[
|
[
|
||||||
'build',
|
'build',
|
||||||
'--iidfile', path.join(tmpDir, 'iidfile'),
|
'--iidfile', path.join(tmpDir, 'iidfile'),
|
||||||
"--provenance", 'builder-id=foo',
|
'--attest', 'type=provenance,builder-id=foo',
|
||||||
'--metadata-file', path.join(tmpDir, 'metadata-file'),
|
'--metadata-file', path.join(tmpDir, 'metadata-file'),
|
||||||
'.'
|
'.'
|
||||||
]
|
]
|
||||||
|
@ -620,7 +620,7 @@ nproc=3`],
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
25,
|
26,
|
||||||
'0.10.0',
|
'0.10.0',
|
||||||
new Map<string, string>([
|
new Map<string, string>([
|
||||||
['context', '.'],
|
['context', '.'],
|
||||||
|
@ -642,7 +642,7 @@ ANOTHER_SECRET=ANOTHER_SECRET_ENV`]
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
26,
|
27,
|
||||||
'0.10.0',
|
'0.10.0',
|
||||||
new Map<string, string>([
|
new Map<string, string>([
|
||||||
['context', '.'],
|
['context', '.'],
|
||||||
|
@ -663,7 +663,7 @@ ANOTHER_SECRET=ANOTHER_SECRET_ENV`]
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
27,
|
28,
|
||||||
'0.11.0',
|
'0.11.0',
|
||||||
new Map<string, string>([
|
new Map<string, string>([
|
||||||
['context', '.'],
|
['context', '.'],
|
||||||
|
@ -677,13 +677,13 @@ ANOTHER_SECRET=ANOTHER_SECRET_ENV`]
|
||||||
[
|
[
|
||||||
'build',
|
'build',
|
||||||
'--output', 'type=local,dest=./release-out',
|
'--output', 'type=local,dest=./release-out',
|
||||||
"--provenance", `mode=min,inline-only=true,builder-id=https://github.com/docker/build-push-action/actions/runs/123456789`,
|
'--attest', `type=provenance,mode=min,inline-only=true,builder-id=https://github.com/docker/build-push-action/actions/runs/123456789`,
|
||||||
'--metadata-file', path.join(tmpDir, 'metadata-file'),
|
'--metadata-file', path.join(tmpDir, 'metadata-file'),
|
||||||
'.'
|
'.'
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
28,
|
29,
|
||||||
'0.12.0',
|
'0.12.0',
|
||||||
new Map<string, string>([
|
new Map<string, string>([
|
||||||
['context', '.'],
|
['context', '.'],
|
||||||
|
@ -701,13 +701,13 @@ ANOTHER_SECRET=ANOTHER_SECRET_ENV`]
|
||||||
'--annotation', 'manifest:example3=yyy',
|
'--annotation', 'manifest:example3=yyy',
|
||||||
'--annotation', 'manifest-descriptor[linux/amd64]:example4=zzz',
|
'--annotation', 'manifest-descriptor[linux/amd64]:example4=zzz',
|
||||||
'--output', 'type=local,dest=./release-out',
|
'--output', 'type=local,dest=./release-out',
|
||||||
"--provenance", `mode=min,inline-only=true,builder-id=https://github.com/docker/build-push-action/actions/runs/123456789`,
|
'--attest', `type=provenance,mode=min,inline-only=true,builder-id=https://github.com/docker/build-push-action/actions/runs/123456789`,
|
||||||
'--metadata-file', path.join(tmpDir, 'metadata-file'),
|
'--metadata-file', path.join(tmpDir, 'metadata-file'),
|
||||||
'.'
|
'.'
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
29,
|
30,
|
||||||
'0.12.0',
|
'0.12.0',
|
||||||
new Map<string, string>([
|
new Map<string, string>([
|
||||||
['context', '.'],
|
['context', '.'],
|
||||||
|
@ -721,11 +721,71 @@ ANOTHER_SECRET=ANOTHER_SECRET_ENV`]
|
||||||
'build',
|
'build',
|
||||||
'--iidfile', path.join(tmpDir, 'iidfile'),
|
'--iidfile', path.join(tmpDir, 'iidfile'),
|
||||||
"--output", `type=image,"name=localhost:5000/name/app:latest,localhost:5000/name/app:foo",push-by-digest=true,name-canonical=true,push=true`,
|
"--output", `type=image,"name=localhost:5000/name/app:latest,localhost:5000/name/app:foo",push-by-digest=true,name-canonical=true,push=true`,
|
||||||
"--provenance", `mode=min,inline-only=true,builder-id=https://github.com/docker/build-push-action/actions/runs/123456789`,
|
'--attest', `type=provenance,mode=min,inline-only=true,builder-id=https://github.com/docker/build-push-action/actions/runs/123456789`,
|
||||||
'--metadata-file', path.join(tmpDir, 'metadata-file'),
|
'--metadata-file', path.join(tmpDir, 'metadata-file'),
|
||||||
'.'
|
'.'
|
||||||
]
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
31,
|
||||||
|
'0.13.1',
|
||||||
|
new Map<string, string>([
|
||||||
|
['context', '.'],
|
||||||
|
['load', 'false'],
|
||||||
|
['no-cache', 'false'],
|
||||||
|
['push', 'false'],
|
||||||
|
['pull', 'false'],
|
||||||
|
['provenance', 'mode=max'],
|
||||||
|
['sbom', 'true'],
|
||||||
|
]),
|
||||||
|
[
|
||||||
|
'build',
|
||||||
|
'--iidfile', path.join(tmpDir, 'iidfile'),
|
||||||
|
'--attest', `type=provenance,mode=max,builder-id=https://github.com/docker/build-push-action/actions/runs/123456789`,
|
||||||
|
'--attest', `type=sbom,disabled=false`,
|
||||||
|
'--metadata-file', path.join(tmpDir, 'metadata-file'),
|
||||||
|
'.'
|
||||||
]
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
32,
|
||||||
|
'0.13.1',
|
||||||
|
new Map<string, string>([
|
||||||
|
['context', '.'],
|
||||||
|
['load', 'false'],
|
||||||
|
['no-cache', 'false'],
|
||||||
|
['push', 'false'],
|
||||||
|
['pull', 'false'],
|
||||||
|
['attests', 'type=provenance,mode=min'],
|
||||||
|
['provenance', 'mode=max'],
|
||||||
|
]),
|
||||||
|
[
|
||||||
|
'build',
|
||||||
|
'--iidfile', path.join(tmpDir, 'iidfile'),
|
||||||
|
'--attest', `type=provenance,mode=max,builder-id=https://github.com/docker/build-push-action/actions/runs/123456789`,
|
||||||
|
'--metadata-file', path.join(tmpDir, 'metadata-file'),
|
||||||
|
'.'
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
33,
|
||||||
|
'0.13.1',
|
||||||
|
new Map<string, string>([
|
||||||
|
['context', '.'],
|
||||||
|
['load', 'false'],
|
||||||
|
['no-cache', 'false'],
|
||||||
|
['push', 'false'],
|
||||||
|
['pull', 'false'],
|
||||||
|
['attests', 'type=provenance,mode=min'],
|
||||||
|
]),
|
||||||
|
[
|
||||||
|
'build',
|
||||||
|
'--iidfile', path.join(tmpDir, 'iidfile'),
|
||||||
|
'--attest', `type=provenance,mode=min,builder-id=https://github.com/docker/build-push-action/actions/runs/123456789`,
|
||||||
|
'--metadata-file', path.join(tmpDir, '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>) => {
|
||||||
|
|
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
|
@ -98,13 +98,6 @@ async function getBuildArgs(inputs: Inputs, context: string, toolkit: Toolkit):
|
||||||
if (inputs.allow.length > 0) {
|
if (inputs.allow.length > 0) {
|
||||||
args.push('--allow', inputs.allow.join(','));
|
args.push('--allow', inputs.allow.join(','));
|
||||||
}
|
}
|
||||||
if (await toolkit.buildx.versionSatisfies('>=0.10.0')) {
|
|
||||||
await Util.asyncForEach(inputs.attests, async attest => {
|
|
||||||
args.push('--attest', attest);
|
|
||||||
});
|
|
||||||
} else if (inputs.attests.length > 0) {
|
|
||||||
core.warning("Attestations are only supported by buildx >= 0.10.0; the input 'attests' is ignored.");
|
|
||||||
}
|
|
||||||
if (await toolkit.buildx.versionSatisfies('>=0.12.0')) {
|
if (await toolkit.buildx.versionSatisfies('>=0.12.0')) {
|
||||||
await Util.asyncForEach(inputs.annotations, async annotation => {
|
await Util.asyncForEach(inputs.annotations, async annotation => {
|
||||||
args.push('--annotation', annotation);
|
args.push('--annotation', annotation);
|
||||||
|
@ -157,26 +150,9 @@ async function getBuildArgs(inputs: Inputs, context: string, toolkit: Toolkit):
|
||||||
args.push('--platform', inputs.platforms.join(','));
|
args.push('--platform', inputs.platforms.join(','));
|
||||||
}
|
}
|
||||||
if (await toolkit.buildx.versionSatisfies('>=0.10.0')) {
|
if (await toolkit.buildx.versionSatisfies('>=0.10.0')) {
|
||||||
if (inputs.provenance) {
|
args.push(...(await getAttestArgs(inputs, toolkit)));
|
||||||
args.push('--provenance', inputs.provenance);
|
|
||||||
} else if ((await toolkit.buildkit.versionSatisfies(inputs.builder, '>=0.11.0')) && !BuildxInputs.hasDockerExporter(inputs.outputs, inputs.load)) {
|
|
||||||
// if provenance not specified and BuildKit version compatible for
|
|
||||||
// attestation, set default provenance. Also needs to make sure user
|
|
||||||
// doesn't want to explicitly load the image to docker.
|
|
||||||
if (GitHub.context.payload.repository?.private ?? false) {
|
|
||||||
// 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
|
|
||||||
args.push('--provenance', BuildxInputs.resolveProvenanceAttrs(`mode=min,inline-only=true`));
|
|
||||||
} else {
|
} else {
|
||||||
// for a public repository, we set max provenance mode.
|
core.warning("Attestations are only supported by buildx >= 0.10.0; the inputs 'attests', 'provenance' and 'sbom' are ignored.");
|
||||||
args.push('--provenance', BuildxInputs.resolveProvenanceAttrs(`mode=max`));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (inputs.sbom) {
|
|
||||||
args.push('--sbom', inputs.sbom);
|
|
||||||
}
|
|
||||||
} else if (inputs.provenance || inputs.sbom) {
|
|
||||||
core.warning("Attestations are only supported by buildx >= 0.10.0; the inputs 'provenance' and 'sbom' are ignored.");
|
|
||||||
}
|
}
|
||||||
await Util.asyncForEach(inputs.secrets, async secret => {
|
await Util.asyncForEach(inputs.secrets, async secret => {
|
||||||
try {
|
try {
|
||||||
|
@ -238,3 +214,52 @@ async function getCommonArgs(inputs: Inputs, toolkit: Toolkit): Promise<Array<st
|
||||||
}
|
}
|
||||||
return args;
|
return args;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function getAttestArgs(inputs: Inputs, toolkit: Toolkit): Promise<Array<string>> {
|
||||||
|
const args: Array<string> = [];
|
||||||
|
|
||||||
|
// check if provenance attestation is set in attests input
|
||||||
|
let hasAttestProvenance = false;
|
||||||
|
await Util.asyncForEach(inputs.attests, async (attest: string) => {
|
||||||
|
if (BuildxInputs.hasAttestationType('provenance', attest)) {
|
||||||
|
hasAttestProvenance = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let provenanceSet = false;
|
||||||
|
let sbomSet = false;
|
||||||
|
if (inputs.provenance) {
|
||||||
|
args.push('--attest', BuildxInputs.resolveAttestationAttrs(`type=provenance,${inputs.provenance}`));
|
||||||
|
provenanceSet = true;
|
||||||
|
} else if (!hasAttestProvenance && (await toolkit.buildkit.versionSatisfies(inputs.builder, '>=0.11.0')) && !BuildxInputs.hasDockerExporter(inputs.outputs, inputs.load)) {
|
||||||
|
// if provenance not specified in provenance or attests inputs and BuildKit
|
||||||
|
// version compatible for attestation, set default provenance. Also needs
|
||||||
|
// to make sure user doesn't want to explicitly load the image to docker.
|
||||||
|
if (GitHub.context.payload.repository?.private ?? false) {
|
||||||
|
// 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
|
||||||
|
args.push('--attest', `type=provenance,${BuildxInputs.resolveProvenanceAttrs(`mode=min,inline-only=true`)}`);
|
||||||
|
} else {
|
||||||
|
// for a public repository, we set max provenance mode.
|
||||||
|
args.push('--attest', `type=provenance,${BuildxInputs.resolveProvenanceAttrs(`mode=max`)}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (inputs.sbom) {
|
||||||
|
args.push('--attest', BuildxInputs.resolveAttestationAttrs(`type=sbom,${inputs.sbom}`));
|
||||||
|
sbomSet = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set attests but check if provenance or sbom types already set as
|
||||||
|
// provenance and sbom inputs take precedence over attests input.
|
||||||
|
await Util.asyncForEach(inputs.attests, async (attest: string) => {
|
||||||
|
if (!BuildxInputs.hasAttestationType('provenance', attest) && !BuildxInputs.hasAttestationType('sbom', attest)) {
|
||||||
|
args.push('--attest', BuildxInputs.resolveAttestationAttrs(attest));
|
||||||
|
} else if (!provenanceSet && BuildxInputs.hasAttestationType('provenance', attest)) {
|
||||||
|
args.push('--attest', BuildxInputs.resolveProvenanceAttrs(attest));
|
||||||
|
} else if (!sbomSet && BuildxInputs.hasAttestationType('sbom', attest)) {
|
||||||
|
args.push('--attest', attest);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue