@@ -70,6 +70,7 @@ var buildTests = []func(t *testing.T, sb integration.Sandbox){
7070 testBuildShmSize ,
7171 testBuildUlimit ,
7272 testBuildMetadataProvenance ,
73+ testBuildMetadataProvenanceMultiplatform ,
7374 testBuildMetadataWarnings ,
7475 testBuildMultiExporters ,
7576 testBuildLoadPush ,
@@ -967,6 +968,101 @@ func buildMetadataProvenance(t *testing.T, sb integration.Sandbox, metadataMode
967968 require .Equal (t , provenancetypes .BuildKitBuildType02 , prv .BuildType )
968969}
969970
971+ func testBuildMetadataProvenanceMultiplatform (t * testing.T , sb integration.Sandbox ) {
972+ t .Run ("default" , func (t * testing.T ) {
973+ buildMetadataProvenanceMultiplatform (t , sb , "" )
974+ })
975+ t .Run ("max" , func (t * testing.T ) {
976+ buildMetadataProvenanceMultiplatform (t , sb , "max" )
977+ })
978+ t .Run ("min" , func (t * testing.T ) {
979+ buildMetadataProvenanceMultiplatform (t , sb , "min" )
980+ })
981+ t .Run ("disabled" , func (t * testing.T ) {
982+ buildMetadataProvenanceMultiplatform (t , sb , "disabled" )
983+ })
984+ }
985+
986+ func buildMetadataProvenanceMultiplatform (t * testing.T , sb integration.Sandbox , metadataMode string ) {
987+ if isMobyWorker (sb ) {
988+ t .Skip ("multi-platform build is not supported" )
989+ }
990+
991+ dockerfile := []byte (`
992+ FROM --platform=$BUILDPLATFORM busybox:latest AS base
993+ COPY foo /etc/foo
994+ RUN cp /etc/foo /etc/bar
995+
996+ FROM scratch
997+ COPY --from=base /etc/bar /bar
998+ ` )
999+ dir := tmpdir (
1000+ t ,
1001+ fstest .CreateFile ("Dockerfile" , dockerfile , 0600 ),
1002+ fstest .CreateFile ("foo" , []byte ("foo" ), 0600 ),
1003+ )
1004+
1005+ registry , err := sb .NewRegistry ()
1006+ if errors .Is (err , integration .ErrRequirements ) {
1007+ t .Skip (err .Error ())
1008+ }
1009+ require .NoError (t , err )
1010+ target := registry + "/buildx/registry:latest"
1011+
1012+ cmd := buildxCmd (sb ,
1013+ withArgs ("build" ,
1014+ "--platform=linux/amd64,linux/arm64" ,
1015+ "--metadata-file" , filepath .Join (dir , "md.json" ),
1016+ fmt .Sprintf ("--output=type=image,name=%s,push=true" , target ),
1017+ dir ,
1018+ ),
1019+ withEnv ("BUILDX_METADATA_PROVENANCE=" + metadataMode ),
1020+ )
1021+
1022+ out , err := cmd .CombinedOutput ()
1023+ require .NoError (t , err , string (out ))
1024+
1025+ desc , provider , err := contentutil .ProviderFromRef (target )
1026+ require .NoError (t , err )
1027+ imgs , err := testutil .ReadImages (sb .Context (), provider , desc )
1028+ require .NoError (t , err )
1029+
1030+ img := imgs .Find ("linux/amd64" )
1031+ require .NotNil (t , img )
1032+ img = imgs .Find ("linux/arm64" )
1033+ require .NotNil (t , img )
1034+
1035+ dt , err := os .ReadFile (filepath .Join (dir , "md.json" ))
1036+ require .NoError (t , err )
1037+
1038+ type mdT struct {
1039+ BuildRef string `json:"buildx.build.ref"`
1040+ BuildProvenanceAmd64 map [string ]any `json:"buildx.build.provenance/linux/amd64"`
1041+ BuildProvenanceArm64 map [string ]any `json:"buildx.build.provenance/linux/arm64"`
1042+ }
1043+ var md mdT
1044+ err = json .Unmarshal (dt , & md )
1045+ require .NoError (t , err )
1046+
1047+ require .NotEmpty (t , md .BuildRef )
1048+ if metadataMode == "disabled" {
1049+ require .Empty (t , md .BuildProvenanceAmd64 )
1050+ require .Empty (t , md .BuildProvenanceArm64 )
1051+ return
1052+ }
1053+ require .NotEmpty (t , md .BuildProvenanceAmd64 )
1054+ require .NotEmpty (t , md .BuildProvenanceArm64 )
1055+
1056+ for _ , prov := range []map [string ]any {md .BuildProvenanceAmd64 , md .BuildProvenanceArm64 } {
1057+ dtprv , err := json .Marshal (prov )
1058+ require .NoError (t , err )
1059+
1060+ var prv provenancetypes.ProvenancePredicateSLSA02
1061+ require .NoError (t , json .Unmarshal (dtprv , & prv ))
1062+ require .Equal (t , provenancetypes .BuildKitBuildType02 , prv .BuildType )
1063+ }
1064+ }
1065+
9701066func testBuildMetadataWarnings (t * testing.T , sb integration.Sandbox ) {
9711067 t .Run ("default" , func (t * testing.T ) {
9721068 buildMetadataWarnings (t , sb , "" )
0 commit comments