From 76dc9c39490a32f5ac442fafe286111afb8307b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CJamesHenry=E2=80=9D?= Date: Fri, 5 May 2023 13:09:48 +0100 Subject: [PATCH 1/3] feat(libnpmpublish): expose provenance transparency url --- workspaces/libnpmpublish/lib/publish.js | 27 +++++++++++++++++++----- workspaces/libnpmpublish/test/publish.js | 6 ++++++ 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/workspaces/libnpmpublish/lib/publish.js b/workspaces/libnpmpublish/lib/publish.js index 89ca01662cdb5..0c1e27bdc3f47 100644 --- a/workspaces/libnpmpublish/lib/publish.js +++ b/workspaces/libnpmpublish/lib/publish.js @@ -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 @@ -138,6 +148,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), @@ -178,8 +189,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) @@ -190,7 +204,10 @@ const buildMetadata = async (registry, manifest, tarballData, spec, opts) => { } } - return root + return { + metadata: root, + transparencyLogUrl, + } } const patchMetadata = (current, newData) => { diff --git a/workspaces/libnpmpublish/test/publish.js b/workspaces/libnpmpublish/test/publish.js index 065765807b889..fa68f4d98052d 100644 --- a/workspaces/libnpmpublish/test/publish.js +++ b/workspaces/libnpmpublish/test/publish.js @@ -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 => { @@ -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'], From 1c2c058e4c5924775d67946dad1573af46c8d890 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CJamesHenry=E2=80=9D?= Date: Fri, 5 May 2023 15:58:14 +0100 Subject: [PATCH 2/3] chore: apply transparency url in 409 retry case --- workspaces/libnpmpublish/lib/publish.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/workspaces/libnpmpublish/lib/publish.js b/workspaces/libnpmpublish/lib/publish.js index 0c1e27bdc3f47..289148bec71ba 100644 --- a/workspaces/libnpmpublish/lib/publish.js +++ b/workspaces/libnpmpublish/lib/publish.js @@ -74,12 +74,16 @@ 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, }) + if (transparencyLogUrl) { + res.transparencyLogUrl = transparencyLogUrl + } + return res } } From 638ecac75b47eb11eddd4e61eeccd47c4a7574a2 Mon Sep 17 00:00:00 2001 From: James Henry Date: Fri, 5 May 2023 20:11:48 +0400 Subject: [PATCH 3/3] chore: update workspaces/libnpmpublish/lib/publish.js Co-authored-by: Gar --- workspaces/libnpmpublish/lib/publish.js | 1 + 1 file changed, 1 insertion(+) diff --git a/workspaces/libnpmpublish/lib/publish.js b/workspaces/libnpmpublish/lib/publish.js index 289148bec71ba..d36b7fe6c374f 100644 --- a/workspaces/libnpmpublish/lib/publish.js +++ b/workspaces/libnpmpublish/lib/publish.js @@ -80,6 +80,7 @@ Remove the 'private' field from the package.json to publish it.`), body: newMetadata, ignoreBody: true, }) + /* istanbul ignore next */ if (transparencyLogUrl) { res.transparencyLogUrl = transparencyLogUrl }