From feddc88d74781a448855a5a0b0ffa50917489b15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Wed, 22 Mar 2023 07:36:52 +0100 Subject: [PATCH] Call `pnpm publish` directly from the directory of the published package (#1115) --- .changeset/curly-fans-fly.md | 5 +++ .../cli/src/commands/publish/npm-utils.ts | 34 +++++++++++++------ .../src/commands/publish/publishPackages.ts | 12 +++---- 3 files changed, 34 insertions(+), 17 deletions(-) create mode 100644 .changeset/curly-fans-fly.md diff --git a/.changeset/curly-fans-fly.md b/.changeset/curly-fans-fly.md new file mode 100644 index 000000000..3c0e83495 --- /dev/null +++ b/.changeset/curly-fans-fly.md @@ -0,0 +1,5 @@ +--- +"@changesets/cli": patch +--- + +Call `pnpm publish` directly from the directory of the published package. This allows `pnpm` to correctly handle configured `publishConfig.directory`. diff --git a/packages/cli/src/commands/publish/npm-utils.ts b/packages/cli/src/commands/publish/npm-utils.ts index 4b78d93d2..297d9d0a3 100644 --- a/packages/cli/src/commands/publish/npm-utils.ts +++ b/packages/cli/src/commands/publish/npm-utils.ts @@ -1,6 +1,6 @@ import { ExitError } from "@changesets/errors"; import { error, info, warn } from "@changesets/logger"; -import { PackageJSON } from "@changesets/types"; +import { AccessType, PackageJSON } from "@changesets/types"; import pLimit from "p-limit"; import preferredPM from "preferred-pm"; import chalk from "chalk"; @@ -11,6 +11,13 @@ import isCI from "is-ci"; import { TwoFactorState } from "../../utils/types"; import { getLastJsonObjectFromString } from "../../utils/getLastJsonObjectFromString"; +interface PublishOptions { + cwd: string; + publishDir: string; + access: AccessType; + tag: string; +} + const npmRequestLimit = pLimit(40); const npmPublishLimit = pLimit(10); @@ -155,12 +162,13 @@ export let getOtpCode = async (twoFactorState: TwoFactorState) => { // the call being wrapped in the npm request limit and causing the publishes to potentially never run async function internalPublish( pkgName: string, - opts: { cwd: string; access?: string; tag: string }, + opts: PublishOptions, twoFactorState: TwoFactorState ): Promise<{ published: boolean }> { let publishTool = await getPublishTool(opts.cwd); let publishFlags = opts.access ? ["--access", opts.access] : []; publishFlags.push("--tag", opts.tag); + if ((await twoFactorState.isRequired) && !isCI) { let otpCode = await getOtpCode(twoFactorState); publishFlags.push("--otp", otpCode); @@ -174,13 +182,19 @@ async function internalPublish( const envOverride = { npm_config_registry: getCorrectRegistry(), }; - let { code, stdout, stderr } = await spawn( - publishTool.name, - ["publish", opts.cwd, "--json", ...publishFlags], - { - env: Object.assign({}, process.env, envOverride), - } - ); + let { code, stdout, stderr } = + publishTool.name === "pnpm" + ? await spawn("pnpm", ["publish", "--json", ...publishFlags], { + env: Object.assign({}, process.env, envOverride), + cwd: opts.cwd, + }) + : await spawn( + publishTool.name, + ["publish", opts.publishDir, "--json", ...publishFlags], + { + env: Object.assign({}, process.env, envOverride), + } + ); if (code !== 0) { // NPM's --json output is included alongside the `prepublish` and `postpublish` output in terminal // We want to handle this as best we can but it has some struggles: @@ -222,7 +236,7 @@ async function internalPublish( export function publish( pkgName: string, - opts: { cwd: string; access?: string; tag: string }, + opts: PublishOptions, twoFactorState: TwoFactorState ): Promise<{ published: boolean }> { // If there are many packages to be published, it's better to limit the diff --git a/packages/cli/src/commands/publish/publishPackages.ts b/packages/cli/src/commands/publish/publishPackages.ts index 62b6d8a31..6b6d31580 100644 --- a/packages/cli/src/commands/publish/publishPackages.ts +++ b/packages/cli/src/commands/publish/publishPackages.ts @@ -122,20 +122,18 @@ async function publishAPackage( tag: string ): Promise { const { name, version, publishConfig } = pkg.packageJson; - const localAccess = publishConfig?.access; info( `Publishing ${chalk.cyan(`"${name}"`)} at ${chalk.green(`"${version}"`)}` ); - const publishDir = publishConfig?.directory - ? join(pkg.dir, publishConfig.directory) - : pkg.dir; - const publishConfirmation = await npmUtils.publish( name, { - cwd: publishDir, - access: localAccess || access, + cwd: pkg.dir, + publishDir: publishConfig?.directory + ? join(pkg.dir, publishConfig.directory) + : pkg.dir, + access: publishConfig?.access || access, tag, }, twoFactorState