diff --git a/.changeset/chatty-rivers-roll.md b/.changeset/chatty-rivers-roll.md new file mode 100644 index 0000000000..01170026b6 --- /dev/null +++ b/.changeset/chatty-rivers-roll.md @@ -0,0 +1,5 @@ +--- +"@pnpm/run-npm": patch +--- + +If running npm errors, throw an error. diff --git a/.changeset/nasty-baboons-return.md b/.changeset/nasty-baboons-return.md new file mode 100644 index 0000000000..22407731c9 --- /dev/null +++ b/.changeset/nasty-baboons-return.md @@ -0,0 +1,6 @@ +--- +"@pnpm/plugin-commands-publishing": patch +"pnpm": patch +--- + +`pnpm publish` should work correctly in a workspace, when the latest npm CLI is installed [#4348](https://github.com/pnpm/pnpm/issues/4348). diff --git a/packages/plugin-commands-publishing/package.json b/packages/plugin-commands-publishing/package.json index c9da4ec519..37043e5553 100644 --- a/packages/plugin-commands-publishing/package.json +++ b/packages/plugin-commands-publishing/package.json @@ -55,7 +55,6 @@ "load-json-file": "^6.2.0", "path-exists": "^4.0.0", "tar": "^6.1.4", - "tempy": "^1.0.0", "write-yaml-file": "^4.2.0" }, "dependencies": { @@ -81,6 +80,7 @@ "realpath-missing": "^1.1.0", "render-help": "^1.0.1", "tar-stream": "^2.2.0", + "tempy": "^1.0.0", "write-json-file": "^4.3.0" }, "peerDependencies": { diff --git a/packages/plugin-commands-publishing/src/pack.ts b/packages/plugin-commands-publishing/src/pack.ts index 60700dd23f..daffbb0a31 100644 --- a/packages/plugin-commands-publishing/src/pack.ts +++ b/packages/plugin-commands-publishing/src/pack.ts @@ -107,6 +107,9 @@ export async function handler ( if (!opts.ignoreScripts) { await _runScriptsIfPresent(['postpack'], entryManifest) } + if (opts.dir !== dir) { + return path.join(dir, tarballName) + } return path.relative(opts.dir, path.join(dir, tarballName)) } diff --git a/packages/plugin-commands-publishing/src/publish.ts b/packages/plugin-commands-publishing/src/publish.ts index 282a438472..94422f6074 100644 --- a/packages/plugin-commands-publishing/src/publish.ts +++ b/packages/plugin-commands-publishing/src/publish.ts @@ -11,6 +11,7 @@ import rimraf from '@zkochan/rimraf' import pick from 'ramda/src/pick' import realpathMissing from 'realpath-missing' import renderHelp from 'render-help' +import tempy from 'tempy' import * as pack from './pack' import recursivePublish, { PublishRecursiveOpts } from './recursivePublish' import { getCurrentBranch, isGitRepo, isRemoteHistoryClean, isWorkingTreeClean } from './gitChecks' @@ -186,23 +187,21 @@ Do you want to continue?`, } } + // We have to publish the tarball from another location. + // Otherwise, npm would publish the package with the package.json file + // from the current working directory, ignoring the package.json file + // that was generated and packed to the tarball. + const packDestination = tempy.directory() const tarballName = await pack.handler({ ...opts, dir, + packDestination, }) - const tarballDir = path.dirname(path.join(dir, tarballName)) - const localNpmrc = path.join(tarballDir, '.npmrc') - const copyNpmrc = !existsSync(localNpmrc) && opts.workspaceDir && existsSync(path.join(opts.workspaceDir, '.npmrc')) - if (copyNpmrc && opts.workspaceDir) { - await fs.copyFile(path.join(opts.workspaceDir, '.npmrc'), localNpmrc) - } + await copyNpmrc({ dir, workspaceDir: opts.workspaceDir, packDestination }) const { status } = runNpm(opts.npmPath, ['publish', '--ignore-scripts', path.basename(tarballName), ...args], { - cwd: tarballDir, + cwd: packDestination, }) - await rimraf(path.join(dir, tarballName)) - if (copyNpmrc) { - await rimraf(localNpmrc) - } + await rimraf(packDestination) if (status != null && status !== 0) { return { exitCode: status } @@ -216,6 +215,25 @@ Do you want to continue?`, return { manifest } } +async function copyNpmrc ( + { dir, workspaceDir, packDestination }: { + dir: string + workspaceDir?: string + packDestination: string + } +) { + const localNpmrc = path.join(dir, '.npmrc') + if (existsSync(localNpmrc)) { + await fs.copyFile(localNpmrc, path.join(packDestination, '.npmrc')) + return + } + if (!workspaceDir) return + const workspaceNpmrc = path.join(workspaceDir, '.npmrc') + if (existsSync(workspaceNpmrc)) { + await fs.copyFile(workspaceNpmrc, path.join(packDestination, '.npmrc')) + } +} + export async function runScriptsIfPresent ( opts: RunLifecycleHookOptions, scriptNames: string[], diff --git a/packages/run-npm/src/index.ts b/packages/run-npm/src/index.ts index 3b7124c3de..0058c771a8 100644 --- a/packages/run-npm/src/index.ts +++ b/packages/run-npm/src/index.ts @@ -26,9 +26,11 @@ export function runScriptSync ( } ) { opts = Object.assign({}, opts) - return spawn.sync(command, args, Object.assign({}, opts, { + const result = spawn.sync(command, args, Object.assign({}, opts, { env: createEnv(opts), })) + if (result.error) throw result.error + return result } function createEnv ( diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index eb28cea9d3..e56c8ee931 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2458,6 +2458,7 @@ importers: realpath-missing: 1.1.0 render-help: 1.0.2 tar-stream: 2.2.0 + tempy: 1.0.1 write-json-file: 4.3.0 devDependencies: '@pnpm/filter-workspace-packages': link:../filter-workspace-packages @@ -2480,7 +2481,6 @@ importers: load-json-file: 6.2.0 path-exists: 4.0.0 tar: 6.1.11 - tempy: 1.0.1 write-yaml-file: 4.2.0 packages/plugin-commands-rebuild: