nx 19.6.3 → 19.6.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/package.json +12 -12
  2. package/release/changelog-renderer/index.d.ts +1 -1
  3. package/release/changelog-renderer/index.js +46 -11
  4. package/schemas/nx-schema.json +5 -0
  5. package/src/command-line/graph/graph.js +35 -18
  6. package/src/command-line/import/command-object.js +4 -0
  7. package/src/command-line/import/import.d.ts +4 -0
  8. package/src/command-line/import/import.js +147 -12
  9. package/src/command-line/import/utils/prepare-source-repo.d.ts +1 -1
  10. package/src/command-line/import/utils/prepare-source-repo.js +31 -85
  11. package/src/command-line/release/changelog.js +52 -11
  12. package/src/command-line/release/command-object.d.ts +1 -0
  13. package/src/command-line/release/command-object.js +6 -1
  14. package/src/command-line/release/config/version-plans.d.ts +14 -1
  15. package/src/command-line/release/config/version-plans.js +33 -1
  16. package/src/command-line/release/index.d.ts +6 -4
  17. package/src/command-line/release/plan-check.js +8 -61
  18. package/src/command-line/release/plan.js +131 -37
  19. package/src/command-line/release/release.js +1 -1
  20. package/src/command-line/release/utils/get-touched-projects-for-group.d.ts +7 -0
  21. package/src/command-line/release/utils/get-touched-projects-for-group.js +78 -0
  22. package/src/command-line/release/utils/git.d.ts +1 -1
  23. package/src/command-line/release/utils/git.js +45 -18
  24. package/src/command-line/release/version.js +1 -1
  25. package/src/daemon/server/sync-generators.d.ts +4 -0
  26. package/src/daemon/server/sync-generators.js +172 -52
  27. package/src/executors/run-commands/run-commands.impl.js +8 -3
  28. package/src/hasher/node-task-hasher-impl.d.ts +1 -1
  29. package/src/hasher/node-task-hasher-impl.js +34 -16
  30. package/src/native/nx.wasm32-wasi.wasm +0 -0
  31. package/src/plugins/js/project-graph/build-dependencies/target-project-locator.js +8 -1
  32. package/src/project-graph/plugins/isolation/plugin-pool.js +1 -1
  33. package/src/tasks-runner/default-tasks-runner.js +1 -1
  34. package/src/tasks-runner/init-tasks-runner.d.ts +2 -0
  35. package/src/tasks-runner/init-tasks-runner.js +1 -0
  36. package/src/tasks-runner/life-cycles/invoke-runner-terminal-output-life-cycle.d.ts +4 -6
  37. package/src/tasks-runner/life-cycles/invoke-runner-terminal-output-life-cycle.js +5 -0
  38. package/src/tasks-runner/task-env.d.ts +3 -3
  39. package/src/tasks-runner/task-env.js +3 -3
  40. package/src/tasks-runner/task-orchestrator.d.ts +2 -1
  41. package/src/tasks-runner/task-orchestrator.js +5 -2
  42. package/src/utils/git-utils.d.ts +7 -10
  43. package/src/utils/git-utils.js +61 -44
  44. package/src/utils/sync-generators.d.ts +2 -2
  45. package/src/utils/squash.d.ts +0 -1
  46. package/src/utils/squash.js +0 -12
@@ -4,99 +4,45 @@ exports.prepareSourceRepo = prepareSourceRepo;
4
4
  const createSpinner = require("ora");
5
5
  const path_1 = require("path");
6
6
  const promises_1 = require("node:fs/promises");
7
- async function prepareSourceRepo(gitClient, ref, source, relativeDestination, tempImportBranch, sourceRemoteUrl, originName) {
7
+ async function prepareSourceRepo(gitClient, ref, source, relativeDestination, tempImportBranch, sourceRemoteUrl) {
8
8
  const spinner = createSpinner().start(`Fetching ${ref} from ${sourceRemoteUrl}`);
9
- await gitClient.addFetchRemote(originName, ref);
10
- await gitClient.fetch(originName, ref);
11
- spinner.succeed(`Fetched ${ref} from ${sourceRemoteUrl}`);
12
- spinner.start(`Checking out a temporary branch, ${tempImportBranch} based on ${ref}`);
13
- await gitClient.checkout(tempImportBranch, {
14
- new: true,
15
- base: `${originName}/${ref}`,
16
- });
17
- spinner.succeed(`Created a ${tempImportBranch} branch based on ${ref}`);
18
9
  const relativeSourceDir = (0, path_1.relative)(gitClient.root, (0, path_1.join)(gitClient.root, source));
19
- const destinationInSource = (0, path_1.join)(gitClient.root, relativeDestination);
20
- spinner.start(`Moving files and git history to ${destinationInSource}`);
21
- if (relativeSourceDir === '') {
22
- const files = await gitClient.getGitFiles('.');
23
- try {
24
- await (0, promises_1.rm)(destinationInSource, {
25
- recursive: true,
26
- });
27
- }
28
- catch { }
29
- await (0, promises_1.mkdir)(destinationInSource, { recursive: true });
30
- const gitignores = new Set();
31
- for (const file of files) {
32
- if ((0, path_1.basename)(file) === '.gitignore') {
33
- gitignores.add(file);
34
- continue;
35
- }
36
- spinner.start(`Moving files and git history to ${destinationInSource}: ${file}`);
37
- const newPath = (0, path_1.join)(destinationInSource, file);
38
- await (0, promises_1.mkdir)((0, path_1.dirname)(newPath), { recursive: true });
39
- try {
40
- await gitClient.move(file, newPath);
41
- }
42
- catch {
43
- await wait(100);
44
- await gitClient.move(file, newPath);
45
- }
46
- }
47
- await gitClient.commit(`chore(repo): move ${source} to ${relativeDestination} to prepare to be imported`);
48
- for (const gitignore of gitignores) {
49
- await gitClient.move(gitignore, (0, path_1.join)(destinationInSource, gitignore));
10
+ if (relativeSourceDir !== '') {
11
+ if (await gitClient.hasFilterRepoInstalled()) {
12
+ spinner.start(`Filtering git history to only include files in ${relativeSourceDir}`);
13
+ await gitClient.filterRepo(relativeSourceDir);
50
14
  }
51
- await gitClient.amendCommit();
52
- for (const gitignore of gitignores) {
53
- await (0, promises_1.copyFile)((0, path_1.join)(destinationInSource, gitignore), (0, path_1.join)(gitClient.root, gitignore));
15
+ else {
16
+ spinner.start(`Filtering git history to only include files in ${relativeSourceDir} (this might take a few minutes -- install git-filter-repo for faster performance)`);
17
+ await gitClient.filterBranch(relativeSourceDir, tempImportBranch);
54
18
  }
19
+ spinner.succeed(`Filtered git history to only include files in ${relativeSourceDir}`);
55
20
  }
56
- else {
57
- let needsSquash = false;
58
- const needsMove = destinationInSource !== (0, path_1.join)(gitClient.root, source);
59
- if (needsMove) {
60
- try {
61
- await (0, promises_1.rm)(destinationInSource, {
62
- recursive: true,
63
- });
64
- await gitClient.commit(`chore(repo): move ${source} to ${relativeDestination} to prepare to be imported`);
65
- needsSquash = true;
66
- }
67
- catch { }
68
- await (0, promises_1.mkdir)(destinationInSource, { recursive: true });
69
- }
70
- const files = await gitClient.getGitFiles('.');
71
- for (const file of files) {
72
- if (file === '.gitignore') {
73
- continue;
74
- }
75
- spinner.start(`Moving files and git history to ${destinationInSource}: ${file}`);
76
- if (!(0, path_1.relative)(source, file).startsWith('..')) {
77
- if (needsMove) {
78
- const newPath = (0, path_1.join)(destinationInSource, file);
79
- await (0, promises_1.mkdir)((0, path_1.dirname)(newPath), { recursive: true });
80
- try {
81
- await gitClient.move(file, newPath);
82
- }
83
- catch {
84
- await wait(100);
85
- await gitClient.move(file, newPath);
86
- }
87
- }
88
- }
89
- else {
90
- await (0, promises_1.rm)((0, path_1.join)(gitClient.root, file), {
91
- recursive: true,
92
- });
93
- }
21
+ const destinationInSource = (0, path_1.join)(gitClient.root, relativeDestination);
22
+ spinner.start(`Moving files and git history to ${destinationInSource}`);
23
+ // The result of filter-branch will contain only the files in the subdirectory at its root.
24
+ const files = await gitClient.getGitFiles('.');
25
+ try {
26
+ await (0, promises_1.rm)(destinationInSource, {
27
+ recursive: true,
28
+ });
29
+ }
30
+ catch { }
31
+ await (0, promises_1.mkdir)(destinationInSource, { recursive: true });
32
+ for (const file of files) {
33
+ spinner.start(`Moving files and git history to ${destinationInSource}: ${file}`);
34
+ const newPath = (0, path_1.join)(destinationInSource, file);
35
+ await (0, promises_1.mkdir)((0, path_1.dirname)(newPath), { recursive: true });
36
+ try {
37
+ await gitClient.move(file, newPath);
94
38
  }
95
- await gitClient.commit(`chore(repo): move ${source} to ${relativeDestination} to prepare to be imported`);
96
- if (needsSquash) {
97
- await gitClient.squashLastTwoCommits();
39
+ catch {
40
+ await wait(100);
41
+ await gitClient.move(file, newPath);
98
42
  }
99
43
  }
44
+ await gitClient.commit(`chore(repo): move ${source} to ${relativeDestination} to prepare to be imported`);
45
+ await gitClient.amendCommit();
100
46
  spinner.succeed(`${sourceRemoteUrl} has been prepared to be imported into this workspace on a temporary branch: ${tempImportBranch} in ${gitClient.root}`);
101
47
  }
102
48
  function wait(ms) {
@@ -81,7 +81,7 @@ function createAPI(overrideReleaseConfig) {
81
81
  process.exit(1);
82
82
  }
83
83
  const rawVersionPlans = await (0, version_plans_1.readRawVersionPlans)();
84
- (0, version_plans_1.setResolvedVersionPlansOnGroups)(rawVersionPlans, releaseGroups, Object.keys(projectGraph.nodes));
84
+ await (0, version_plans_1.setResolvedVersionPlansOnGroups)(rawVersionPlans, releaseGroups, Object.keys(projectGraph.nodes), args.verbose);
85
85
  if (args.deleteVersionPlans === undefined) {
86
86
  // default to deleting version plans in this command instead of after versioning
87
87
  args.deleteVersionPlans = true;
@@ -146,6 +146,15 @@ function createAPI(overrideReleaseConfig) {
146
146
  workspaceChangelogChanges = versionPlans
147
147
  .flatMap((vp) => {
148
148
  const releaseType = versionPlanSemverReleaseTypeToChangelogType(vp.groupVersionBump);
149
+ let githubReferences = [];
150
+ let author = undefined;
151
+ const parsedCommit = vp.commit
152
+ ? (0, git_1.parseGitCommit)(vp.commit, true)
153
+ : null;
154
+ if (parsedCommit) {
155
+ githubReferences = parsedCommit.references;
156
+ author = parsedCommit.author;
157
+ }
149
158
  const changes = !vp.triggeredByProjects
150
159
  ? {
151
160
  type: releaseType.type,
@@ -153,7 +162,8 @@ function createAPI(overrideReleaseConfig) {
153
162
  description: vp.message,
154
163
  body: '',
155
164
  isBreaking: releaseType.isBreaking,
156
- githubReferences: [],
165
+ githubReferences,
166
+ author,
157
167
  affectedProjects: '*',
158
168
  }
159
169
  : vp.triggeredByProjects.map((project) => {
@@ -162,9 +172,9 @@ function createAPI(overrideReleaseConfig) {
162
172
  scope: project,
163
173
  description: vp.message,
164
174
  body: '',
165
- // TODO: what about github references?
166
175
  isBreaking: releaseType.isBreaking,
167
- githubReferences: [],
176
+ githubReferences,
177
+ author,
168
178
  affectedProjects: [project],
169
179
  };
170
180
  });
@@ -301,6 +311,15 @@ function createAPI(overrideReleaseConfig) {
301
311
  return null;
302
312
  }
303
313
  const releaseType = versionPlanSemverReleaseTypeToChangelogType(bumpForProject);
314
+ let githubReferences = [];
315
+ let author = undefined;
316
+ const parsedCommit = vp.commit
317
+ ? (0, git_1.parseGitCommit)(vp.commit, true)
318
+ : null;
319
+ if (parsedCommit) {
320
+ githubReferences = parsedCommit.references;
321
+ author = parsedCommit.author;
322
+ }
304
323
  return {
305
324
  type: releaseType.type,
306
325
  scope: project.name,
@@ -308,8 +327,8 @@ function createAPI(overrideReleaseConfig) {
308
327
  body: '',
309
328
  isBreaking: releaseType.isBreaking,
310
329
  affectedProjects: Object.keys(vp.projectVersionBumps),
311
- // TODO: can we include github references when using version plans?
312
- githubReferences: [],
330
+ githubReferences,
331
+ author,
313
332
  };
314
333
  })
315
334
  .filter(Boolean);
@@ -397,6 +416,15 @@ function createAPI(overrideReleaseConfig) {
397
416
  changes = releaseGroup.resolvedVersionPlans
398
417
  .flatMap((vp) => {
399
418
  const releaseType = versionPlanSemverReleaseTypeToChangelogType(vp.groupVersionBump);
419
+ let githubReferences = [];
420
+ let author = undefined;
421
+ const parsedCommit = vp.commit
422
+ ? (0, git_1.parseGitCommit)(vp.commit, true)
423
+ : null;
424
+ if (parsedCommit) {
425
+ githubReferences = parsedCommit.references;
426
+ author = parsedCommit.author;
427
+ }
400
428
  const changes = !vp.triggeredByProjects
401
429
  ? {
402
430
  type: releaseType.type,
@@ -404,7 +432,8 @@ function createAPI(overrideReleaseConfig) {
404
432
  description: vp.message,
405
433
  body: '',
406
434
  isBreaking: releaseType.isBreaking,
407
- githubReferences: [],
435
+ githubReferences,
436
+ author,
408
437
  affectedProjects: '*',
409
438
  }
410
439
  : vp.triggeredByProjects.map((project) => {
@@ -413,9 +442,9 @@ function createAPI(overrideReleaseConfig) {
413
442
  scope: project,
414
443
  description: vp.message,
415
444
  body: '',
416
- // TODO: what about github references?
417
445
  isBreaking: releaseType.isBreaking,
418
- githubReferences: [],
446
+ githubReferences,
447
+ author,
419
448
  affectedProjects: [project],
420
449
  };
421
450
  });
@@ -584,7 +613,17 @@ async function applyChangesAndExit(args, nxReleaseConfig, tree, toSHA, postGitTa
584
613
  releaseGroups.forEach((group) => {
585
614
  if (group.resolvedVersionPlans) {
586
615
  group.resolvedVersionPlans.forEach((plan) => {
587
- (0, fs_extra_1.removeSync)(plan.absolutePath);
616
+ if (!args.dryRun) {
617
+ (0, fs_extra_1.removeSync)(plan.absolutePath);
618
+ if (args.verbose) {
619
+ console.log(`Removing ${plan.relativePath}`);
620
+ }
621
+ }
622
+ else {
623
+ if (args.verbose) {
624
+ console.log(`Would remove ${plan.relativePath}, but --dry-run was set`);
625
+ }
626
+ }
588
627
  planFiles.add(plan.relativePath);
589
628
  });
590
629
  }
@@ -801,7 +840,9 @@ async function generateChangelogForProjects({ tree, args, projectGraph, changes,
801
840
  })
802
841
  : false,
803
842
  changelogRenderOptions: config.renderOptions,
804
- conventionalCommitsConfig: nxReleaseConfig.conventionalCommits,
843
+ conventionalCommitsConfig: releaseGroup.versionPlans
844
+ ? null
845
+ : nxReleaseConfig.conventionalCommits,
805
846
  dependencyBumps: projectToAdditionalDependencyBumps.get(project.name),
806
847
  });
807
848
  /**
@@ -44,6 +44,7 @@ export type PublishOptions = NxReleaseArgs & Partial<RunManyOptions> & {
44
44
  export type PlanOptions = NxReleaseArgs & {
45
45
  bump?: string;
46
46
  message?: string;
47
+ onlyTouched?: boolean;
47
48
  };
48
49
  export type PlanCheckOptions = BaseNxReleaseArgs & {
49
50
  base?: string;
@@ -207,7 +207,7 @@ const planCommand = {
207
207
  // Create a plan to pick a new version and generate a changelog entry.
208
208
  // Hidden for now until the feature is more stable
209
209
  describe: false,
210
- builder: (yargs) => yargs
210
+ builder: (yargs) => (0, shared_options_1.withAffectedOptions)(yargs)
211
211
  .positional('bump', {
212
212
  type: 'string',
213
213
  describe: 'Semver keyword to use for the selected release group.',
@@ -225,6 +225,11 @@ const planCommand = {
225
225
  type: 'string',
226
226
  alias: 'm',
227
227
  describe: 'Custom message to use for the changelog entry',
228
+ })
229
+ .option('onlyTouched', {
230
+ type: 'boolean',
231
+ describe: 'Only include projects that have been affected by the current changes',
232
+ default: true,
228
233
  }),
229
234
  handler: async (args) => {
230
235
  const release = await Promise.resolve().then(() => require('./plan'));
@@ -1,4 +1,5 @@
1
1
  import { ReleaseType } from 'semver';
2
+ import { RawGitCommit } from '../utils/git';
2
3
  import { ReleaseGroupWithName } from './filter-release-groups';
3
4
  export interface VersionPlanFile {
4
5
  absolutePath: string;
@@ -12,9 +13,21 @@ export interface RawVersionPlan extends VersionPlanFile {
12
13
  }
13
14
  export interface VersionPlan extends VersionPlanFile {
14
15
  message: string;
16
+ /**
17
+ * The commit that added the version plan file, will be null if the file was never committed.
18
+ * For optimal performance, we don't apply it at the time of reading the raw contents, because
19
+ * it hasn't yet passed further validation at that point.
20
+ */
21
+ commit: RawGitCommit | null;
15
22
  }
16
23
  export interface GroupVersionPlan extends VersionPlan {
17
24
  groupVersionBump: ReleaseType;
25
+ /**
26
+ * The commit that added the version plan file, will be null if the file was never committed.
27
+ * For optimal performance, we don't apply it at the time of reading the raw contents, because.
28
+ * it hasn't yet passed validation.
29
+ */
30
+ commit: RawGitCommit | null;
18
31
  /**
19
32
  * Will not be set if the group name was the trigger, otherwise will be a list of
20
33
  * all the individual project names explicitly found in the version plan file.
@@ -25,5 +38,5 @@ export interface ProjectsVersionPlan extends VersionPlan {
25
38
  projectVersionBumps: Record<string, ReleaseType>;
26
39
  }
27
40
  export declare function readRawVersionPlans(): Promise<RawVersionPlan[]>;
28
- export declare function setResolvedVersionPlansOnGroups(rawVersionPlans: RawVersionPlan[], releaseGroups: ReleaseGroupWithName[], allProjectNamesInWorkspace: string[]): ReleaseGroupWithName[];
41
+ export declare function setResolvedVersionPlansOnGroups(rawVersionPlans: RawVersionPlan[], releaseGroups: ReleaseGroupWithName[], allProjectNamesInWorkspace: string[], isVerbose: boolean): Promise<ReleaseGroupWithName[]>;
29
42
  export declare function getVersionPlansAbsolutePath(): string;
@@ -5,6 +5,7 @@ exports.setResolvedVersionPlansOnGroups = setResolvedVersionPlansOnGroups;
5
5
  exports.getVersionPlansAbsolutePath = getVersionPlansAbsolutePath;
6
6
  const fs_1 = require("fs");
7
7
  const fs_extra_1 = require("fs-extra");
8
+ const node_child_process_1 = require("node:child_process");
8
9
  const path_1 = require("path");
9
10
  const semver_1 = require("semver");
10
11
  const workspace_root_1 = require("../../../utils/workspace-root");
@@ -35,7 +36,7 @@ async function readRawVersionPlans() {
35
36
  }
36
37
  return versionPlans;
37
38
  }
38
- function setResolvedVersionPlansOnGroups(rawVersionPlans, releaseGroups, allProjectNamesInWorkspace) {
39
+ async function setResolvedVersionPlansOnGroups(rawVersionPlans, releaseGroups, allProjectNamesInWorkspace, isVerbose) {
39
40
  const groupsByName = releaseGroups.reduce((acc, group) => acc.set(group.name, group), new Map());
40
41
  const isDefaultGroup = isDefault(releaseGroups);
41
42
  for (const rawVersionPlan of rawVersionPlans) {
@@ -88,6 +89,7 @@ function setResolvedVersionPlansOnGroups(rawVersionPlans, releaseGroups, allProj
88
89
  createdOnMs: rawVersionPlan.createdOnMs,
89
90
  message: rawVersionPlan.message,
90
91
  groupVersionBump: value,
92
+ commit: await getCommitForVersionPlanFile(rawVersionPlan, isVerbose),
91
93
  });
92
94
  }
93
95
  }
@@ -130,6 +132,7 @@ function setResolvedVersionPlansOnGroups(rawVersionPlans, releaseGroups, allProj
130
132
  projectVersionBumps: {
131
133
  [key]: value,
132
134
  },
135
+ commit: await getCommitForVersionPlanFile(rawVersionPlan, isVerbose),
133
136
  });
134
137
  }
135
138
  }
@@ -161,6 +164,7 @@ function setResolvedVersionPlansOnGroups(rawVersionPlans, releaseGroups, allProj
161
164
  // but we track the projects that triggered the version bump so that we can accurately produce changelog entries.
162
165
  groupVersionBump: value,
163
166
  triggeredByProjects: [key],
167
+ commit: await getCommitForVersionPlanFile(rawVersionPlan, isVerbose),
164
168
  });
165
169
  }
166
170
  }
@@ -185,3 +189,31 @@ function getVersionPlansAbsolutePath() {
185
189
  function isReleaseType(value) {
186
190
  return semver_1.RELEASE_TYPES.includes(value);
187
191
  }
192
+ async function getCommitForVersionPlanFile(rawVersionPlan, isVerbose) {
193
+ return new Promise((resolve) => {
194
+ (0, node_child_process_1.exec)(`git log --diff-filter=A --pretty=format:"%s|%h|%an|%ae|%b" -n 1 -- ${rawVersionPlan.absolutePath}`, (error, stdout, stderr) => {
195
+ if (error) {
196
+ if (isVerbose) {
197
+ console.error(`Error executing git command for ${rawVersionPlan.relativePath}: ${error.message}`);
198
+ }
199
+ return resolve(null);
200
+ }
201
+ if (stderr) {
202
+ if (isVerbose) {
203
+ console.error(`Git command stderr for ${rawVersionPlan.relativePath}: ${stderr}`);
204
+ }
205
+ return resolve(null);
206
+ }
207
+ const [message, shortHash, authorName, authorEmail, ...body] = stdout
208
+ .trim()
209
+ .split('|');
210
+ const commitDetails = {
211
+ message: message || '',
212
+ shortHash: shortHash || '',
213
+ author: { name: authorName || '', email: authorEmail || '' },
214
+ body: body.join('|') || '', // Handle case where body might be empty or contain multiple '|'
215
+ };
216
+ return resolve(commitDetails);
217
+ });
218
+ });
219
+ }
@@ -10,19 +10,21 @@ export declare class ReleaseClient {
10
10
  release: (args: import("./command-object").ReleaseOptions) => Promise<import("./version").NxReleaseVersionResult | number>;
11
11
  constructor(overrideReleaseConfig: NxReleaseConfiguration);
12
12
  }
13
+ declare const defaultClient: ReleaseClient;
13
14
  /**
14
15
  * @public
15
16
  */
16
- export declare const releaseChangelog: any;
17
+ export declare const releaseChangelog: typeof defaultClient.releaseChangelog;
17
18
  /**
18
19
  * @public
19
20
  */
20
- export declare const releasePublish: any;
21
+ export declare const releasePublish: typeof defaultClient.releasePublish;
21
22
  /**
22
23
  * @public
23
24
  */
24
- export declare const releaseVersion: any;
25
+ export declare const releaseVersion: typeof defaultClient.releaseVersion;
25
26
  /**
26
27
  * @public
27
28
  */
28
- export declare const release: any;
29
+ export declare const release: typeof defaultClient.release;
30
+ export {};
@@ -3,19 +3,17 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.releasePlanCheckCLIHandler = void 0;
4
4
  exports.createAPI = createAPI;
5
5
  const nx_json_1 = require("../../config/nx-json");
6
- const workspace_projects_1 = require("../../project-graph/affected/locators/workspace-projects");
7
6
  const file_map_utils_1 = require("../../project-graph/file-map-utils");
8
- const file_utils_1 = require("../../project-graph/file-utils");
9
7
  const project_graph_1 = require("../../project-graph/project-graph");
10
8
  const all_file_data_1 = require("../../utils/all-file-data");
11
9
  const command_line_utils_1 = require("../../utils/command-line-utils");
12
- const ignore_1 = require("../../utils/ignore");
13
10
  const output_1 = require("../../utils/output");
14
11
  const params_1 = require("../../utils/params");
15
12
  const config_1 = require("./config/config");
16
13
  const deep_merge_json_1 = require("./config/deep-merge-json");
17
14
  const filter_release_groups_1 = require("./config/filter-release-groups");
18
15
  const version_plans_1 = require("./config/version-plans");
16
+ const get_touched_projects_for_group_1 = require("./utils/get-touched-projects-for-group");
19
17
  const print_config_1 = require("./utils/print-config");
20
18
  const releasePlanCheckCLIHandler = (args) => (0, params_1.handleErrors)(args.verbose, () => createAPI({})(args));
21
19
  exports.releasePlanCheckCLIHandler = releasePlanCheckCLIHandler;
@@ -37,7 +35,8 @@ function createAPI(overrideReleaseConfig) {
37
35
  isDebug: args.printConfig === 'debug',
38
36
  });
39
37
  }
40
- const { error: filterError, releaseGroups, releaseGroupToFilteredProjects, } = (0, filter_release_groups_1.filterReleaseGroups)(projectGraph, nxReleaseConfig, args.projects, args.groups);
38
+ // No filtering is applied here, as we want to consider all release groups for plan:check
39
+ const { error: filterError, releaseGroups } = (0, filter_release_groups_1.filterReleaseGroups)(projectGraph, nxReleaseConfig);
41
40
  if (filterError) {
42
41
  output_1.output.error(filterError);
43
42
  process.exit(1);
@@ -54,7 +53,7 @@ function createAPI(overrideReleaseConfig) {
54
53
  return 1;
55
54
  }
56
55
  const rawVersionPlans = await (0, version_plans_1.readRawVersionPlans)();
57
- (0, version_plans_1.setResolvedVersionPlansOnGroups)(rawVersionPlans, releaseGroups, Object.keys(projectGraph.nodes));
56
+ await (0, version_plans_1.setResolvedVersionPlansOnGroups)(rawVersionPlans, releaseGroups, Object.keys(projectGraph.nodes), args.verbose);
58
57
  // Resolve the final values for base, head etc to use when resolving the changes to consider
59
58
  const { nxArgs } = (0, command_line_utils_1.splitArgsIntoNxArgsAndOverrides)(args, 'affected', {
60
59
  printWarnings: args.verbose,
@@ -74,11 +73,7 @@ function createAPI(overrideReleaseConfig) {
74
73
  }
75
74
  }
76
75
  const resolvedAllFileData = await (0, all_file_data_1.allFileData)();
77
- /**
78
- * Create a minimal subset of touched projects based on the configured ignore patterns, we only need
79
- * to recompute when the ignorePatternsForPlanCheck differs between release groups.
80
- */
81
- const serializedIgnorePatternsToTouchedProjects = new Map();
76
+ const getTouchedProjectsForGroup = (0, get_touched_projects_for_group_1.createGetTouchedProjectsForGroup)(nxArgs, projectGraph, changedFiles, resolvedAllFileData);
82
77
  const NOTE_ABOUT_VERBOSE_LOGGING = 'Run with --verbose to see the full list of changed files used for the touched projects logic.';
83
78
  let hasErrors = false;
84
79
  for (const releaseGroup of releaseGroups) {
@@ -100,57 +95,9 @@ function createAPI(overrideReleaseConfig) {
100
95
  });
101
96
  continue;
102
97
  }
103
- // Exclude patterns from .nxignore, .gitignore and explicit version plan config
104
- let serializedIgnorePatterns = '[]';
105
- const ignore = (0, ignore_1.getIgnoreObject)();
106
- if (typeof releaseGroup.versionPlans !== 'boolean' &&
107
- Array.isArray(releaseGroup.versionPlans.ignorePatternsForPlanCheck) &&
108
- releaseGroup.versionPlans.ignorePatternsForPlanCheck.length) {
109
- output_1.output.note({
110
- title: `Applying configured ignore patterns to changed files${releaseGroup.name !== config_1.IMPLICIT_DEFAULT_RELEASE_GROUP
111
- ? ` for release group "${releaseGroup.name}"`
112
- : ''}`,
113
- bodyLines: [
114
- ...releaseGroup.versionPlans.ignorePatternsForPlanCheck.map((pattern) => ` - ${pattern}`),
115
- ],
116
- });
117
- ignore.add(releaseGroup.versionPlans.ignorePatternsForPlanCheck);
118
- serializedIgnorePatterns = JSON.stringify(releaseGroup.versionPlans.ignorePatternsForPlanCheck);
119
- }
120
- let touchedProjects = {};
121
- if (serializedIgnorePatternsToTouchedProjects.has(serializedIgnorePatterns)) {
122
- touchedProjects = serializedIgnorePatternsToTouchedProjects.get(serializedIgnorePatterns);
123
- }
124
- else {
125
- // We only care about directly touched projects, not implicitly affected ones etc
126
- const touchedProjectsArr = await (0, workspace_projects_1.getTouchedProjects)((0, file_utils_1.calculateFileChanges)(changedFiles, resolvedAllFileData, nxArgs, undefined, ignore), projectGraph.nodes);
127
- touchedProjects = touchedProjectsArr.reduce((acc, project) => ({ ...acc, [project]: true }), {});
128
- serializedIgnorePatternsToTouchedProjects.set(serializedIgnorePatterns, touchedProjects);
129
- }
130
- const touchedProjectsUnderReleaseGroup = releaseGroup.projects.filter((project) => touchedProjects[project]);
131
- if (touchedProjectsUnderReleaseGroup.length) {
132
- output_1.output.log({
133
- title: `Touched projects based on changed files${releaseGroup.name !== config_1.IMPLICIT_DEFAULT_RELEASE_GROUP
134
- ? ` under release group "${releaseGroup.name}"`
135
- : ''}`,
136
- bodyLines: [
137
- ...touchedProjectsUnderReleaseGroup.map((project) => ` - ${project}`),
138
- '',
139
- 'NOTE: You can adjust your "versionPlans.ignorePatternsForPlanCheck" config to stop certain files from resulting in projects being classed as touched for the purposes of this command.',
140
- ],
141
- });
142
- }
143
- else {
144
- output_1.output.log({
145
- title: `No touched projects found based on changed files${typeof releaseGroup.versionPlans !== 'boolean' &&
146
- Array.isArray(releaseGroup.versionPlans.ignorePatternsForPlanCheck) &&
147
- releaseGroup.versionPlans.ignorePatternsForPlanCheck.length
148
- ? ' combined with configured ignore patterns'
149
- : ''}${releaseGroup.name !== config_1.IMPLICIT_DEFAULT_RELEASE_GROUP
150
- ? ` under release group "${releaseGroup.name}"`
151
- : ''}`,
152
- });
153
- }
98
+ const touchedProjectsUnderReleaseGroup = await getTouchedProjectsForGroup(releaseGroup,
99
+ // We do not take any --projects or --groups filtering into account for plan:check
100
+ releaseGroup.projects, false);
154
101
  const projectsInResolvedVersionPlans = resolvedVersionPlans.reduce((acc, plan) => {
155
102
  if ('projectVersionBumps' in plan) {
156
103
  for (const project in plan.projectVersionBumps) {