@@ -18,7 +18,11 @@ import {beforeAll, describe, expect, jest, it, test} from '@jest/globals';
1818import fs from 'fs' ;
1919import * as path from 'path' ;
2020
21+ import { Buildx } from '../../src/buildx/buildx' ;
22+ import { Build } from '../../src/buildx/build' ;
2123import { Install as CosignInstall } from '../../src/cosign/install' ;
24+ import { Docker } from '../../src/docker/docker' ;
25+ import { Exec } from '../../src/exec' ;
2226import { Sigstore } from '../../src/sigstore/sigstore' ;
2327
2428const fixturesDir = path . join ( __dirname , '..' , '.fixtures' ) ;
@@ -39,6 +43,57 @@ beforeAll(async () => {
3943 await cosignInstall . install ( cosignBinPath ) ;
4044} , 100000 ) ;
4145
46+ maybeIdToken ( 'signAttestationManifests' , ( ) => {
47+ it ( 'build, sign and verify' , async ( ) => {
48+ const buildx = new Buildx ( ) ;
49+ const build = new Build ( { buildx : buildx } ) ;
50+ const imageName = 'ghcr.io/docker/actions-toolkit/test' ;
51+
52+ await expect (
53+ ( async ( ) => {
54+ await Docker . getExecOutput ( [ 'login' , '--password-stdin' , '--username' , process . env . GITHUB_REPOSITORY_OWNER || 'docker' , 'ghcr.io' ] , {
55+ input : Buffer . from ( process . env . GITHUB_TOKEN || '' )
56+ } ) ;
57+ } ) ( )
58+ ) . resolves . not . toThrow ( ) ;
59+
60+ await expect (
61+ ( async ( ) => {
62+ // prettier-ignore
63+ const buildCmd = await buildx . getCommand ( [
64+ '--builder' , process . env . CTN_BUILDER_NAME ?? 'default' ,
65+ 'build' ,
66+ '-f' , path . join ( fixturesDir , 'hello.Dockerfile' ) ,
67+ '--provenance=mode=max' ,
68+ '--tag' , `${ imageName } :sigstore-itg` ,
69+ '--platform' , 'linux/amd64,linux/arm64' ,
70+ '--push' ,
71+ '--metadata-file' , build . getMetadataFilePath ( ) ,
72+ fixturesDir
73+ ] ) ;
74+ await Exec . exec ( buildCmd . command , buildCmd . args ) ;
75+ } ) ( )
76+ ) . resolves . not . toThrow ( ) ;
77+
78+ const metadata = build . resolveMetadata ( ) ;
79+ expect ( metadata ) . toBeDefined ( ) ;
80+ const buildDigest = build . resolveDigest ( metadata ) ;
81+ expect ( buildDigest ) . toBeDefined ( ) ;
82+
83+ const sigstore = new Sigstore ( ) ;
84+ const signResults = await sigstore . signAttestationManifests ( {
85+ imageNames : [ imageName ] ,
86+ imageDigest : buildDigest !
87+ } ) ;
88+ expect ( Object . keys ( signResults ) . length ) . toEqual ( 2 ) ;
89+
90+ const verifyResults = await sigstore . verifySignedManifests ( signResults , {
91+ certificateIdentityRegexp : `^https://github.com/docker/actions-toolkit/.github/workflows/test.yml.*$`
92+ } ) ;
93+ expect ( Object . keys ( verifyResults ) . length ) . toEqual ( 2 ) ;
94+ } , 100000 ) ;
95+ } ) ;
96+
4297maybe ( 'verifyImageAttestations' , ( ) => {
4398 test . each ( [
4499 [ 'moby/buildkit:master@sha256:84014da3581b2ff2c14cb4f60029cf9caa272b79e58f2e89c651ea6966d7a505' , `^https://github.com/docker/github-builder-experimental/.github/workflows/bake.yml.*$` ] ,
0 commit comments