diff --git a/lib/commands/publish.js b/lib/commands/publish.js index 450c51858ba01..aea01cc10e7a1 100644 --- a/lib/commands/publish.js +++ b/lib/commands/publish.js @@ -83,6 +83,7 @@ class Publish extends BaseCommand { const json = this.npm.config.get('json') const defaultTag = this.npm.config.get('tag') const ignoreScripts = this.npm.config.get('ignore-scripts') + const scriptShell = this.npm.config.get('script-shell') || undefined const { silent } = this.npm if (semver.validRange(defaultTag)) { @@ -102,6 +103,7 @@ class Publish extends BaseCommand { path: spec.fetchSpec, stdio: 'inherit', pkg: manifest, + scriptShell, }) } @@ -218,6 +220,7 @@ class Publish extends BaseCommand { path: spec.fetchSpec, stdio: 'inherit', pkg: manifest, + scriptShell, }) await runScript({ @@ -225,6 +228,7 @@ class Publish extends BaseCommand { path: spec.fetchSpec, stdio: 'inherit', pkg: manifest, + scriptShell, }) } diff --git a/test/lib/commands/publish.js b/test/lib/commands/publish.js index acf8c4c96a93d..b204f7452a65d 100644 --- a/test/lib/commands/publish.js +++ b/test/lib/commands/publish.js @@ -1624,3 +1624,37 @@ t.test('oidc token exchange - provenance', (t) => { t.end() }) + +t.test('passes script-shell config to lifecycle hooks', async t => { + const CAPTURED = [] + const { npm, registry } = await loadNpmWithRegistry(t, { + config: { + ...auth, + 'script-shell': '/bin/bash', + }, + prefixDir: { + 'package.json': JSON.stringify({ + ...pkgJson, + scripts: { + prepublishOnly: 'exit 0', + publish: 'exit 0', + postpublish: 'exit 0', + }, + }), + }, + mocks: { + '@npmcli/run-script': async (opts) => { + CAPTURED.push(opts) + }, + }, + }) + + registry.publish(pkg, {}) + await npm.exec('publish', []) + + for (const event of ['prepublishOnly', 'publish', 'postpublish']) { + const rs = CAPTURED.find(r => r.event === event) + t.ok(rs, `ran ${event}`) + t.equal(rs?.scriptShell, '/bin/bash', `${event} receives scriptShell`) + } +})