Skip to content

Commit

Permalink
fix: Update publish /w provenance to ignore pkg vis 404 (#6437)
Browse files Browse the repository at this point in the history
Some registries (e.g. GH packages) require auth to check visibility,
and always return 404 when no auth is supplied. In this case we assume
the package is always private and require `--access public` to publish.

I've also updated this to only perform a visibility check when this is
actually needed (i.e. when `provenance` is true and `access` is not `public`).

Fixes #6436
  • Loading branch information
feelepxyz authored May 10, 2023
1 parent bdab631 commit f064696
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 3 deletions.
19 changes: 17 additions & 2 deletions workspaces/libnpmpublish/lib/publish.js
Original file line number Diff line number Diff line change
Expand Up @@ -177,8 +177,23 @@ const buildMetadata = async (registry, manifest, tarballData, spec, opts) => {
)
}

const visibility =
await npmFetch.json(`${registry}/-/package/${spec.escapedName}/visibility`, opts)
// Some registries (e.g. GH packages) require auth to check visibility,
// and always return 404 when no auth is supplied. In this case we assume
// the package is always private and require `--access public` to publish
// with provenance.
let visibility = { public: false }
if (opts.provenance === true && opts.access !== 'public') {
try {
const res = await npmFetch
.json(`${registry}/-/package/${spec.escapedName}/visibility`, opts)
visibility = res
} catch (err) {
if (err.code !== 'E404') {
throw err
}
}
}

if (!visibility.public && opts.provenance === true && opts.access !== 'public') {
throw Object.assign(
/* eslint-disable-next-line max-len */
Expand Down
75 changes: 74 additions & 1 deletion workspaces/libnpmpublish/test/publish.js
Original file line number Diff line number Diff line change
Expand Up @@ -776,7 +776,6 @@ t.test('publish existing package with provenance in gha', async t => {
.post('/api/v1/log/entries')
.reply(201, rekorEntry)

registry.getVisibility({ spec, visibility: { public: true } })
registry.nock.put(`/${spec.escapedName}`, body => {
const bundleAttachment = body._attachments['@npmcli/libnpmpublish-test-1.0.0.sigstore']
const bundle = JSON.parse(bundleAttachment.data)
Expand Down Expand Up @@ -855,6 +854,80 @@ t.test('publish new/private package with provenance in gha - no access', async t
)
})

t.test('publish new package with provenance in gha when visibility 404s - no access', async t => {
const oidcURL = 'https://mock.oidc'
const requestToken = 'decafbad'
mockGlobals(t, {
'process.env': {
CI: true,
GITHUB_ACTIONS: true,
ACTIONS_ID_TOKEN_REQUEST_URL: oidcURL,
ACTIONS_ID_TOKEN_REQUEST_TOKEN: requestToken,
},
})
const { publish } = t.mock('..', { 'ci-info': t.mock('ci-info') })
const registry = new MockRegistry({
tap: t,
registry: opts.registry,
authorization: token,
strict: true,
})
const manifest = {
name: '@npmcli/libnpmpublish-test',
version: '1.0.0',
description: 'test libnpmpublish package',
}
const spec = npa(manifest.name)
registry.nock.get(`/-/package/${npa(spec).escapedName}/visibility`)
.reply(404)

await t.rejects(
publish(manifest, Buffer.from(''), {
...opts,
access: null,
provenance: true,
}),
{ code: 'EUSAGE' }
)
})

t.test('publish new package with provenance in gha when visibility 500s - no access', async t => {
const oidcURL = 'https://mock.oidc'
const requestToken = 'decafbad'
mockGlobals(t, {
'process.env': {
CI: true,
GITHUB_ACTIONS: true,
ACTIONS_ID_TOKEN_REQUEST_URL: oidcURL,
ACTIONS_ID_TOKEN_REQUEST_TOKEN: requestToken,
},
})
const { publish } = t.mock('..', { 'ci-info': t.mock('ci-info') })
const registry = new MockRegistry({
tap: t,
registry: opts.registry,
authorization: token,
strict: true,
})
const manifest = {
name: '@npmcli/libnpmpublish-test',
version: '1.0.0',
description: 'test libnpmpublish package',
}
const spec = npa(manifest.name)
registry.nock.get(`/-/package/${npa(spec).escapedName}/visibility`)
.reply(500)

await t.rejects(
publish(manifest, Buffer.from(''), {
...opts,
access: null,
provenance: true,
}),
{ code: 'E500' }
)
})

t.test('automatic provenance in unsupported environment', async t => {
mockGlobals(t, {
'process.env': {
Expand Down

0 comments on commit f064696

Please sign in to comment.