nx 19.7.0-canary.20240831-18e5535 → 19.7.0-canary.20240904-f39b995

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nx",
3
- "version": "19.7.0-canary.20240831-18e5535",
3
+ "version": "19.7.0-canary.20240904-f39b995",
4
4
  "private": false,
5
5
  "description": "The core Nx plugin contains the core functionality of Nx like the project graph, nx commands and task orchestration.",
6
6
  "repository": {
@@ -71,7 +71,7 @@
71
71
  "yargs-parser": "21.1.1",
72
72
  "node-machine-id": "1.1.12",
73
73
  "ora": "5.3.0",
74
- "@nrwl/tao": "19.7.0-canary.20240831-18e5535"
74
+ "@nrwl/tao": "19.7.0-canary.20240904-f39b995"
75
75
  },
76
76
  "peerDependencies": {
77
77
  "@swc-node/register": "^1.8.0",
@@ -86,16 +86,16 @@
86
86
  }
87
87
  },
88
88
  "optionalDependencies": {
89
- "@nx/nx-darwin-x64": "19.7.0-canary.20240831-18e5535",
90
- "@nx/nx-darwin-arm64": "19.7.0-canary.20240831-18e5535",
91
- "@nx/nx-linux-x64-gnu": "19.7.0-canary.20240831-18e5535",
92
- "@nx/nx-linux-x64-musl": "19.7.0-canary.20240831-18e5535",
93
- "@nx/nx-win32-x64-msvc": "19.7.0-canary.20240831-18e5535",
94
- "@nx/nx-linux-arm64-gnu": "19.7.0-canary.20240831-18e5535",
95
- "@nx/nx-linux-arm64-musl": "19.7.0-canary.20240831-18e5535",
96
- "@nx/nx-linux-arm-gnueabihf": "19.7.0-canary.20240831-18e5535",
97
- "@nx/nx-win32-arm64-msvc": "19.7.0-canary.20240831-18e5535",
98
- "@nx/nx-freebsd-x64": "19.7.0-canary.20240831-18e5535"
89
+ "@nx/nx-darwin-x64": "19.7.0-canary.20240904-f39b995",
90
+ "@nx/nx-darwin-arm64": "19.7.0-canary.20240904-f39b995",
91
+ "@nx/nx-linux-x64-gnu": "19.7.0-canary.20240904-f39b995",
92
+ "@nx/nx-linux-x64-musl": "19.7.0-canary.20240904-f39b995",
93
+ "@nx/nx-win32-x64-msvc": "19.7.0-canary.20240904-f39b995",
94
+ "@nx/nx-linux-arm64-gnu": "19.7.0-canary.20240904-f39b995",
95
+ "@nx/nx-linux-arm64-musl": "19.7.0-canary.20240904-f39b995",
96
+ "@nx/nx-linux-arm-gnueabihf": "19.7.0-canary.20240904-f39b995",
97
+ "@nx/nx-win32-arm64-msvc": "19.7.0-canary.20240904-f39b995",
98
+ "@nx/nx-freebsd-x64": "19.7.0-canary.20240904-f39b995"
99
99
  },
100
100
  "nx-migrations": {
101
101
  "migrations": "./migrations.json",
@@ -41,7 +41,7 @@ export type ChangelogRenderer = (config: {
41
41
  changelogRenderOptions: DefaultChangelogRenderOptions;
42
42
  dependencyBumps?: DependencyBump[];
43
43
  repoSlug?: RepoSlug;
44
- conventionalCommitsConfig: NxReleaseConfig['conventionalCommits'];
44
+ conventionalCommitsConfig: NxReleaseConfig['conventionalCommits'] | null;
45
45
  }) => Promise<string> | string;
46
46
  /**
47
47
  * The specific options available to the default implementation of the ChangelogRenderer that nx exports
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const semver_1 = require("semver");
4
+ const conventional_commits_1 = require("../../src/command-line/release/config/conventional-commits");
4
5
  const github_1 = require("../../src/command-line/release/utils/github");
5
6
  // axios types and values don't seem to match
6
7
  const _axios = require("axios");
@@ -10,9 +11,7 @@ const axios = _axios;
10
11
  * from the given commits and other metadata.
11
12
  */
12
13
  const defaultChangelogRenderer = async ({ projectGraph, changes, releaseVersion, project, entryWhenNoChanges, changelogRenderOptions, dependencyBumps, repoSlug, conventionalCommitsConfig, }) => {
13
- const changeTypes = conventionalCommitsConfig.types;
14
14
  const markdownLines = [];
15
- const breakingChanges = [];
16
15
  // If the current range of changes contains both a commit and its revert, we strip them both from the final list. Changes from version plans are unaffected, as they have no hashes.
17
16
  for (const change of changes) {
18
17
  if (change.type === 'revert' && change.revertedHashes) {
@@ -26,10 +25,38 @@ const defaultChangelogRenderer = async ({ projectGraph, changes, releaseVersion,
26
25
  }
27
26
  }
28
27
  let relevantChanges = changes;
28
+ const breakingChanges = [];
29
+ // For now to keep the interface of the changelog renderer non-breaking for v19 releases we have a somewhat indirect check for whether or not we are generating a changelog for version plans
30
+ const isVersionPlans = !conventionalCommitsConfig;
31
+ // Only applicable for version plans
32
+ const additionalChangesForAuthorsSection = [];
33
+ // Provide a default configuration for version plans to allow most of the subsequent logic to work in the same way it would for conventional commits
34
+ // NOTE: The one exception is breaking/major changes, where we do not follow the same structure and instead only show the changes once
35
+ if (isVersionPlans) {
36
+ conventionalCommitsConfig = {
37
+ types: {
38
+ feat: conventional_commits_1.DEFAULT_CONVENTIONAL_COMMITS_CONFIG.types.feat,
39
+ fix: conventional_commits_1.DEFAULT_CONVENTIONAL_COMMITS_CONFIG.types.fix,
40
+ },
41
+ };
42
+ // Trim down "relevant changes" to only include non-breaking ones so that we can render them differently under version plans,
43
+ // but keep track of the changes for the purposes of the authors section
44
+ // TODO(v20): Clean this abstraction up as part of the larger overall refactor of changelog rendering
45
+ for (let i = 0; i < relevantChanges.length; i++) {
46
+ if (relevantChanges[i].isBreaking) {
47
+ const change = relevantChanges[i];
48
+ additionalChangesForAuthorsSection.push(change);
49
+ const line = formatChange(change, changelogRenderOptions, isVersionPlans, repoSlug);
50
+ breakingChanges.push(line);
51
+ relevantChanges.splice(i, 1);
52
+ }
53
+ }
54
+ }
55
+ const changeTypes = conventionalCommitsConfig.types;
29
56
  // workspace root level changelog
30
57
  if (project === null) {
31
58
  // No changes for the workspace
32
- if (relevantChanges.length === 0) {
59
+ if (relevantChanges.length === 0 && breakingChanges.length === 0) {
33
60
  if (dependencyBumps?.length) {
34
61
  applyAdditionalDependencyBumps({
35
62
  markdownLines,
@@ -62,7 +89,7 @@ const defaultChangelogRenderer = async ({ projectGraph, changes, releaseVersion,
62
89
  for (const scope of scopesSortedAlphabetically) {
63
90
  const changes = changesGroupedByScope[scope];
64
91
  for (const change of changes) {
65
- const line = formatChange(change, changelogRenderOptions, repoSlug);
92
+ const line = formatChange(change, changelogRenderOptions, isVersionPlans, repoSlug);
66
93
  markdownLines.push(line);
67
94
  if (change.isBreaking) {
68
95
  const breakingChangeExplanation = extractBreakingChangeExplanation(change.body);
@@ -79,7 +106,7 @@ const defaultChangelogRenderer = async ({ projectGraph, changes, releaseVersion,
79
106
  relevantChanges = relevantChanges.filter((c) => c.affectedProjects &&
80
107
  (c.affectedProjects === '*' || c.affectedProjects.includes(project)));
81
108
  // Generating for a named project, but that project has no relevant changes in the current set of commits, exit early
82
- if (relevantChanges.length === 0) {
109
+ if (relevantChanges.length === 0 && breakingChanges.length === 0) {
83
110
  if (dependencyBumps?.length) {
84
111
  applyAdditionalDependencyBumps({
85
112
  markdownLines,
@@ -105,7 +132,7 @@ const defaultChangelogRenderer = async ({ projectGraph, changes, releaseVersion,
105
132
  markdownLines.push('', `### ${changeTypes[type].changelog.title}`, '');
106
133
  const changesInChronologicalOrder = group.reverse();
107
134
  for (const change of changesInChronologicalOrder) {
108
- const line = formatChange(change, changelogRenderOptions, repoSlug);
135
+ const line = formatChange(change, changelogRenderOptions, isVersionPlans, repoSlug);
109
136
  markdownLines.push(line + '\n');
110
137
  if (change.isBreaking) {
111
138
  const breakingChangeExplanation = extractBreakingChangeExplanation(change.body);
@@ -117,7 +144,7 @@ const defaultChangelogRenderer = async ({ projectGraph, changes, releaseVersion,
117
144
  }
118
145
  }
119
146
  if (breakingChanges.length > 0) {
120
- markdownLines.push('', '#### ⚠️ Breaking Changes', '', ...breakingChanges);
147
+ markdownLines.push('', '### ⚠️ Breaking Changes', '', ...breakingChanges);
121
148
  }
122
149
  if (dependencyBumps?.length) {
123
150
  applyAdditionalDependencyBumps({
@@ -129,7 +156,10 @@ const defaultChangelogRenderer = async ({ projectGraph, changes, releaseVersion,
129
156
  }
130
157
  if (changelogRenderOptions.authors) {
131
158
  const _authors = new Map();
132
- for (const change of relevantChanges) {
159
+ for (const change of [
160
+ ...relevantChanges,
161
+ ...additionalChangesForAuthorsSection,
162
+ ]) {
133
163
  if (!change.author) {
134
164
  continue;
135
165
  }
@@ -215,7 +245,7 @@ function groupBy(items, key) {
215
245
  }
216
246
  return groups;
217
247
  }
218
- function formatChange(change, changelogRenderOptions, repoSlug) {
248
+ function formatChange(change, changelogRenderOptions, isVersionPlans, repoSlug) {
219
249
  let description = change.description;
220
250
  let extraLines = [];
221
251
  let extraLinesStr = '';
@@ -228,9 +258,14 @@ function formatChange(change, changelogRenderOptions, repoSlug) {
228
258
  .map((l) => `${indentation}${l}`)
229
259
  .join('\n');
230
260
  }
261
+ /**
262
+ * In version plans changelogs:
263
+ * - don't repeat the breaking change icon
264
+ * - don't render the scope
265
+ */
231
266
  let changeLine = '- ' +
232
- (change.isBreaking ? '⚠️ ' : '') +
233
- (change.scope ? `**${change.scope.trim()}:** ` : '') +
267
+ (!isVersionPlans && change.isBreaking ? '⚠️ ' : '') +
268
+ (!isVersionPlans && change.scope ? `**${change.scope.trim()}:** ` : '') +
234
269
  description;
235
270
  if (repoSlug && changelogRenderOptions.commitReferences) {
236
271
  changeLine += (0, github_1.formatReferences)(change.githubReferences, repoSlug);
@@ -4,7 +4,7 @@ exports.yargsLoginCommand = void 0;
4
4
  const shared_options_1 = require("../../command-line/yargs-utils/shared-options");
5
5
  exports.yargsLoginCommand = {
6
6
  command: 'login [nxCloudUrl]',
7
- describe: 'Login to Nx Cloud',
7
+ describe: false,
8
8
  builder: (yargs) => (0, shared_options_1.withVerbose)(yargs.positional('nxCloudUrl', {
9
9
  describe: 'The Nx Cloud URL of the instance you are trying to connect to. If no positional argument is provided, this command will connect to https://cloud.nx.app.',
10
10
  type: 'string',
@@ -4,7 +4,7 @@ exports.yargsLogoutCommand = void 0;
4
4
  const shared_options_1 = require("../../command-line/yargs-utils/shared-options");
5
5
  exports.yargsLogoutCommand = {
6
6
  command: 'logout',
7
- describe: 'Logout from Nx Cloud',
7
+ describe: false,
8
8
  builder: (yargs) => (0, shared_options_1.withVerbose)(yargs),
9
9
  handler: async (args) => {
10
10
  process.exit(await (await Promise.resolve().then(() => require('./logout'))).logoutHandler(args));
@@ -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
  });
@@ -811,7 +840,9 @@ async function generateChangelogForProjects({ tree, args, projectGraph, changes,
811
840
  })
812
841
  : false,
813
842
  changelogRenderOptions: config.renderOptions,
814
- conventionalCommitsConfig: nxReleaseConfig.conventionalCommits,
843
+ conventionalCommitsConfig: releaseGroup.versionPlans
844
+ ? null
845
+ : nxReleaseConfig.conventionalCommits,
815
846
  dependencyBumps: projectToAdditionalDependencyBumps.get(project.name),
816
847
  });
817
848
  /**
@@ -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
+ }
@@ -53,7 +53,7 @@ function createAPI(overrideReleaseConfig) {
53
53
  return 1;
54
54
  }
55
55
  const rawVersionPlans = await (0, version_plans_1.readRawVersionPlans)();
56
- (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);
57
57
  // Resolve the final values for base, head etc to use when resolving the changes to consider
58
58
  const { nxArgs } = (0, command_line_utils_1.splitArgsIntoNxArgsAndOverrides)(args, 'affected', {
59
59
  printWarnings: args.verbose,
@@ -94,7 +94,7 @@ function createAPI(overrideReleaseConfig) {
94
94
  output_1.output.error(filterError);
95
95
  process.exit(1);
96
96
  }
97
- (0, version_plans_1.setResolvedVersionPlansOnGroups)(rawVersionPlans, releaseGroups, Object.keys(projectGraph.nodes));
97
+ await (0, version_plans_1.setResolvedVersionPlansOnGroups)(rawVersionPlans, releaseGroups, Object.keys(projectGraph.nodes), args.verbose);
98
98
  const planFiles = new Set();
99
99
  releaseGroups.forEach((group) => {
100
100
  if (group.resolvedVersionPlans) {
@@ -62,6 +62,6 @@ export declare function parseConventionalCommitsMessage(message: string): {
62
62
  description: string;
63
63
  breaking: boolean;
64
64
  } | null;
65
- export declare function parseGitCommit(commit: RawGitCommit): GitCommit | null;
65
+ export declare function parseGitCommit(commit: RawGitCommit, isVersionPlanCommit?: boolean): GitCommit | null;
66
66
  export declare function getCommitHash(ref: string): Promise<string>;
67
67
  export declare function getFirstGitCommit(): Promise<string>;
@@ -281,6 +281,30 @@ function parseConventionalCommitsMessage(message) {
281
281
  breaking: Boolean(match.groups.breaking),
282
282
  };
283
283
  }
284
+ function extractReferencesFromCommitMessage(message, shortHash) {
285
+ const references = [];
286
+ for (const m of message.matchAll(PullRequestRE)) {
287
+ references.push({ type: 'pull-request', value: m[1] });
288
+ }
289
+ for (const m of message.matchAll(IssueRE)) {
290
+ if (!references.some((i) => i.value === m[1])) {
291
+ references.push({ type: 'issue', value: m[1] });
292
+ }
293
+ }
294
+ references.push({ value: shortHash, type: 'hash' });
295
+ return references;
296
+ }
297
+ function getAllAuthorsForCommit(commit) {
298
+ const authors = [commit.author];
299
+ // Additional authors can be specified in the commit body (depending on the VCS provider)
300
+ for (const match of commit.body.matchAll(CoAuthoredByRegex)) {
301
+ authors.push({
302
+ name: (match.groups.name || '').trim(),
303
+ email: (match.groups.email || '').trim(),
304
+ });
305
+ }
306
+ return authors;
307
+ }
284
308
  // https://www.conventionalcommits.org/en/v1.0.0/
285
309
  // https://regex101.com/r/FSfNvA/1
286
310
  const ConventionalCommitRegex = /(?<type>[a-z]+)(\((?<scope>.+)\))?(?<breaking>!)?: (?<description>.+)/i;
@@ -289,7 +313,25 @@ const PullRequestRE = /\([ a-z]*(#\d+)\s*\)/gm;
289
313
  const IssueRE = /(#\d+)/gm;
290
314
  const ChangedFileRegex = /(A|M|D|R\d*|C\d*)\t([^\t\n]*)\t?(.*)?/gm;
291
315
  const RevertHashRE = /This reverts commit (?<hash>[\da-f]{40})./gm;
292
- function parseGitCommit(commit) {
316
+ function parseGitCommit(commit, isVersionPlanCommit = false) {
317
+ // For version plans, we do not require conventional commits and therefore cannot extract data based on that format
318
+ if (isVersionPlanCommit) {
319
+ return {
320
+ ...commit,
321
+ description: commit.message,
322
+ type: '',
323
+ scope: '',
324
+ references: extractReferencesFromCommitMessage(commit.message, commit.shortHash),
325
+ // The commit message is not the source of truth for a breaking (major) change in version plans, so the value is not relevant
326
+ // TODO(v20): Make the current GitCommit interface more clearly tied to conventional commits
327
+ isBreaking: false,
328
+ authors: getAllAuthorsForCommit(commit),
329
+ // Not applicable to version plans
330
+ affectedFiles: [],
331
+ // Not applicable, a version plan cannot have been added in a commit that also reverts another commit
332
+ revertedHashes: [],
333
+ };
334
+ }
293
335
  const parsedMessage = parseConventionalCommitsMessage(commit.message);
294
336
  if (!parsedMessage) {
295
337
  return null;
@@ -298,16 +340,7 @@ function parseGitCommit(commit) {
298
340
  const isBreaking = parsedMessage.breaking || commit.body.includes('BREAKING CHANGE:');
299
341
  let description = parsedMessage.description;
300
342
  // Extract references from message
301
- const references = [];
302
- for (const m of description.matchAll(PullRequestRE)) {
303
- references.push({ type: 'pull-request', value: m[1] });
304
- }
305
- for (const m of description.matchAll(IssueRE)) {
306
- if (!references.some((i) => i.value === m[1])) {
307
- references.push({ type: 'issue', value: m[1] });
308
- }
309
- }
310
- references.push({ value: commit.shortHash, type: 'hash' });
343
+ const references = extractReferencesFromCommitMessage(description, commit.shortHash);
311
344
  // Remove references and normalize
312
345
  description = description.replace(PullRequestRE, '').trim();
313
346
  let type = parsedMessage.type;
@@ -322,13 +355,7 @@ function parseGitCommit(commit) {
322
355
  description = commit.message;
323
356
  }
324
357
  // Find all authors
325
- const authors = [commit.author];
326
- for (const match of commit.body.matchAll(CoAuthoredByRegex)) {
327
- authors.push({
328
- name: (match.groups.name || '').trim(),
329
- email: (match.groups.email || '').trim(),
330
- });
331
- }
358
+ const authors = getAllAuthorsForCommit(commit);
332
359
  // Extract file changes from commit body
333
360
  const affectedFiles = Array.from(commit.body.matchAll(ChangedFileRegex)).reduce((prev, [fullLine, changeType, file1, file2]) =>
334
361
  // file2 only exists for some change types, such as renames
@@ -82,7 +82,7 @@ function createAPI(overrideReleaseConfig) {
82
82
  }
83
83
  if (!args.specifier) {
84
84
  const rawVersionPlans = await (0, version_plans_1.readRawVersionPlans)();
85
- (0, version_plans_1.setResolvedVersionPlansOnGroups)(rawVersionPlans, releaseGroups, Object.keys(projectGraph.nodes));
85
+ await (0, version_plans_1.setResolvedVersionPlansOnGroups)(rawVersionPlans, releaseGroups, Object.keys(projectGraph.nodes), args.verbose);
86
86
  }
87
87
  else {
88
88
  if (args.verbose && releaseGroups.some((g) => !!g.versionPlans)) {
Binary file
@@ -42,6 +42,18 @@ function getNxInitDate() {
42
42
  return null;
43
43
  }
44
44
  }
45
+ async function createNxCloudWorkspaceV1(workspaceName, installationSource, nxInitDate) {
46
+ const apiUrl = (0, get_cloud_options_1.getCloudUrl)();
47
+ const response = await require('axios').post(`${apiUrl}/nx-cloud/create-org-and-workspace`, {
48
+ workspaceName,
49
+ installationSource,
50
+ nxInitDate,
51
+ });
52
+ if (response.data.message) {
53
+ throw new Error(response.data.message);
54
+ }
55
+ return response.data;
56
+ }
45
57
  async function createNxCloudWorkspaceV2(workspaceName, installationSource, nxInitDate) {
46
58
  const apiUrl = (0, get_cloud_options_1.getCloudUrl)();
47
59
  const response = await require('axios').post(`${apiUrl}/nx-cloud/v2/create-org-and-workspace`, {
@@ -69,6 +81,19 @@ async function printSuccessMessage(token, installationSource, usesGithub) {
69
81
  });
70
82
  return connectCloudUrl;
71
83
  }
84
+ function addNxCloudOptionsToNxJson(tree, token, directory = '') {
85
+ const nxJsonPath = (0, path_1.join)(directory, 'nx.json');
86
+ if (tree.exists(nxJsonPath)) {
87
+ (0, json_1.updateJson)(tree, (0, path_1.join)(directory, 'nx.json'), (nxJson) => {
88
+ const overrideUrl = process.env.NX_CLOUD_API || process.env.NRWL_API;
89
+ if (overrideUrl) {
90
+ nxJson.nxCloudUrl = overrideUrl;
91
+ }
92
+ nxJson.nxCloudAccessToken = token;
93
+ return nxJson;
94
+ });
95
+ }
96
+ }
72
97
  function addNxCloudIdToNxJson(tree, nxCloudId, directory = '') {
73
98
  const nxJsonPath = (0, path_1.join)(directory, 'nx.json');
74
99
  if (tree.exists(nxJsonPath)) {
@@ -89,6 +114,7 @@ async function connectToNxCloud(tree, schema, nxJson = (0, nx_json_1.readNxJson)
89
114
  return null;
90
115
  }
91
116
  const isGitHubDetected = schema.github ?? (await (0, url_shorten_1.repoUsesGithub)(schema.github));
117
+ let responseFromCreateNxCloudWorkspaceV1;
92
118
  let responseFromCreateNxCloudWorkspaceV2;
93
119
  /**
94
120
  * Do not create an Nx Cloud token if the user is using GitHub and
@@ -98,12 +124,22 @@ async function connectToNxCloud(tree, schema, nxJson = (0, nx_json_1.readNxJson)
98
124
  isGitHubDetected &&
99
125
  schema.installationSource === 'nx-connect')
100
126
  return null;
101
- responseFromCreateNxCloudWorkspaceV2 = await createNxCloudWorkspaceV2(getRootPackageName(tree), schema.installationSource, getNxInitDate());
102
- addNxCloudIdToNxJson(tree, responseFromCreateNxCloudWorkspaceV2?.nxCloudId, schema.directory);
103
- await (0, format_changed_files_with_prettier_if_available_1.formatChangedFilesWithPrettierIfAvailable)(tree, {
104
- silent: schema.hideFormatLogs,
105
- });
106
- return responseFromCreateNxCloudWorkspaceV2.nxCloudId;
127
+ if (process.env.NX_ENABLE_LOGIN === 'true') {
128
+ responseFromCreateNxCloudWorkspaceV2 = await createNxCloudWorkspaceV2(getRootPackageName(tree), schema.installationSource, getNxInitDate());
129
+ addNxCloudIdToNxJson(tree, responseFromCreateNxCloudWorkspaceV2?.nxCloudId, schema.directory);
130
+ await (0, format_changed_files_with_prettier_if_available_1.formatChangedFilesWithPrettierIfAvailable)(tree, {
131
+ silent: schema.hideFormatLogs,
132
+ });
133
+ return responseFromCreateNxCloudWorkspaceV2.nxCloudId;
134
+ }
135
+ else {
136
+ responseFromCreateNxCloudWorkspaceV1 = await createNxCloudWorkspaceV1(getRootPackageName(tree), schema.installationSource, getNxInitDate());
137
+ addNxCloudOptionsToNxJson(tree, responseFromCreateNxCloudWorkspaceV1?.token, schema.directory);
138
+ await (0, format_changed_files_with_prettier_if_available_1.formatChangedFilesWithPrettierIfAvailable)(tree, {
139
+ silent: schema.hideFormatLogs,
140
+ });
141
+ return responseFromCreateNxCloudWorkspaceV1.token;
142
+ }
107
143
  }
108
144
  async function connectToNxCloudGenerator(tree, options) {
109
145
  await connectToNxCloud(tree, options);
@@ -273,7 +273,7 @@ async function startPluginWorker() {
273
273
  socket,
274
274
  });
275
275
  }
276
- else if (attempts > 1000) {
276
+ else if (attempts > 10000) {
277
277
  // daemon fails to start, the process probably exited
278
278
  // we print the logs and exit the client
279
279
  reject('Failed to start plugin worker.');