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
					
				| @ -481,7 +481,7 @@ nproc=3`], | ||||
|       [ | ||||
|         'build', | ||||
|         '--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'), | ||||
|         '.' | ||||
|       ] | ||||
| @ -500,7 +500,7 @@ nproc=3`], | ||||
|       [ | ||||
|         'build', | ||||
|         '--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'), | ||||
|         '.' | ||||
|       ] | ||||
| @ -519,7 +519,7 @@ nproc=3`], | ||||
|       [ | ||||
|         'build', | ||||
|         '--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'), | ||||
|         '.' | ||||
|       ] | ||||
| @ -538,7 +538,7 @@ nproc=3`], | ||||
|       [ | ||||
|         'build', | ||||
|         '--iidfile', path.join(tmpDir, 'iidfile'), | ||||
|         "--provenance", 'false', | ||||
|         '--attest', 'type=provenance,disabled=true', | ||||
|         '--metadata-file', path.join(tmpDir, 'metadata-file'), | ||||
|         '.' | ||||
|       ] | ||||
| @ -557,7 +557,7 @@ nproc=3`], | ||||
|       [ | ||||
|         'build', | ||||
|         '--iidfile', path.join(tmpDir, 'iidfile'), | ||||
|         "--provenance", 'builder-id=foo', | ||||
|         '--attest', 'type=provenance,builder-id=foo', | ||||
|         '--metadata-file', path.join(tmpDir, 'metadata-file'), | ||||
|         '.' | ||||
|       ] | ||||
| @ -620,7 +620,7 @@ nproc=3`], | ||||
|       ] | ||||
|     ], | ||||
|     [ | ||||
|       25, | ||||
|       26, | ||||
|       '0.10.0', | ||||
|       new Map<string, string>([ | ||||
|         ['context', '.'], | ||||
| @ -642,7 +642,7 @@ ANOTHER_SECRET=ANOTHER_SECRET_ENV`] | ||||
|       ] | ||||
|     ], | ||||
|     [ | ||||
|       26, | ||||
|       27, | ||||
|       '0.10.0', | ||||
|       new Map<string, string>([ | ||||
|         ['context', '.'], | ||||
| @ -663,7 +663,7 @@ ANOTHER_SECRET=ANOTHER_SECRET_ENV`] | ||||
|       ] | ||||
|     ], | ||||
|     [ | ||||
|       27, | ||||
|       28, | ||||
|       '0.11.0', | ||||
|       new Map<string, string>([ | ||||
|         ['context', '.'], | ||||
| @ -677,13 +677,13 @@ ANOTHER_SECRET=ANOTHER_SECRET_ENV`] | ||||
|       [ | ||||
|         'build', | ||||
|         '--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'), | ||||
|         '.' | ||||
|       ] | ||||
|     ], | ||||
|     [ | ||||
|       28, | ||||
|       29, | ||||
|       '0.12.0', | ||||
|       new Map<string, string>([ | ||||
|         ['context', '.'], | ||||
| @ -701,13 +701,13 @@ ANOTHER_SECRET=ANOTHER_SECRET_ENV`] | ||||
|         '--annotation', 'manifest:example3=yyy', | ||||
|         '--annotation', 'manifest-descriptor[linux/amd64]:example4=zzz', | ||||
|         '--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'), | ||||
|         '.' | ||||
|       ] | ||||
|     ], | ||||
|     [ | ||||
|       29, | ||||
|       30, | ||||
|       '0.12.0', | ||||
|       new Map<string, string>([ | ||||
|         ['context', '.'], | ||||
| @ -721,11 +721,71 @@ ANOTHER_SECRET=ANOTHER_SECRET_ENV`] | ||||
|         'build', | ||||
|         '--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`, | ||||
|         "--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'), | ||||
|         '.' | ||||
|       ] | ||||
|     ], | ||||
|     [ | ||||
|       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', | ||||
|     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) { | ||||
|     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')) { | ||||
|     await Util.asyncForEach(inputs.annotations, async annotation => { | ||||
|       args.push('--annotation', annotation); | ||||
| @ -157,26 +150,9 @@ async function getBuildArgs(inputs: Inputs, context: string, toolkit: Toolkit): | ||||
|     args.push('--platform', inputs.platforms.join(',')); | ||||
|   } | ||||
|   if (await toolkit.buildx.versionSatisfies('>=0.10.0')) { | ||||
|     if (inputs.provenance) { | ||||
|       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`)); | ||||
|     args.push(...(await getAttestArgs(inputs, toolkit))); | ||||
|   } else { | ||||
|         // for a public repository, we set max provenance mode.
 | ||||
|         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."); | ||||
|     core.warning("Attestations are only supported by buildx >= 0.10.0; the inputs 'attests', 'provenance' and 'sbom' are ignored."); | ||||
|   } | ||||
|   await Util.asyncForEach(inputs.secrets, async secret => { | ||||
|     try { | ||||
| @ -238,3 +214,52 @@ async function getCommonArgs(inputs: Inputs, toolkit: Toolkit): Promise<Array<st | ||||
|   } | ||||
|   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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 CrazyMax
						CrazyMax