nx 19.7.0-beta.3 → 19.7.0-beta.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) 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/add/command-object.js +2 -2
  6. package/src/command-line/affected/command-object.js +1 -1
  7. package/src/command-line/connect/command-object.js +11 -4
  8. package/src/command-line/connect/connect-to-nx-cloud.d.ts +3 -1
  9. package/src/command-line/connect/connect-to-nx-cloud.js +7 -4
  10. package/src/command-line/daemon/command-object.js +1 -1
  11. package/src/command-line/deprecated/command-objects.js +2 -2
  12. package/src/command-line/exec/command-object.js +1 -1
  13. package/src/command-line/format/command-object.js +4 -4
  14. package/src/command-line/generate/command-object.js +4 -4
  15. package/src/command-line/graph/command-object.js +6 -6
  16. package/src/command-line/import/command-object.js +9 -5
  17. package/src/command-line/import/import.d.ts +4 -0
  18. package/src/command-line/import/import.js +147 -12
  19. package/src/command-line/import/utils/prepare-source-repo.d.ts +1 -1
  20. package/src/command-line/import/utils/prepare-source-repo.js +31 -85
  21. package/src/command-line/list/command-object.js +1 -1
  22. package/src/command-line/login/command-object.js +1 -1
  23. package/src/command-line/logout/command-object.js +1 -1
  24. package/src/command-line/migrate/command-object.js +9 -9
  25. package/src/command-line/new/command-object.js +2 -2
  26. package/src/command-line/release/changelog.js +53 -12
  27. package/src/command-line/release/command-object.d.ts +2 -0
  28. package/src/command-line/release/command-object.js +37 -33
  29. package/src/command-line/release/config/version-plans.d.ts +14 -1
  30. package/src/command-line/release/config/version-plans.js +33 -1
  31. package/src/command-line/release/plan-check.js +8 -61
  32. package/src/command-line/release/plan.js +131 -37
  33. package/src/command-line/release/publish.js +3 -0
  34. package/src/command-line/release/release.js +1 -1
  35. package/src/command-line/release/utils/get-touched-projects-for-group.d.ts +7 -0
  36. package/src/command-line/release/utils/get-touched-projects-for-group.js +78 -0
  37. package/src/command-line/release/utils/git.d.ts +1 -1
  38. package/src/command-line/release/utils/git.js +46 -19
  39. package/src/command-line/release/version.js +1 -1
  40. package/src/command-line/report/command-object.js +1 -1
  41. package/src/command-line/reset/command-object.js +1 -1
  42. package/src/command-line/run/command-object.js +1 -1
  43. package/src/command-line/run-many/command-object.js +1 -1
  44. package/src/command-line/show/command-object.js +10 -10
  45. package/src/command-line/watch/command-object.js +1 -1
  46. package/src/command-line/yargs-utils/shared-options.d.ts +2 -1
  47. package/src/command-line/yargs-utils/shared-options.js +26 -29
  48. package/src/core/graph/main.js +1 -1
  49. package/src/daemon/server/sync-generators.d.ts +4 -0
  50. package/src/daemon/server/sync-generators.js +172 -52
  51. package/src/native/nx.wasm32-wasi.wasm +0 -0
  52. package/src/nx-cloud/generators/connect-to-nx-cloud/connect-to-nx-cloud.d.ts +2 -1
  53. package/src/nx-cloud/generators/connect-to-nx-cloud/connect-to-nx-cloud.js +25 -23
  54. package/src/nx-cloud/generators/connect-to-nx-cloud/schema.json +4 -0
  55. package/src/plugins/js/project-graph/build-dependencies/target-project-locator.js +8 -1
  56. package/src/project-graph/plugins/isolation/plugin-pool.js +1 -1
  57. package/src/tasks-runner/cache.d.ts +2 -0
  58. package/src/tasks-runner/cache.js +15 -1
  59. package/src/tasks-runner/run-command.js +4 -1
  60. package/src/tasks-runner/task-orchestrator.js +1 -10
  61. package/src/utils/command-line-utils.d.ts +1 -0
  62. package/src/utils/git-utils.d.ts +7 -10
  63. package/src/utils/git-utils.js +61 -44
  64. package/src/utils/sync-generators.d.ts +2 -2
  65. package/src/utils/squash.d.ts +0 -1
  66. package/src/utils/squash.js +0 -12
@@ -2,6 +2,10 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.importHandler = importHandler;
4
4
  const path_1 = require("path");
5
+ const minimatch_1 = require("minimatch");
6
+ const node_fs_1 = require("node:fs");
7
+ const chalk = require("chalk");
8
+ const js_yaml_1 = require("@zkochan/js-yaml");
5
9
  const git_utils_1 = require("../../utils/git-utils");
6
10
  const promises_1 = require("node:fs/promises");
7
11
  const tmp_1 = require("tmp");
@@ -18,6 +22,7 @@ const command_line_utils_1 = require("../../utils/command-line-utils");
18
22
  const prepare_source_repo_1 = require("./utils/prepare-source-repo");
19
23
  const merge_remote_source_1 = require("./utils/merge-remote-source");
20
24
  const needs_install_1 = require("./utils/needs-install");
25
+ const file_utils_1 = require("../../project-graph/file-utils");
21
26
  const importRemoteName = '__tmp_nx_import__';
22
27
  async function importHandler(options) {
23
28
  let { sourceRemoteUrl, ref, source, destination } = options;
@@ -54,7 +59,7 @@ async function importHandler(options) {
54
59
  // It's a remote url
55
60
  }
56
61
  const sourceRepoPath = (0, path_1.join)(tempImportDirectory, 'repo');
57
- const spinner = createSpinner(`Cloning ${sourceRemoteUrl} into a temporary directory: ${sourceRepoPath}`).start();
62
+ const spinner = createSpinner(`Cloning ${sourceRemoteUrl} into a temporary directory: ${sourceRepoPath} (Use --depth to limit commit history and speed up clone times)`).start();
58
63
  try {
59
64
  await (0, promises_1.rm)(tempImportDirectory, { recursive: true });
60
65
  }
@@ -64,6 +69,7 @@ async function importHandler(options) {
64
69
  try {
65
70
  sourceGitClient = await (0, git_utils_1.cloneFromUpstream)(sourceRemoteUrl, sourceRepoPath, {
66
71
  originName: importRemoteName,
72
+ depth: options.depth,
67
73
  });
68
74
  }
69
75
  catch (e) {
@@ -72,6 +78,8 @@ async function importHandler(options) {
72
78
  throw new Error(errorMessage);
73
79
  }
74
80
  spinner.succeed(`Cloned into ${sourceRepoPath}`);
81
+ // Detecting the package manager before preparing the source repo for import.
82
+ const sourcePackageManager = (0, package_manager_1.detectPackageManager)(sourceGitClient.root);
75
83
  if (!ref) {
76
84
  const branchChoices = await sourceGitClient.listBranches();
77
85
  ref = (await (0, enquirer_1.prompt)([
@@ -104,24 +112,34 @@ async function importHandler(options) {
104
112
  name: 'destination',
105
113
  message: 'Where in this workspace should the code be imported into?',
106
114
  required: true,
115
+ initial: source ? source : undefined,
107
116
  },
108
117
  ])).destination;
109
118
  }
110
119
  const absSource = (0, path_1.join)(sourceRepoPath, source);
111
120
  const absDestination = (0, path_1.join)(process.cwd(), destination);
121
+ const destinationGitClient = new git_utils_1.GitRepository(process.cwd());
122
+ await assertDestinationEmpty(destinationGitClient, absDestination);
123
+ const tempImportBranch = getTempImportBranch(ref);
124
+ await sourceGitClient.addFetchRemote(importRemoteName, ref);
125
+ await sourceGitClient.fetch(importRemoteName, ref);
126
+ spinner.succeed(`Fetched ${ref} from ${sourceRemoteUrl}`);
127
+ spinner.start(`Checking out a temporary branch, ${tempImportBranch} based on ${ref}`);
128
+ await sourceGitClient.checkout(tempImportBranch, {
129
+ new: true,
130
+ base: `${importRemoteName}/${ref}`,
131
+ });
132
+ spinner.succeed(`Created a ${tempImportBranch} branch based on ${ref}`);
112
133
  try {
113
134
  await (0, promises_1.stat)(absSource);
114
135
  }
115
136
  catch (e) {
116
137
  throw new Error(`The source directory ${source} does not exist in ${sourceRemoteUrl}. Please double check to make sure it exists.`);
117
138
  }
118
- const destinationGitClient = new git_utils_1.GitRepository(process.cwd());
119
- await assertDestinationEmpty(destinationGitClient, absDestination);
120
- const tempImportBranch = getTempImportBranch(ref);
121
139
  const packageManager = (0, package_manager_1.detectPackageManager)(workspace_root_1.workspaceRoot);
122
140
  const originalPackageWorkspaces = await (0, needs_install_1.getPackagesInPackageManagerWorkspace)(packageManager);
123
141
  const relativeDestination = (0, path_1.relative)(destinationGitClient.root, absDestination);
124
- await (0, prepare_source_repo_1.prepareSourceRepo)(sourceGitClient, ref, source, relativeDestination, tempImportBranch, sourceRemoteUrl, importRemoteName);
142
+ await (0, prepare_source_repo_1.prepareSourceRepo)(sourceGitClient, ref, source, relativeDestination, tempImportBranch, sourceRemoteUrl);
125
143
  await createTemporaryRemote(destinationGitClient, (0, path_1.join)(sourceRepoPath, '.git'), importRemoteName);
126
144
  await (0, merge_remote_source_1.mergeRemoteSource)(destinationGitClient, sourceRemoteUrl, tempImportBranch, destination, importRemoteName, ref);
127
145
  spinner.start('Cleaning up temporary files and remotes');
@@ -132,19 +150,69 @@ async function importHandler(options) {
132
150
  const nxJson = (0, nx_json_1.readNxJson)(workspace_root_1.workspaceRoot);
133
151
  (0, workspace_context_1.resetWorkspaceContext)();
134
152
  const { plugins, updatePackageScripts } = await (0, init_v2_1.detectPlugins)(nxJson, options.interactive);
153
+ if (packageManager !== sourcePackageManager) {
154
+ output_1.output.warn({
155
+ title: `Mismatched package managers`,
156
+ bodyLines: [
157
+ `The source repository is using a different package manager (${sourcePackageManager}) than this workspace (${packageManager}).`,
158
+ `This could lead to install issues due to discrepancies in "package.json" features.`,
159
+ ],
160
+ });
161
+ }
162
+ // If install fails, we should continue since the errors could be resolved later.
163
+ let installFailed = false;
135
164
  if (plugins.length > 0) {
136
- output_1.output.log({ title: 'Installing Plugins' });
137
- (0, init_v2_1.installPlugins)(workspace_root_1.workspaceRoot, plugins, pmc, updatePackageScripts);
138
- await destinationGitClient.amendCommit();
165
+ try {
166
+ output_1.output.log({ title: 'Installing Plugins' });
167
+ (0, init_v2_1.installPlugins)(workspace_root_1.workspaceRoot, plugins, pmc, updatePackageScripts);
168
+ await destinationGitClient.amendCommit();
169
+ }
170
+ catch (e) {
171
+ installFailed = true;
172
+ output_1.output.error({
173
+ title: `Install failed: ${e.message || 'Unknown error'}`,
174
+ bodyLines: [e.stack],
175
+ });
176
+ }
139
177
  }
140
178
  else if (await (0, needs_install_1.needsInstall)(packageManager, originalPackageWorkspaces)) {
179
+ try {
180
+ output_1.output.log({
181
+ title: 'Installing dependencies for imported code',
182
+ });
183
+ (0, utils_1.runInstall)(workspace_root_1.workspaceRoot, (0, package_manager_1.getPackageManagerCommand)(packageManager));
184
+ await destinationGitClient.amendCommit();
185
+ }
186
+ catch (e) {
187
+ installFailed = true;
188
+ output_1.output.error({
189
+ title: `Install failed: ${e.message || 'Unknown error'}`,
190
+ bodyLines: [e.stack],
191
+ });
192
+ }
193
+ }
194
+ console.log(await destinationGitClient.showStat());
195
+ if (installFailed) {
196
+ const pmc = (0, package_manager_1.getPackageManagerCommand)(packageManager);
197
+ output_1.output.warn({
198
+ title: `The import was successful, but the install failed`,
199
+ bodyLines: [
200
+ `You may need to run "${pmc.install}" manually to resolve the issue. The error is logged above.`,
201
+ ],
202
+ });
203
+ }
204
+ await warnOnMissingWorkspacesEntry(packageManager, pmc, relativeDestination);
205
+ // When only a subdirectory is imported, there might be devDependencies in the root package.json file
206
+ // that needs to be ported over as well.
207
+ if (ref) {
141
208
  output_1.output.log({
142
- title: 'Installing dependencies for imported code',
209
+ title: `Check root dependencies`,
210
+ bodyLines: [
211
+ `"dependencies" and "devDependencies" are not imported from the source repository (${sourceRemoteUrl}).`,
212
+ `You may need to add some of those dependencies to this workspace in order to run tasks successfully.`,
213
+ ],
143
214
  });
144
- (0, utils_1.runInstall)(workspace_root_1.workspaceRoot, (0, package_manager_1.getPackageManagerCommand)(packageManager));
145
- await destinationGitClient.amendCommit();
146
215
  }
147
- console.log(await destinationGitClient.showStat());
148
216
  output_1.output.log({
149
217
  title: `Merging these changes into ${(0, command_line_utils_1.getBaseRef)(nxJson)}`,
150
218
  bodyLines: [
@@ -171,3 +239,70 @@ async function createTemporaryRemote(destinationGitClient, sourceRemoteUrl, remo
171
239
  await destinationGitClient.addGitRemote(remoteName, sourceRemoteUrl);
172
240
  await destinationGitClient.fetch(remoteName);
173
241
  }
242
+ // If the user imports a project that isn't in NPM/Yarn/PNPM workspaces, then its dependencies
243
+ // will not be installed. We should warn users and provide instructions on how to fix this.
244
+ async function warnOnMissingWorkspacesEntry(pm, pmc, pkgPath) {
245
+ if (!(0, package_manager_1.isWorkspacesEnabled)(pm, workspace_root_1.workspaceRoot)) {
246
+ output_1.output.warn({
247
+ title: `Missing workspaces in package.json`,
248
+ bodyLines: pm === 'npm'
249
+ ? [
250
+ `We recommend enabling NPM workspaces to install dependencies for the imported project.`,
251
+ `Add \`"workspaces": ["${pkgPath}"]\` to package.json and run "${pmc.install}".`,
252
+ `See: https://docs.npmjs.com/cli/using-npm/workspaces`,
253
+ ]
254
+ : pm === 'yarn'
255
+ ? [
256
+ `We recommend enabling Yarn workspaces to install dependencies for the imported project.`,
257
+ `Add \`"workspaces": ["${pkgPath}"]\` to package.json and run "${pmc.install}".`,
258
+ `See: https://yarnpkg.com/features/workspaces`,
259
+ ]
260
+ : pm === 'bun'
261
+ ? [
262
+ `We recommend enabling Bun workspaces to install dependencies for the imported project.`,
263
+ `Add \`"workspaces": ["${pkgPath}"]\` to package.json and run "${pmc.install}".`,
264
+ `See: https://bun.sh/docs/install/workspaces`,
265
+ ]
266
+ : [
267
+ `We recommend enabling PNPM workspaces to install dependencies for the imported project.`,
268
+ `Add the following entry to to pnpm-workspace.yaml and run "${pmc.install}":`,
269
+ chalk.bold(`packages:\n - '${pkgPath}'`),
270
+ `See: https://pnpm.io/workspaces`,
271
+ ],
272
+ });
273
+ }
274
+ else {
275
+ // Check if the new package is included in existing workspaces entries. If not, warn the user.
276
+ let workspaces = null;
277
+ if (pm === 'npm' || pm === 'yarn' || pm === 'bun') {
278
+ const packageJson = (0, file_utils_1.readPackageJson)();
279
+ workspaces = packageJson.workspaces;
280
+ }
281
+ else if (pm === 'pnpm') {
282
+ const yamlPath = (0, path_1.join)(workspace_root_1.workspaceRoot, 'pnpm-workspace.yaml');
283
+ if ((0, node_fs_1.existsSync)(yamlPath)) {
284
+ const yamlContent = await node_fs_1.promises.readFile(yamlPath, 'utf-8');
285
+ const yaml = (0, js_yaml_1.load)(yamlContent);
286
+ workspaces = yaml.packages;
287
+ }
288
+ }
289
+ if (workspaces) {
290
+ const isPkgIncluded = workspaces.some((w) => (0, minimatch_1.minimatch)(pkgPath, w));
291
+ if (!isPkgIncluded) {
292
+ const pkgsDir = (0, path_1.dirname)(pkgPath);
293
+ output_1.output.warn({
294
+ title: `Project missing in workspaces`,
295
+ bodyLines: pm === 'npm' || pm === 'yarn' || pm === 'bun'
296
+ ? [
297
+ `The imported project (${pkgPath}) is missing the "workspaces" field in package.json.`,
298
+ `Add "${pkgsDir}/*" to workspaces run "${pmc.install}".`,
299
+ ]
300
+ : [
301
+ `The imported project (${pkgPath}) is missing the "packages" field in pnpm-workspaces.yaml.`,
302
+ `Add "${pkgsDir}/*" to packages run "${pmc.install}".`,
303
+ ],
304
+ });
305
+ }
306
+ }
307
+ }
308
+ }
@@ -1,2 +1,2 @@
1
1
  import { GitRepository } from '../../../utils/git-utils';
2
- export declare function prepareSourceRepo(gitClient: GitRepository, ref: string, source: string, relativeDestination: string, tempImportBranch: string, sourceRemoteUrl: string, originName: string): Promise<void>;
2
+ export declare function prepareSourceRepo(gitClient: GitRepository, ref: string, source: string, relativeDestination: string, tempImportBranch: string, sourceRemoteUrl: string): Promise<void>;
@@ -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) {
@@ -6,7 +6,7 @@ exports.yargsListCommand = {
6
6
  describe: 'Lists installed plugins, capabilities of installed plugins and other available plugins.',
7
7
  builder: (yargs) => yargs.positional('plugin', {
8
8
  type: 'string',
9
- description: 'The name of an installed plugin to query',
9
+ description: 'The name of an installed plugin to query.',
10
10
  }),
11
11
  handler: async (args) => {
12
12
  await (await Promise.resolve().then(() => require('./list'))).listHandler(args);
@@ -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));
@@ -30,44 +30,44 @@ function withMigrationOptions(yargs) {
30
30
  const defaultCommitPrefix = 'chore: [nx migration] ';
31
31
  return (0, shared_options_1.withVerbose)(yargs)
32
32
  .positional('packageAndVersion', {
33
- describe: `The target package and version (e.g, @nx/workspace@16.0.0)`,
33
+ describe: `The target package and version (e.g, @nx/workspace@16.0.0).`,
34
34
  type: 'string',
35
35
  })
36
36
  .option('runMigrations', {
37
- describe: `Execute migrations from a file (when the file isn't provided, execute migrations from migrations.json)`,
37
+ describe: `Execute migrations from a file (when the file isn't provided, execute migrations from migrations.json).`,
38
38
  type: 'string',
39
39
  })
40
40
  .option('ifExists', {
41
- describe: `Run migrations only if the migrations file exists, if not continues successfully`,
41
+ describe: `Run migrations only if the migrations file exists, if not continues successfully.`,
42
42
  type: 'boolean',
43
43
  default: false,
44
44
  })
45
45
  .option('from', {
46
- describe: 'Use the provided versions for packages instead of the ones installed in node_modules (e.g., --from="@nx/react@16.0.0,@nx/js@16.0.0")',
46
+ describe: 'Use the provided versions for packages instead of the ones installed in node_modules (e.g., --from="@nx/react@16.0.0,@nx/js@16.0.0").',
47
47
  type: 'string',
48
48
  })
49
49
  .option('to', {
50
- describe: 'Use the provided versions for packages instead of the ones calculated by the migrator (e.g., --to="@nx/react@16.0.0,@nx/js@16.0.0")',
50
+ describe: 'Use the provided versions for packages instead of the ones calculated by the migrator (e.g., --to="@nx/react@16.0.0,@nx/js@16.0.0").',
51
51
  type: 'string',
52
52
  })
53
53
  .option('createCommits', {
54
- describe: 'Automatically create a git commit after each migration runs',
54
+ describe: 'Automatically create a git commit after each migration runs.',
55
55
  type: 'boolean',
56
56
  alias: ['C'],
57
57
  default: false,
58
58
  })
59
59
  .option('commitPrefix', {
60
- describe: 'Commit prefix to apply to the commit for each migration, when --create-commits is enabled',
60
+ describe: 'Commit prefix to apply to the commit for each migration, when --create-commits is enabled.',
61
61
  type: 'string',
62
62
  default: defaultCommitPrefix,
63
63
  })
64
64
  .option('interactive', {
65
- describe: 'Enable prompts to confirm whether to collect optional package updates and migrations',
65
+ describe: 'Enable prompts to confirm whether to collect optional package updates and migrations.',
66
66
  type: 'boolean',
67
67
  default: false,
68
68
  })
69
69
  .option('excludeAppliedMigrations', {
70
- describe: 'Exclude migrations that should have been applied on previous updates. To be used with --from',
70
+ describe: 'Exclude migrations that should have been applied on previous updates. To be used with --from.',
71
71
  type: 'boolean',
72
72
  default: false,
73
73
  })
@@ -13,12 +13,12 @@ exports.yargsNewCommand = {
13
13
  function withNewOptions(yargs) {
14
14
  return yargs
15
15
  .option('nxWorkspaceRoot', {
16
- describe: 'The folder where the new workspace is going to be created',
16
+ describe: 'The folder where the new workspace is going to be created.',
17
17
  type: 'string',
18
18
  required: true,
19
19
  })
20
20
  .option('interactive', {
21
- describe: 'When false disables interactive input prompts for options',
21
+ describe: 'When false disables interactive input prompts for options.',
22
22
  type: 'boolean',
23
23
  default: true,
24
24
  });
@@ -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
  });
@@ -579,12 +608,22 @@ async function applyChangesAndExit(args, nxReleaseConfig, tree, toSHA, postGitTa
579
608
  }
580
609
  const changedFiles = changes.map((f) => f.path);
581
610
  let deletedFiles = [];
582
- if (args.deleteVersionPlans && !args.dryRun) {
611
+ if (args.deleteVersionPlans) {
583
612
  const planFiles = new Set();
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
  /**
@@ -39,11 +39,13 @@ export type PublishOptions = NxReleaseArgs & Partial<RunManyOptions> & {
39
39
  } & FirstReleaseArgs & {
40
40
  registry?: string;
41
41
  tag?: string;
42
+ access?: string;
42
43
  otp?: number;
43
44
  };
44
45
  export type PlanOptions = NxReleaseArgs & {
45
46
  bump?: string;
46
47
  message?: string;
48
+ onlyTouched?: boolean;
47
49
  };
48
50
  export type PlanCheckOptions = BaseNxReleaseArgs & {
49
51
  base?: string;