@@ -7,7 +7,7 @@ const { URL } = require('url')
77const ssri = require ( 'ssri' )
88const ciInfo = require ( 'ci-info' )
99
10- const { generateProvenance } = require ( './provenance' )
10+ const { generateProvenance, verifyProvenance } = require ( './provenance' )
1111
1212const TLOG_BASE_URL = 'https://search.sigstore.dev/'
1313
@@ -111,7 +111,7 @@ const patchManifest = (_manifest, opts) => {
111111}
112112
113113const buildMetadata = async ( registry , manifest , tarballData , spec , opts ) => {
114- const { access, defaultTag, algorithms, provenance } = opts
114+ const { access, defaultTag, algorithms, provenance, provenanceFile } = opts
115115 const root = {
116116 _id : manifest . name ,
117117 name : manifest . name ,
@@ -154,66 +154,31 @@ const buildMetadata = async (registry, manifest, tarballData, spec, opts) => {
154154
155155 // Handle case where --provenance flag was set to true
156156 let transparencyLogUrl
157- if ( provenance === true ) {
157+ if ( provenance === true || provenanceFile ) {
158+ let provenanceBundle
158159 const subject = {
159160 name : npa . toPurl ( spec ) ,
160161 digest : { sha512 : integrity . sha512 [ 0 ] . hexDigest ( ) } ,
161162 }
162163
163- // Ensure that we're running in GHA, currently the only supported build environment
164- if ( ciInfo . name !== 'GitHub Actions' ) {
165- throw Object . assign (
166- new Error ( 'Automatic provenance generation not supported outside of GitHub Actions' ) ,
167- { code : 'EUSAGE' }
168- )
169- }
170-
171- // Ensure that the GHA OIDC token is available
172- if ( ! process . env . ACTIONS_ID_TOKEN_REQUEST_URL ) {
173- throw Object . assign (
174- /* eslint-disable-next-line max-len */
175- new Error ( 'Provenance generation in GitHub Actions requires "write" access to the "id-token" permission' ) ,
176- { code : 'EUSAGE' }
177- )
178- }
179-
180- // Some registries (e.g. GH packages) require auth to check visibility,
181- // and always return 404 when no auth is supplied. In this case we assume
182- // the package is always private and require `--access public` to publish
183- // with provenance.
184- let visibility = { public : false }
185- if ( opts . provenance === true && opts . access !== 'public' ) {
186- try {
187- const res = await npmFetch
188- . json ( `${ registry } /-/package/${ spec . escapedName } /visibility` , opts )
189- visibility = res
190- } catch ( err ) {
191- if ( err . code !== 'E404' ) {
192- throw err
193- }
164+ if ( provenance === true ) {
165+ await ensureProvenanceGeneration ( registry , spec , opts )
166+ provenanceBundle = await generateProvenance ( [ subject ] , opts )
167+
168+ /* eslint-disable-next-line max-len */
169+ log . notice ( 'publish' , 'Signed provenance statement with source and build information from GitHub Actions' )
170+
171+ const tlogEntry = provenanceBundle ?. verificationMaterial ?. tlogEntries [ 0 ]
172+ /* istanbul ignore else */
173+ if ( tlogEntry ) {
174+ transparencyLogUrl = `${ TLOG_BASE_URL } ?logIndex=${ tlogEntry . logIndex } `
175+ log . notice (
176+ 'publish' ,
177+ `Provenance statement published to transparency log: ${ transparencyLogUrl } `
178+ )
194179 }
195- }
196-
197- if ( ! visibility . public && opts . provenance === true && opts . access !== 'public' ) {
198- throw Object . assign (
199- /* eslint-disable-next-line max-len */
200- new Error ( "Can't generate provenance for new or private package, you must set `access` to public." ) ,
201- { code : 'EUSAGE' }
202- )
203- }
204- const provenanceBundle = await generateProvenance ( [ subject ] , opts )
205-
206- /* eslint-disable-next-line max-len */
207- log . notice ( 'publish' , 'Signed provenance statement with source and build information from GitHub Actions' )
208-
209- const tlogEntry = provenanceBundle ?. verificationMaterial ?. tlogEntries [ 0 ]
210- /* istanbul ignore else */
211- if ( tlogEntry ) {
212- transparencyLogUrl = `${ TLOG_BASE_URL } ?logIndex=${ tlogEntry . logIndex } `
213- log . notice (
214- 'publish' ,
215- `Provenance statement published to transparency log: ${ transparencyLogUrl } `
216- )
180+ } else {
181+ provenanceBundle = await verifyProvenance ( subject , provenanceFile )
217182 }
218183
219184 const serializedBundle = JSON . stringify ( provenanceBundle )
@@ -275,4 +240,49 @@ const patchMetadata = (current, newData) => {
275240 return current
276241}
277242
243+ // Check that all the prereqs are met for provenance generation
244+ const ensureProvenanceGeneration = async ( registry , spec , opts ) => {
245+ // Ensure that we're running in GHA, currently the only supported build environment
246+ if ( ciInfo . name !== 'GitHub Actions' ) {
247+ throw Object . assign (
248+ new Error ( 'Automatic provenance generation not supported outside of GitHub Actions' ) ,
249+ { code : 'EUSAGE' }
250+ )
251+ }
252+
253+ // Ensure that the GHA OIDC token is available
254+ if ( ! process . env . ACTIONS_ID_TOKEN_REQUEST_URL ) {
255+ throw Object . assign (
256+ /* eslint-disable-next-line max-len */
257+ new Error ( 'Provenance generation in GitHub Actions requires "write" access to the "id-token" permission' ) ,
258+ { code : 'EUSAGE' }
259+ )
260+ }
261+
262+ // Some registries (e.g. GH packages) require auth to check visibility,
263+ // and always return 404 when no auth is supplied. In this case we assume
264+ // the package is always private and require `--access public` to publish
265+ // with provenance.
266+ let visibility = { public : false }
267+ if ( true && opts . access !== 'public' ) {
268+ try {
269+ const res = await npmFetch
270+ . json ( `${ registry } /-/package/${ spec . escapedName } /visibility` , opts )
271+ visibility = res
272+ } catch ( err ) {
273+ if ( err . code !== 'E404' ) {
274+ throw err
275+ }
276+ }
277+ }
278+
279+ if ( ! visibility . public && opts . provenance === true && opts . access !== 'public' ) {
280+ throw Object . assign (
281+ /* eslint-disable-next-line max-len */
282+ new Error ( "Can't generate provenance for new or private package, you must set `access` to public." ) ,
283+ { code : 'EUSAGE' }
284+ )
285+ }
286+ }
287+
278288module . exports = publish
0 commit comments