Skip to content

Commit 97a603c

Browse files
committed
feat(ci): filter nx run-many by projects from nx show projects as fallback
1 parent e221655 commit 97a603c

File tree

11 files changed

+154
-47
lines changed

11 files changed

+154
-47
lines changed

packages/ci/src/lib/monorepo/handlers/npm.unit.test.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
import { vol } from 'memfs';
22
import type { PackageJson } from 'type-fest';
33
import { MEMFS_VOLUME } from '@code-pushup/test-utils';
4-
import type { MonorepoHandlerOptions, ProjectConfig } from '../tools';
4+
import type {
5+
MonorepoHandlerOptions,
6+
MonorepoHandlerProjectsContext,
7+
ProjectConfig,
8+
} from '../tools';
59
import { npmHandler } from './npm';
610

711
describe('npmHandler', () => {
@@ -169,8 +173,15 @@ describe('npmHandler', () => {
169173
});
170174

171175
describe('createRunManyCommand', () => {
176+
const projects: MonorepoHandlerProjectsContext = {
177+
all: [
178+
{ name: 'api', bin: 'npm --workspace=api run code-pushup --' },
179+
{ name: 'ui', bin: 'npm --workspace=ui run code-pushup --' },
180+
],
181+
};
182+
172183
it('should create command to run npm script for all workspaces', () => {
173-
expect(npmHandler.createRunManyCommand(options)).toBe(
184+
expect(npmHandler.createRunManyCommand(options, projects)).toBe(
174185
'npm run code-pushup --workspaces --if-present --',
175186
);
176187
});

packages/ci/src/lib/monorepo/handlers/nx.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,15 +47,16 @@ export const nxHandler: MonorepoToolHandler = {
4747
}));
4848
},
4949

50-
createRunManyCommand(options, onlyProjects) {
50+
createRunManyCommand(options, projects) {
51+
const projectNames: string[] =
52+
projects.only ?? projects.all.map(({ name }) => name);
5153
return [
5254
'npx',
5355
'nx',
54-
'run-many', // TODO: allow affected instead of run-many?
56+
'run-many',
5557
`--targets=${options.task}`,
56-
// TODO: add options.nxRunManyFilter? (e.g. --exclude=...)
57-
...(onlyProjects ? [`--projects=${onlyProjects.join(',')}`] : []),
5858
`--parallel=${options.parallel}`,
59+
`--projects=${projectNames.join(',')}`,
5960
'--',
6061
].join(' ');
6162
},

packages/ci/src/lib/monorepo/handlers/nx.unit.test.ts

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
import { vol } from 'memfs';
22
import { MEMFS_VOLUME } from '@code-pushup/test-utils';
33
import * as utils from '@code-pushup/utils';
4-
import type { MonorepoHandlerOptions, ProjectConfig } from '../tools';
4+
import type {
5+
MonorepoHandlerOptions,
6+
MonorepoHandlerProjectsContext,
7+
ProjectConfig,
8+
} from '../tools';
59
import { nxHandler } from './nx';
610

711
describe('nxHandler', () => {
@@ -113,27 +117,46 @@ describe('nxHandler', () => {
113117
});
114118

115119
describe('createRunManyCommand', () => {
116-
it('should run script for all projects sequentially by default', () => {
117-
expect(nxHandler.createRunManyCommand(options)).toBe(
118-
'npx nx run-many --targets=code-pushup --parallel=false --',
120+
const projects: MonorepoHandlerProjectsContext = {
121+
all: [
122+
{ name: 'backend', bin: 'npx nx run backend:code-pushup --' },
123+
{ name: 'frontend', bin: 'npx nx run frontend:code-pushup --' },
124+
],
125+
};
126+
127+
it('should run script for all listed projects sequentially by default', () => {
128+
expect(nxHandler.createRunManyCommand(options, projects)).toBe(
129+
'npx nx run-many --targets=code-pushup --parallel=false --projects=backend,frontend --',
119130
);
120131
});
121132

122133
it('should set parallel flag with default number of tasks', () => {
123134
expect(
124-
nxHandler.createRunManyCommand({ ...options, parallel: true }),
125-
).toBe('npx nx run-many --targets=code-pushup --parallel=true --');
135+
nxHandler.createRunManyCommand(
136+
{ ...options, parallel: true },
137+
projects,
138+
),
139+
).toBe(
140+
'npx nx run-many --targets=code-pushup --parallel=true --projects=backend,frontend --',
141+
);
126142
});
127143

128144
it('should set parallel flag with custom number of tasks', () => {
129-
expect(nxHandler.createRunManyCommand({ ...options, parallel: 5 })).toBe(
130-
'npx nx run-many --targets=code-pushup --parallel=5 --',
145+
expect(
146+
nxHandler.createRunManyCommand({ ...options, parallel: 5 }, projects),
147+
).toBe(
148+
'npx nx run-many --targets=code-pushup --parallel=5 --projects=backend,frontend --',
131149
);
132150
});
133151

134152
it('should filter projects by list of project names', () => {
135-
expect(nxHandler.createRunManyCommand(options, ['web', 'cms'])).toBe(
136-
'npx nx run-many --targets=code-pushup --projects=web,cms --parallel=false --',
153+
expect(
154+
nxHandler.createRunManyCommand(options, {
155+
...projects,
156+
only: ['frontend'],
157+
}),
158+
).toBe(
159+
'npx nx run-many --targets=code-pushup --parallel=false --projects=frontend --',
137160
);
138161
});
139162
});

packages/ci/src/lib/monorepo/handlers/pnpm.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ export const pnpmHandler: MonorepoToolHandler = {
4444
}));
4545
},
4646

47-
createRunManyCommand(options, onlyProjects) {
47+
createRunManyCommand(options, projects) {
4848
const workspaceConcurrency: number =
4949
options.parallel === true
5050
? DEFAULT_WORKSPACE_CONCURRENCY
@@ -55,7 +55,7 @@ export const pnpmHandler: MonorepoToolHandler = {
5555
'pnpm',
5656
'--recursive',
5757
`--workspace-concurrency=${workspaceConcurrency}`,
58-
...(onlyProjects?.map(project => `--filter=${project}`) ?? []),
58+
...(projects.only?.map(project => `--filter=${project}`) ?? []),
5959
options.task,
6060
].join(' ');
6161
},

packages/ci/src/lib/monorepo/handlers/pnpm.unit.test.ts

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
import { vol } from 'memfs';
22
import type { PackageJson } from 'type-fest';
33
import { MEMFS_VOLUME } from '@code-pushup/test-utils';
4-
import type { MonorepoHandlerOptions, ProjectConfig } from '../tools';
4+
import type {
5+
MonorepoHandlerOptions,
6+
MonorepoHandlerProjectsContext,
7+
ProjectConfig,
8+
} from '../tools';
59
import { pnpmHandler } from './pnpm';
610

711
describe('pnpmHandler', () => {
@@ -160,27 +164,43 @@ describe('pnpmHandler', () => {
160164
});
161165

162166
describe('createRunManyCommand', () => {
167+
const projects: MonorepoHandlerProjectsContext = {
168+
all: [
169+
{ name: 'backend', bin: 'pnpm --filter=backend run code-pushup' },
170+
{ name: 'frontend', bin: 'pnpm --filter=frontend run code-pushup' },
171+
{ name: 'shared', bin: 'pnpm --filter=shared run code-pushup' },
172+
],
173+
};
174+
163175
it('should run script for all workspace packages sequentially by default', () => {
164-
expect(pnpmHandler.createRunManyCommand(options)).toBe(
176+
expect(pnpmHandler.createRunManyCommand(options, projects)).toBe(
165177
'pnpm --recursive --workspace-concurrency=1 code-pushup',
166178
);
167179
});
168180

169181
it('should set parallel flag with default number of jobs', () => {
170182
expect(
171-
pnpmHandler.createRunManyCommand({ ...options, parallel: true }),
183+
pnpmHandler.createRunManyCommand(
184+
{ ...options, parallel: true },
185+
projects,
186+
),
172187
).toBe('pnpm --recursive --workspace-concurrency=4 code-pushup');
173188
});
174189

175190
it('should set parallel flag with custom number of jobs', () => {
176191
expect(
177-
pnpmHandler.createRunManyCommand({ ...options, parallel: 5 }),
192+
pnpmHandler.createRunManyCommand({ ...options, parallel: 5 }, projects),
178193
).toBe('pnpm --recursive --workspace-concurrency=5 code-pushup');
179194
});
180195

181196
it('should filter workspace packages by list of project names', () => {
182-
expect(pnpmHandler.createRunManyCommand(options, ['core', 'utils'])).toBe(
183-
'pnpm --recursive --workspace-concurrency=1 --filter=core --filter=utils code-pushup',
197+
expect(
198+
pnpmHandler.createRunManyCommand(options, {
199+
...projects,
200+
only: ['frontend', 'shared'],
201+
}),
202+
).toBe(
203+
'pnpm --recursive --workspace-concurrency=1 --filter=frontend --filter=shared code-pushup',
184204
);
185205
});
186206
});

packages/ci/src/lib/monorepo/handlers/turbo.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ export const turboHandler: MonorepoToolHandler = {
4545
);
4646
},
4747

48-
createRunManyCommand(options, onlyProjects) {
48+
createRunManyCommand(options, projects) {
4949
const concurrency: number =
5050
options.parallel === true
5151
? DEFAULT_CONCURRENCY
@@ -57,7 +57,7 @@ export const turboHandler: MonorepoToolHandler = {
5757
'turbo',
5858
'run',
5959
options.task,
60-
...(onlyProjects?.map(project => `--filter=${project}`) ?? []),
60+
...(projects.only?.map(project => `--filter=${project}`) ?? []),
6161
`--concurrency=${concurrency}`,
6262
'--',
6363
].join(' ');

packages/ci/src/lib/monorepo/handlers/turbo.unit.test.ts

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
import { vol } from 'memfs';
22
import type { PackageJson } from 'type-fest';
33
import { MEMFS_VOLUME } from '@code-pushup/test-utils';
4-
import type { MonorepoHandlerOptions, ProjectConfig } from '../tools';
4+
import type {
5+
MonorepoHandlerOptions,
6+
MonorepoHandlerProjectsContext,
7+
ProjectConfig,
8+
} from '../tools';
59
import { turboHandler } from './turbo';
610

711
describe('turboHandler', () => {
@@ -158,27 +162,46 @@ describe('turboHandler', () => {
158162
});
159163

160164
describe('createRunManyCommand', () => {
165+
const projects: MonorepoHandlerProjectsContext = {
166+
all: [
167+
{ name: 'api', bin: 'npx turbo run code-pushup --filter=api --' },
168+
{ name: 'cms', bin: 'npx turbo run code-pushup --filter=cms --' },
169+
{ name: 'web', bin: 'npx turbo run code-pushup --filter=web --' },
170+
],
171+
};
172+
161173
it('should run script for all projects sequentially by default', () => {
162-
expect(turboHandler.createRunManyCommand(options)).toBe(
174+
expect(turboHandler.createRunManyCommand(options, projects)).toBe(
163175
'npx turbo run code-pushup --concurrency=1 --',
164176
);
165177
});
166178

167179
it('should set parallel flag with default number of jobs', () => {
168180
expect(
169-
turboHandler.createRunManyCommand({ ...options, parallel: true }),
181+
turboHandler.createRunManyCommand(
182+
{ ...options, parallel: true },
183+
projects,
184+
),
170185
).toBe('npx turbo run code-pushup --concurrency=10 --');
171186
});
172187

173188
it('should set parallel flag with custom number of jobs', () => {
174189
expect(
175-
turboHandler.createRunManyCommand({ ...options, parallel: 5 }),
190+
turboHandler.createRunManyCommand(
191+
{ ...options, parallel: 5 },
192+
projects,
193+
),
176194
).toBe('npx turbo run code-pushup --concurrency=5 --');
177195
});
178196

179197
it('should filter projects by list of project names', () => {
180-
expect(turboHandler.createRunManyCommand(options, ['web', 'cms'])).toBe(
181-
'npx turbo run code-pushup --filter=web --filter=cms --concurrency=1 --',
198+
expect(
199+
turboHandler.createRunManyCommand(options, {
200+
...projects,
201+
only: ['cms', 'web'],
202+
}),
203+
).toBe(
204+
'npx turbo run code-pushup --filter=cms --filter=web --concurrency=1 --',
182205
);
183206
});
184207
});

packages/ci/src/lib/monorepo/handlers/yarn.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ export const yarnHandler: MonorepoToolHandler = {
3535
}));
3636
},
3737

38-
async createRunManyCommand(options, onlyProjects) {
38+
async createRunManyCommand(options, projects) {
3939
const { stdout } = await executeProcess({ command: 'yarn', args: ['-v'] });
4040
const isV1 = stdout.startsWith('1.');
4141

@@ -52,7 +52,7 @@ export const yarnHandler: MonorepoToolHandler = {
5252
...(typeof options.parallel === 'number'
5353
? [`--jobs=${options.parallel}`]
5454
: []),
55-
...(onlyProjects?.map(project => `--include=${project}`) ?? ['--all']),
55+
...(projects.only?.map(project => `--include=${project}`) ?? ['--all']),
5656
options.task,
5757
].join(' ');
5858
},

packages/ci/src/lib/monorepo/handlers/yarn.unit.test.ts

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@ import { vol } from 'memfs';
22
import type { PackageJson } from 'type-fest';
33
import { MEMFS_VOLUME } from '@code-pushup/test-utils';
44
import * as utils from '@code-pushup/utils';
5-
import type { MonorepoHandlerOptions, ProjectConfig } from '../tools';
5+
import type {
6+
MonorepoHandlerOptions,
7+
MonorepoHandlerProjectsContext,
8+
ProjectConfig,
9+
} from '../tools';
610
import { yarnHandler } from './yarn';
711

812
describe('yarnHandler', () => {
@@ -171,6 +175,14 @@ describe('yarnHandler', () => {
171175
});
172176

173177
describe('createRunManyCommand', () => {
178+
const projects: MonorepoHandlerProjectsContext = {
179+
all: [
180+
{ name: 'api', bin: 'yarn workspace api run code-pushup' },
181+
{ name: 'cms', bin: 'yarn workspace cms run code-pushup' },
182+
{ name: 'web', bin: 'yarn workspace web run code-pushup' },
183+
],
184+
};
185+
174186
// eslint-disable-next-line vitest/max-nested-describe
175187
describe('classic Yarn (v1)', () => {
176188
beforeEach(() => {
@@ -180,9 +192,9 @@ describe('yarnHandler', () => {
180192
});
181193

182194
it('should run script for all workspaces sequentially', async () => {
183-
await expect(yarnHandler.createRunManyCommand(options)).resolves.toBe(
184-
'yarn workspaces run code-pushup',
185-
);
195+
await expect(
196+
yarnHandler.createRunManyCommand(options, projects),
197+
).resolves.toBe('yarn workspaces run code-pushup');
186198
});
187199
});
188200

@@ -195,30 +207,39 @@ describe('yarnHandler', () => {
195207
});
196208

197209
it('should run script for all workspaces sequentially by default', async () => {
198-
await expect(yarnHandler.createRunManyCommand(options)).resolves.toBe(
199-
'yarn workspaces foreach --all code-pushup',
200-
);
210+
await expect(
211+
yarnHandler.createRunManyCommand(options, projects),
212+
).resolves.toBe('yarn workspaces foreach --all code-pushup');
201213
});
202214

203215
it('should set parallel flag with default number of jobs', async () => {
204216
await expect(
205-
yarnHandler.createRunManyCommand({ ...options, parallel: true }),
217+
yarnHandler.createRunManyCommand(
218+
{ ...options, parallel: true },
219+
projects,
220+
),
206221
).resolves.toBe('yarn workspaces foreach --parallel --all code-pushup');
207222
});
208223

209224
it('should set parallel flag with custom number of jobs', async () => {
210225
await expect(
211-
yarnHandler.createRunManyCommand({ ...options, parallel: 5 }),
226+
yarnHandler.createRunManyCommand(
227+
{ ...options, parallel: 5 },
228+
projects,
229+
),
212230
).resolves.toBe(
213231
'yarn workspaces foreach --parallel --jobs=5 --all code-pushup',
214232
);
215233
});
216234

217235
it('should filter workspaces by list of project names', async () => {
218236
await expect(
219-
yarnHandler.createRunManyCommand(options, ['core', 'utils']),
237+
yarnHandler.createRunManyCommand(options, {
238+
...projects,
239+
only: ['api', 'cms'],
240+
}),
220241
).resolves.toBe(
221-
'yarn workspaces foreach --include=core --include=utils code-pushup',
242+
'yarn workspaces foreach --include=api --include=cms code-pushup',
222243
);
223244
});
224245
});

0 commit comments

Comments
 (0)