diff --git a/.changeset/long-dryers-run.md b/.changeset/long-dryers-run.md new file mode 100644 index 0000000000..55a71ee8c1 --- /dev/null +++ b/.changeset/long-dryers-run.md @@ -0,0 +1,5 @@ +--- +"@pnpm/plugin-commands-publishing": patch +--- + +Scripts should be executed upon the original package.json, when publishConfig.directory is set. diff --git a/packages/plugin-commands-publishing/src/pack.ts b/packages/plugin-commands-publishing/src/pack.ts index 4c7337626c..73c9fe7ff6 100644 --- a/packages/plugin-commands-publishing/src/pack.ts +++ b/packages/plugin-commands-publishing/src/pack.ts @@ -64,7 +64,7 @@ export async function handler ( workspaceDir?: string } ) { - const { manifest } = await readProjectManifest(opts.dir, opts) + const { manifest: entryManifest } = await readProjectManifest(opts.dir, opts) const _runScriptsIfPresent = runScriptsIfPresent.bind(null, { depPath: opts.dir, extraBinPaths: opts.extraBinPaths, @@ -80,25 +80,29 @@ export async function handler ( 'prepare', 'prepublishOnly', 'prepack', - ], manifest) + ], entryManifest) } + const dir = entryManifest.publishConfig?.directory + ? path.join(opts.dir, entryManifest.publishConfig.directory) + : opts.dir + const manifest = (opts.dir !== dir) ? (await readProjectManifest(dir, opts)).manifest : entryManifest const tarballName = `${manifest.name!.replace('@', '').replace('/', '-')}-${manifest.version!}.tgz` - const files = await packlist({ path: opts.dir }) - const filesMap: Record = fromPairs(files.map((file) => [`package/${file}`, path.join(opts.dir, file)])) - if (opts.workspaceDir != null && opts.dir !== opts.workspaceDir && !files.some((file) => /LICEN[CS]E(\..+)?/i.test(file))) { + const files = await packlist({ path: dir }) + const filesMap: Record = fromPairs(files.map((file) => [`package/${file}`, path.join(dir, file)])) + if (opts.workspaceDir != null && dir !== opts.workspaceDir && !files.some((file) => /LICEN[CS]E(\..+)?/i.test(file))) { const licenses = await findLicenses({ cwd: opts.workspaceDir }) for (const license of licenses) { filesMap[`package/${license}`] = path.join(opts.workspaceDir, license) } } const destDir = opts.packDestination - ? (path.isAbsolute(opts.packDestination) ? opts.packDestination : path.join(opts.dir, opts.packDestination ?? '.')) - : opts.dir - await packPkg(path.join(destDir, tarballName), filesMap, opts.dir) + ? (path.isAbsolute(opts.packDestination) ? opts.packDestination : path.join(dir, opts.packDestination ?? '.')) + : dir + await packPkg(path.join(destDir, tarballName), filesMap, dir) if (!opts.ignoreScripts) { - await _runScriptsIfPresent(['postpack'], manifest) + await _runScriptsIfPresent(['postpack'], entryManifest) } - return tarballName + return path.relative(opts.dir, path.join(dir, tarballName)) } async function packPkg (destFile: string, filesMap: Record, projectDir: string): Promise { diff --git a/packages/plugin-commands-publishing/src/publish.ts b/packages/plugin-commands-publishing/src/publish.ts index 0ca1027554..1525462c1d 100644 --- a/packages/plugin-commands-publishing/src/publish.ts +++ b/packages/plugin-commands-publishing/src/publish.ts @@ -172,21 +172,20 @@ Do you want to continue?`, } } - const cwd = manifest.publishConfig?.directory ? path.join(dir, manifest.publishConfig.directory) : dir - const localNpmrc = path.join(cwd, '.npmrc') + const tarballName = await pack.handler({ + ...opts, + dir, + }) + 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) } - - const tarballName = await pack.handler({ - ...opts, - dir: cwd, + const { status } = runNpm(opts.npmPath, ['publish', '--ignore-scripts', path.basename(tarballName), ...args], { + cwd: tarballDir, }) - const { status } = runNpm(opts.npmPath, ['publish', '--ignore-scripts', tarballName, ...args], { - cwd, - }) - await rimraf(path.join(cwd, tarballName)) + await rimraf(path.join(dir, tarballName)) if (copyNpmrc) { await rimraf(localNpmrc) } diff --git a/packages/plugin-commands-publishing/test/publish.ts b/packages/plugin-commands-publishing/test/publish.ts index 8d8c2f002d..0355773bb4 100644 --- a/packages/plugin-commands-publishing/test/publish.ts +++ b/packages/plugin-commands-publishing/test/publish.ts @@ -1,4 +1,4 @@ -import { promises as fs } from 'fs' +import { existsSync, promises as fs } from 'fs' import path from 'path' import execa from 'execa' import isCI from 'is-ci' @@ -297,6 +297,10 @@ test('publish: package with publishConfig.directory', async () => { name: 'test-publish-config-directory', version: '1.0.0', + scripts: { + prepublishOnly: 'node --eval="const fs=require(\'fs\');fs.mkdirSync(\'dist\',{recursive:true});fs.writeFileSync(\'dist/prepublishOnly\', \'\', \'utf8\')"', + }, + publishConfig: { directory: 'dist', }, @@ -311,12 +315,10 @@ test('publish: package with publishConfig.directory', async () => { await fs.writeFile( path.join(testPublishConfigDirectory.dir(), 'dist/package.json'), - ` - { - "name": "publish_config_directory_dist_package", - "version": "1.0.0" - } - `, + JSON.stringify({ + name: 'publish_config_directory_dist_package', + version: '1.0.0', + }), { encoding: 'utf-8', } @@ -340,6 +342,7 @@ test('publish: package with publishConfig.directory', async () => { name: 'publish_config_directory_dist_package', version: '1.0.0', }) + expect(existsSync('node_modules/publish_config_directory_dist_package/prepublishOnly')).toBeTruthy() }) test.skip('publish package that calls executable from the workspace .bin folder in prepublishOnly script', async () => {