@@ -7,7 +7,7 @@ const { URL } = require('url')
7
7
const ssri = require ( 'ssri' )
8
8
const ciInfo = require ( 'ci-info' )
9
9
10
- const { generateProvenance } = require ( './provenance' )
10
+ const { generateProvenance, verifyProvenance } = require ( './provenance' )
11
11
12
12
const TLOG_BASE_URL = 'https://search.sigstore.dev/'
13
13
@@ -111,7 +111,7 @@ const patchManifest = (_manifest, opts) => {
111
111
}
112
112
113
113
const buildMetadata = async ( registry , manifest , tarballData , spec , opts ) => {
114
- const { access, defaultTag, algorithms, provenance } = opts
114
+ const { access, defaultTag, algorithms, provenance, provenanceFile } = opts
115
115
const root = {
116
116
_id : manifest . name ,
117
117
name : manifest . name ,
@@ -154,66 +154,31 @@ const buildMetadata = async (registry, manifest, tarballData, spec, opts) => {
154
154
155
155
// Handle case where --provenance flag was set to true
156
156
let transparencyLogUrl
157
- if ( provenance === true ) {
157
+ if ( provenance === true || provenanceFile ) {
158
+ let provenanceBundle
158
159
const subject = {
159
160
name : npa . toPurl ( spec ) ,
160
161
digest : { sha512 : integrity . sha512 [ 0 ] . hexDigest ( ) } ,
161
162
}
162
163
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
+ )
194
179
}
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 )
217
182
}
218
183
219
184
const serializedBundle = JSON . stringify ( provenanceBundle )
@@ -275,4 +240,49 @@ const patchMetadata = (current, newData) => {
275
240
return current
276
241
}
277
242
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
+
278
288
module . exports = publish
0 commit comments