diff --git a/docs/usage/configuration-options.md b/docs/usage/configuration-options.md index 9bb09058e75cc4f491bd9742b583996c92cda6be..89b984479b673916299a8a2b8b5bb6e6eca246a0 100644 --- a/docs/usage/configuration-options.md +++ b/docs/usage/configuration-options.md @@ -2168,6 +2168,7 @@ Table with options: | `gomodTidyE` | Run `go mod tidy -e` after Go module updates. | | `gomodUpdateImportPaths` | Update source import paths on major module updates, using [mod](https://github.com/marwan-at-work/mod). | | `npmDedupe` | Run `npm dedupe` after `package-lock.json` updates. | +| `pnpmDedupe` | Run `pnpm dedupe` after `pnpm-lock.yaml` updates. | | `yarnDedupeFewer` | Run `yarn-deduplicate --strategy fewer` after `yarn.lock` updates. | | `yarnDedupeHighest` | Run `yarn-deduplicate --strategy highest` (`yarn dedupe --strategy highest` for Yarn >=2.2.0) after `yarn.lock` updates. | diff --git a/lib/config/options/index.ts b/lib/config/options/index.ts index ec1f31ecd569bae7ddeb1e6cd579f2c497fb26f9..9d8f7c315c4fc5048f1944c996b28fce09eb79de 100644 --- a/lib/config/options/index.ts +++ b/lib/config/options/index.ts @@ -1996,6 +1996,7 @@ const options: RenovateOptions[] = [ 'gomodTidy1.17', 'gomodTidyE', 'npmDedupe', + 'pnpmDedupe', 'yarnDedupeFewer', 'yarnDedupeHighest', ], diff --git a/lib/modules/manager/npm/post-update/pnpm.spec.ts b/lib/modules/manager/npm/post-update/pnpm.spec.ts index cacdcbc3a7f1fdbf902b3841b0d40926b36b9073..8f5091329b7dfe3819996877e10f778a529d4c45 100644 --- a/lib/modules/manager/npm/post-update/pnpm.spec.ts +++ b/lib/modules/manager/npm/post-update/pnpm.spec.ts @@ -69,6 +69,27 @@ describe('modules/manager/npm/post-update/pnpm', () => { expect(execSnapshots).toMatchSnapshot(); }); + it('performs dedupe', async () => { + const execSnapshots = mockExecAll(); + fs.readLocalFile.mockResolvedValue('package-lock-contents'); + const postUpdateOptions = ['pnpmDedupe']; + const res = await pnpmHelper.generateLockFile( + 'some-dir', + {}, + { ...config, postUpdateOptions } + ); + expect(fs.readLocalFile).toHaveBeenCalledTimes(1); + expect(res.lockFile).toBe('package-lock-contents'); + expect(execSnapshots).toMatchObject([ + { + cmd: 'pnpm install --recursive --lockfile-only --ignore-scripts --ignore-pnpmfile', + }, + { + cmd: 'pnpm dedupe', + }, + ]); + }); + it('uses the new version if packageManager is updated', async () => { const execSnapshots = mockExecAll(); fs.readLocalFile.mockResolvedValue('package-lock-contents'); diff --git a/lib/modules/manager/npm/post-update/pnpm.ts b/lib/modules/manager/npm/post-update/pnpm.ts index 4cb2e7d19bff9ed9214c67d1411b66faf1aabec3..8f0845c7054e70b6d046558da1888a32a43eb01b 100644 --- a/lib/modules/manager/npm/post-update/pnpm.ts +++ b/lib/modules/manager/npm/post-update/pnpm.ts @@ -53,6 +53,8 @@ export async function generateLockFile( extraEnv.NPM_AUTH = env.NPM_AUTH; extraEnv.NPM_EMAIL = env.NPM_EMAIL; } + const commands: string[] = []; + cmd = 'pnpm'; let args = 'install --recursive --lockfile-only'; if (!GlobalConfig.get('allowScripts') || config.ignoreScripts) { @@ -60,6 +62,13 @@ export async function generateLockFile( args += ' --ignore-pnpmfile'; } logger.trace({ cmd, args }, 'pnpm command'); + commands.push(`${cmd} ${args}`); + + // postUpdateOptions + if (config.postUpdateOptions?.includes('pnpmDedupe')) { + logger.debug('Performing pnpm dedupe'); + commands.push('pnpm dedupe'); + } if (upgrades.find((upgrade) => upgrade.isLockFileMaintenance)) { logger.debug( @@ -75,7 +84,7 @@ export async function generateLockFile( } } - await exec(`${cmd} ${args}`, execOptions); + await exec(commands, execOptions); lockFile = await readLocalFile(lockFileName, 'utf8'); } catch (err) /* istanbul ignore next */ { if (err.message === TEMPORARY_ERROR) {