From 93a6a428d18b157f6cd988811166ca5d7c9be82b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C4=9Bj=20Chalk?= Date: Fri, 29 Nov 2024 14:00:39 +0100 Subject: [PATCH] feat(ci): add nxProjectsFilter option, forwards custom filters to Nx CLI --- packages/ci/README.md | 27 ++++++++++--------- packages/ci/src/lib/constants.ts | 1 + packages/ci/src/lib/models.ts | 1 + packages/ci/src/lib/monorepo/handlers/nx.ts | 17 +++++++++--- packages/ci/src/lib/monorepo/list-projects.ts | 1 + .../lib/monorepo/list-projects.unit.test.ts | 10 +++++++ packages/ci/src/lib/monorepo/tools.ts | 1 + 7 files changed, 42 insertions(+), 16 deletions(-) diff --git a/packages/ci/README.md b/packages/ci/README.md index 7bccec24f..3a5831254 100644 --- a/packages/ci/README.md +++ b/packages/ci/README.md @@ -94,23 +94,26 @@ A `Comment` object has the following required properties: Optionally, you can override default options for further customization: -| Property | Type | Default | Description | -| :---------------- | :------------------------ | :------------------------------- | :----------------------------------------------------------------------------------- | -| `monorepo` | `boolean \| MonorepoTool` | `false` | Enables [monorepo mode](#monorepo-mode) | -| `projects` | `string[] \| null` | `null` | Custom projects configuration for [monorepo mode](#monorepo-mode) | -| `task` | `string` | `'code-pushup'` | Name of command to run Code PushUp per project in [monorepo mode](#monorepo-mode) | -| `directory` | `string` | `process.cwd()` | Directory in which Code PushUp CLI should run | -| `config` | `string \| null` | `null` [^1] | Path to config file (`--config` option) | -| `silent` | `boolean` | `false` | Toggles if logs from CLI commands are printed | -| `bin` | `string` | `'npx --no-install code-pushup'` | Command for executing Code PushUp CLI | -| `detectNewIssues` | `boolean` | `true` | Toggles if new issues should be detected and returned in `newIssues` property | -| `logger` | `Logger` | `console` | Logger for reporting progress and encountered problems | -| `output` | `string` | `'.code-pushup'` | Directory where Code PushUp reports will be created (interpolates project name [^2]) | +| Property | Type | Default | Description | +| :----------------- | :------------------------ | :------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `monorepo` | `boolean \| MonorepoTool` | `false` | Enables [monorepo mode](#monorepo-mode) | +| `projects` | `string[] \| null` | `null` | Custom projects configuration for [monorepo mode](#monorepo-mode) | +| `task` | `string` | `'code-pushup'` | Name of command to run Code PushUp per project in [monorepo mode](#monorepo-mode) | +| `nxProjectsFilter` | `string \| string[]` | `'--with-target={task}'` | Arguments passed to [`nx show projects`](https://nx.dev/nx-api/nx/documents/show#projects), only relevant for Nx in [monorepo mode](#monorepo-mode) [^3] | +| `directory` | `string` | `process.cwd()` | Directory in which Code PushUp CLI should run | +| `config` | `string \| null` | `null` [^1] | Path to config file (`--config` option) | +| `silent` | `boolean` | `false` | Toggles if logs from CLI commands are printed | +| `bin` | `string` | `'npx --no-install code-pushup'` | Command for executing Code PushUp CLI | +| `detectNewIssues` | `boolean` | `true` | Toggles if new issues should be detected and returned in `newIssues` property | +| `logger` | `Logger` | `console` | Logger for reporting progress and encountered problems | +| `output` | `string` | `'.code-pushup'` | Directory where Code PushUp reports will be created (interpolates project name [^2]) | [^1]: By default, the `code-pushup.config` file is autodetected as described in [`@code-pushup/cli` docs](../cli/README.md#configuration). [^2]: In monorepo mode, any occurrence of `{project}` in the `output` path will be replaced with a project name. This separation of folders per project (e.g. `output: '.code-pushup/{project}'`) may be useful for caching purposes. +[^3]: The `{task}` pattern is replaced with the `task` value, so the default behaviour is to list projects using `npx nx show projects --with-target=code-pushup --json`. The `nxProjectsFilter` options gives Nx users the flexibility to filter projects in alternative ways supported by the Nx CLI (e.g. `--affected`, `--projects`, `--exclude`, `--type`) - refer to [options in Nx docs](https://nx.dev/nx-api/nx/documents/show#options) for details. + The `Logger` object has the following required properties: | Property | Type | Description | diff --git a/packages/ci/src/lib/constants.ts b/packages/ci/src/lib/constants.ts index b3d5d8396..6aab3dfd2 100644 --- a/packages/ci/src/lib/constants.ts +++ b/packages/ci/src/lib/constants.ts @@ -13,4 +13,5 @@ export const DEFAULT_SETTINGS: Settings = { detectNewIssues: true, logger: console, output: DEFAULT_PERSIST_OUTPUT_DIR, + nxProjectsFilter: '--with-target={task}', }; diff --git a/packages/ci/src/lib/models.ts b/packages/ci/src/lib/models.ts index 724f4322e..ecd79a586 100644 --- a/packages/ci/src/lib/models.ts +++ b/packages/ci/src/lib/models.ts @@ -9,6 +9,7 @@ export type Options = { monorepo?: boolean | MonorepoTool; projects?: string[] | null; task?: string; + nxProjectsFilter?: string | string[]; bin?: string; config?: string | null; directory?: string; diff --git a/packages/ci/src/lib/monorepo/handlers/nx.ts b/packages/ci/src/lib/monorepo/handlers/nx.ts index dc641a348..dac746bab 100644 --- a/packages/ci/src/lib/monorepo/handlers/nx.ts +++ b/packages/ci/src/lib/monorepo/handlers/nx.ts @@ -1,5 +1,10 @@ import { join } from 'node:path'; -import { executeProcess, fileExists, stringifyError } from '@code-pushup/utils'; +import { + executeProcess, + fileExists, + stringifyError, + toArray, +} from '@code-pushup/utils'; import type { MonorepoToolHandler } from '../tools'; export const nxHandler: MonorepoToolHandler = { @@ -9,24 +14,28 @@ export const nxHandler: MonorepoToolHandler = { (await fileExists(join(options.cwd, 'nx.json'))) && ( await executeProcess({ - ...options, command: 'npx', args: ['nx', 'report'], + cwd: options.cwd, + observer: options.observer, }) ).code === 0 ); }, async listProjects(options) { const { stdout } = await executeProcess({ - ...options, command: 'npx', args: [ 'nx', 'show', 'projects', - `--with-target=${options.task}`, + ...toArray(options.nxProjectsFilter).map(arg => + arg.replaceAll('{task}', options.task), + ), '--json', ], + cwd: options.cwd, + observer: options.observer, }); const projects = parseProjects(stdout); return projects.map(project => ({ diff --git a/packages/ci/src/lib/monorepo/list-projects.ts b/packages/ci/src/lib/monorepo/list-projects.ts index 6b95a5500..65791e63a 100644 --- a/packages/ci/src/lib/monorepo/list-projects.ts +++ b/packages/ci/src/lib/monorepo/list-projects.ts @@ -61,6 +61,7 @@ function createMonorepoHandlerOptions( return { task: settings.task, cwd: settings.directory, + nxProjectsFilter: settings.nxProjectsFilter, ...(!settings.silent && { observer: { onStdout: stdout => { diff --git a/packages/ci/src/lib/monorepo/list-projects.unit.test.ts b/packages/ci/src/lib/monorepo/list-projects.unit.test.ts index 23b20b920..619bce098 100644 --- a/packages/ci/src/lib/monorepo/list-projects.unit.test.ts +++ b/packages/ci/src/lib/monorepo/list-projects.unit.test.ts @@ -14,6 +14,7 @@ describe('listMonorepoProjects', () => { monorepo: true, projects: null, task: 'code-pushup', + nxProjectsFilter: '--with-target={task}', directory: MEMFS_VOLUME, bin: 'npx --no-install code-pushup', logger: { @@ -56,6 +57,15 @@ describe('listMonorepoProjects', () => { { name: 'backend', bin: 'npx nx run backend:code-pushup --' }, { name: 'frontend', bin: 'npx nx run frontend:code-pushup --' }, ] satisfies ProjectConfig[]); + + expect(utils.executeProcess).toHaveBeenCalledWith< + Parameters<(typeof utils)['executeProcess']> + >({ + command: 'npx', + args: ['nx', 'show', 'projects', '--with-target=code-pushup', '--json'], + cwd: process.cwd(), + observer: expect.any(Object), + }); }); it('should detect projects in Turborepo which have code-pushup command', async () => { diff --git a/packages/ci/src/lib/monorepo/tools.ts b/packages/ci/src/lib/monorepo/tools.ts index 6dd307c60..435315eb0 100644 --- a/packages/ci/src/lib/monorepo/tools.ts +++ b/packages/ci/src/lib/monorepo/tools.ts @@ -13,6 +13,7 @@ export type MonorepoHandlerOptions = { task: string; cwd: string; observer?: ProcessObserver; + nxProjectsFilter: string | string[]; }; export type ProjectConfig = {