Skip to content

Commit

Permalink
feat: expose provenance transparency url (#6428)
Browse files Browse the repository at this point in the history
* feat(libnpmpublish): expose provenance transparency url

* chore: apply transparency url in 409 retry case

* chore: update workspaces/libnpmpublish/lib/publish.js

Co-authored-by: Gar <wraithgar@github.com>

---------

Co-authored-by: Gar <wraithgar@github.com>
  • Loading branch information
JamesHenry and wraithgar authored May 5, 2023
1 parent 3d5bbcc commit bdab631
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 6 deletions.
34 changes: 28 additions & 6 deletions workspaces/libnpmpublish/lib/publish.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,25 @@ Remove the 'private' field from the package.json to publish it.`),
)
}

const metadata = await buildMetadata(reg, pubManifest, tarballData, spec, opts)
const { metadata, transparencyLogUrl } = await buildMetadata(
reg,
pubManifest,
tarballData,
spec,
opts
)

try {
return await npmFetch(spec.escapedName, {
const res = await npmFetch(spec.escapedName, {
...opts,
method: 'PUT',
body: metadata,
ignoreBody: true,
})
if (transparencyLogUrl) {
res.transparencyLogUrl = transparencyLogUrl
}
return res
} catch (err) {
if (err.code !== 'E409') {
throw err
Expand All @@ -64,12 +74,17 @@ Remove the 'private' field from the package.json to publish it.`),
query: { write: true },
})
const newMetadata = patchMetadata(current, metadata)
return npmFetch(spec.escapedName, {
const res = await npmFetch(spec.escapedName, {
...opts,
method: 'PUT',
body: newMetadata,
ignoreBody: true,
})
/* istanbul ignore next */
if (transparencyLogUrl) {
res.transparencyLogUrl = transparencyLogUrl
}
return res
}
}

Expand Down Expand Up @@ -138,6 +153,7 @@ const buildMetadata = async (registry, manifest, tarballData, spec, opts) => {
}

// Handle case where --provenance flag was set to true
let transparencyLogUrl
if (provenance === true) {
const subject = {
name: npa.toPurl(spec),
Expand Down Expand Up @@ -178,8 +194,11 @@ const buildMetadata = async (registry, manifest, tarballData, spec, opts) => {
const tlogEntry = provenanceBundle?.verificationMaterial?.tlogEntries[0]
/* istanbul ignore else */
if (tlogEntry) {
const logUrl = `${TLOG_BASE_URL}?logIndex=${tlogEntry.logIndex}`
log.notice('publish', `Provenance statement published to transparency log: ${logUrl}`)
transparencyLogUrl = `${TLOG_BASE_URL}?logIndex=${tlogEntry.logIndex}`
log.notice(
'publish',
`Provenance statement published to transparency log: ${transparencyLogUrl}`
)
}

const serializedBundle = JSON.stringify(provenanceBundle)
Expand All @@ -190,7 +209,10 @@ const buildMetadata = async (registry, manifest, tarballData, spec, opts) => {
}
}

return root
return {
metadata: root,
transparencyLogUrl,
}
}

const patchMetadata = (current, newData) => {
Expand Down
6 changes: 6 additions & 0 deletions workspaces/libnpmpublish/test/publish.js
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,7 @@ t.test('publish includes access', async t => {
})

t.ok(ret, 'publish succeeded')
t.notOk(ret.transparencyLogUrl, 'no transparencyLogUrl for non-provenance publish')
})

t.test('refuse if package is unscoped plus `restricted` access', async t => {
Expand Down Expand Up @@ -804,6 +805,11 @@ t.test('publish existing package with provenance in gha', async t => {
rekorURL: rekorURL,
})
t.ok(ret, 'publish succeeded')
t.equal(
ret.transparencyLogUrl,
'https://search.sigstore.dev/?logIndex=2513258',
'has appropriate transparencyLogUrl property'
)
t.match(log, [
['notice', 'publish',
'Signed provenance statement with source and build information from GitHub Actions'],
Expand Down

0 comments on commit bdab631

Please sign in to comment.