nx 18.0.3 → 18.0.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 (45) hide show
  1. package/package.json +14 -13
  2. package/src/command-line/add/add.js +3 -1
  3. package/src/command-line/graph/graph.js +1 -1
  4. package/src/command-line/init/init-v2.js +16 -11
  5. package/src/command-line/migrate/command-object.js +17 -2
  6. package/src/command-line/migrate/migrate.js +13 -1
  7. package/src/command-line/release/changelog.d.ts +16 -1
  8. package/src/command-line/release/changelog.js +104 -198
  9. package/src/command-line/release/command-object.d.ts +1 -0
  10. package/src/command-line/release/command-object.js +31 -12
  11. package/src/command-line/release/publish.js +8 -11
  12. package/src/command-line/release/release.js +57 -6
  13. package/src/command-line/release/utils/git.d.ts +5 -1
  14. package/src/command-line/release/utils/git.js +26 -11
  15. package/src/command-line/release/utils/github.d.ts +4 -8
  16. package/src/command-line/release/utils/github.js +102 -34
  17. package/src/command-line/release/utils/shared.d.ts +1 -0
  18. package/src/command-line/release/utils/shared.js +3 -1
  19. package/src/command-line/release/version.js +0 -6
  20. package/src/core/graph/3rdpartylicenses.txt +0 -51
  21. package/src/core/graph/main.js +1 -1
  22. package/src/core/graph/polyfills.js +1 -1
  23. package/src/core/graph/runtime.js +1 -1
  24. package/src/core/graph/styles.js +1 -1
  25. package/src/executors/run-commands/run-commands.impl.js +3 -3
  26. package/src/migrations/update-17-0-0/rm-default-collection-npm-scope.js +3 -3
  27. package/src/plugins/js/utils/register.d.ts +4 -8
  28. package/src/plugins/js/utils/register.js +8 -22
  29. package/src/plugins/target-defaults/target-defaults-plugin.d.ts +2 -3
  30. package/src/plugins/target-defaults/target-defaults-plugin.js +24 -32
  31. package/src/project-graph/utils/project-configuration-utils.js +13 -6
  32. package/src/tasks-runner/life-cycles/dynamic-run-many-terminal-output-life-cycle.js +20 -23
  33. package/src/tasks-runner/life-cycles/dynamic-run-one-terminal-output-life-cycle.js +16 -16
  34. package/src/tasks-runner/life-cycles/static-run-many-terminal-output-life-cycle.js +1 -1
  35. package/src/tasks-runner/life-cycles/static-run-one-terminal-output-life-cycle.d.ts +1 -0
  36. package/src/tasks-runner/life-cycles/static-run-one-terminal-output-life-cycle.js +10 -2
  37. package/src/tasks-runner/life-cycles/view-logs-utils.js +1 -1
  38. package/src/tasks-runner/task-orchestrator.js +23 -1
  39. package/src/utils/json.js +3 -1
  40. package/src/utils/logger.js +1 -1
  41. package/src/utils/output.d.ts +0 -1
  42. package/src/utils/output.js +6 -7
  43. package/src/utils/package-json.d.ts +1 -1
  44. package/src/utils/package-json.js +12 -11
  45. package/src/utils/plugins/core-plugins.js +4 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nx",
3
- "version": "18.0.3",
3
+ "version": "18.0.5",
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": {
@@ -66,10 +66,10 @@
66
66
  "yargs-parser": "21.1.1",
67
67
  "node-machine-id": "1.1.12",
68
68
  "ora": "5.3.0",
69
- "@nrwl/tao": "18.0.3"
69
+ "@nrwl/tao": "18.0.5"
70
70
  },
71
71
  "peerDependencies": {
72
- "@swc-node/register": "^1.6.7",
72
+ "@swc-node/register": "^1.8.0",
73
73
  "@swc/core": "^1.3.85"
74
74
  },
75
75
  "peerDependenciesMeta": {
@@ -81,16 +81,16 @@
81
81
  }
82
82
  },
83
83
  "optionalDependencies": {
84
- "@nx/nx-darwin-x64": "18.0.3",
85
- "@nx/nx-darwin-arm64": "18.0.3",
86
- "@nx/nx-linux-x64-gnu": "18.0.3",
87
- "@nx/nx-linux-x64-musl": "18.0.3",
88
- "@nx/nx-win32-x64-msvc": "18.0.3",
89
- "@nx/nx-linux-arm64-gnu": "18.0.3",
90
- "@nx/nx-linux-arm64-musl": "18.0.3",
91
- "@nx/nx-linux-arm-gnueabihf": "18.0.3",
92
- "@nx/nx-win32-arm64-msvc": "18.0.3",
93
- "@nx/nx-freebsd-x64": "18.0.3"
84
+ "@nx/nx-darwin-x64": "18.0.5",
85
+ "@nx/nx-darwin-arm64": "18.0.5",
86
+ "@nx/nx-linux-x64-gnu": "18.0.5",
87
+ "@nx/nx-linux-x64-musl": "18.0.5",
88
+ "@nx/nx-win32-x64-msvc": "18.0.5",
89
+ "@nx/nx-linux-arm64-gnu": "18.0.5",
90
+ "@nx/nx-linux-arm64-musl": "18.0.5",
91
+ "@nx/nx-linux-arm-gnueabihf": "18.0.5",
92
+ "@nx/nx-win32-arm64-msvc": "18.0.5",
93
+ "@nx/nx-freebsd-x64": "18.0.5"
94
94
  },
95
95
  "nx-migrations": {
96
96
  "migrations": "./migrations.json",
@@ -126,6 +126,7 @@
126
126
  "@nrwl/next",
127
127
  "@nx/node",
128
128
  "@nrwl/node",
129
+ "@nx/nuxt",
129
130
  "@nx/playwright",
130
131
  "@nx/plugin",
131
132
  "@nrwl/nx-plugin",
@@ -100,7 +100,9 @@ async function initializePlugin(pkgName, options) {
100
100
  process.env.NX_ADD_PLUGINS !== 'false' &&
101
101
  coreNxPlugins.includes(pkgName);
102
102
  }
103
- await (0, child_process_2.runNxAsync)(`g ${pkgName}:${initGenerator} --keepExistingVersions${updatePackageScripts ? ' --updatePackageScripts' : ''}`);
103
+ await (0, child_process_2.runNxAsync)(`g ${pkgName}:${initGenerator} --keepExistingVersions${updatePackageScripts ? ' --updatePackageScripts' : ''}`, {
104
+ silent: !options.verbose,
105
+ });
104
106
  }
105
107
  catch (e) {
106
108
  spinner.fail();
@@ -266,7 +266,7 @@ async function generateGraph(args, affectedProjects) {
266
266
  const { app, url } = await startServer(html, environmentJs, args.host || '127.0.0.1', args.port || 4211, args.watch, affectedProjects, args.focus, args.groupByFolder, args.exclude);
267
267
  url.pathname = args.view;
268
268
  if (args.focus) {
269
- url.pathname += '/' + args.focus;
269
+ url.pathname += '/' + encodeURIComponent(args.focus);
270
270
  }
271
271
  if (target) {
272
272
  url.pathname += '/' + target;
@@ -17,6 +17,7 @@ const workspace_context_1 = require("../../utils/workspace-context");
17
17
  const connect_to_nx_cloud_1 = require("../connect/connect-to-nx-cloud");
18
18
  const add_nx_to_npm_repo_1 = require("./implementation/add-nx-to-npm-repo");
19
19
  const add_nx_to_monorepo_1 = require("./implementation/add-nx-to-monorepo");
20
+ const path_1 = require("path");
20
21
  async function initHandler(options) {
21
22
  const version = process.env.NX_VERSION ?? ((0, semver_1.prerelease)(versions_1.nxVersion) ? 'next' : 'latest');
22
23
  if (process.env.NX_VERSION) {
@@ -63,19 +64,23 @@ async function initHandler(options) {
63
64
  const pmc = (0, package_manager_1.getPackageManagerCommand)();
64
65
  (0, utils_1.createNxJsonFile)(repoRoot, [], [], {});
65
66
  (0, utils_1.updateGitIgnore)(repoRoot);
66
- (0, utils_1.addDepsToPackageJson)(repoRoot, detectPluginsResponse?.plugins ?? []);
67
+ (0, utils_1.addDepsToPackageJson)(repoRoot, detectPluginsResponse.plugins);
67
68
  output_1.output.log({ title: '📦 Installing Nx' });
68
69
  (0, utils_1.runInstall)(repoRoot, pmc);
69
- if (detectPluginsResponse) {
70
- output_1.output.log({ title: '🔨 Configuring plugins' });
71
- for (const plugin of detectPluginsResponse.plugins) {
72
- (0, child_process_2.execSync)(`${pmc.exec} nx g ${plugin}:init --keepExistingVersions ${detectPluginsResponse.updatePackageScripts
73
- ? '--updatePackageScripts'
74
- : ''} --no-interactive`, {
75
- stdio: [0, 1, 2],
76
- cwd: repoRoot,
77
- });
78
- }
70
+ output_1.output.log({ title: '🔨 Configuring plugins' });
71
+ for (const plugin of detectPluginsResponse.plugins) {
72
+ (0, child_process_2.execSync)(`${pmc.exec} nx g ${plugin}:init --keepExistingVersions ${detectPluginsResponse.updatePackageScripts
73
+ ? '--updatePackageScripts'
74
+ : ''} --no-interactive`, {
75
+ stdio: [0, 1, 2],
76
+ cwd: repoRoot,
77
+ });
78
+ }
79
+ if (!detectPluginsResponse.updatePackageScripts) {
80
+ const rootPackageJsonPath = (0, path_1.join)(repoRoot, 'package.json');
81
+ const json = (0, fileutils_1.readJsonFile)(rootPackageJsonPath);
82
+ json.nx = {};
83
+ (0, fileutils_1.writeJsonFile)(rootPackageJsonPath, json);
79
84
  }
80
85
  if (useNxCloud) {
81
86
  output_1.output.log({ title: '🛠️ Setting up Nx Cloud' });
@@ -109,7 +109,8 @@ function runMigration() {
109
109
  }
110
110
  function nxCliPath() {
111
111
  try {
112
- const packageManager = (0, package_manager_1.getPackageManagerCommand)();
112
+ const packageManager = (0, package_manager_1.detectPackageManager)();
113
+ const pmc = (0, package_manager_1.getPackageManagerCommand)(packageManager);
113
114
  const { dirSync } = require('tmp');
114
115
  const tmpDir = dirSync().name;
115
116
  const version = process.env.NX_MIGRATE_USE_NEXT === 'true' ? 'next' : 'latest';
@@ -119,7 +120,21 @@ function nxCliPath() {
119
120
  },
120
121
  license: 'MIT',
121
122
  });
122
- (0, child_process_2.execSync)(packageManager.install, {
123
+ if (pmc.preInstall) {
124
+ // ensure package.json and repo in tmp folder is set to a proper package manager state
125
+ (0, child_process_2.execSync)(pmc.preInstall, {
126
+ cwd: tmpDir,
127
+ stdio: ['ignore', 'ignore', 'ignore'],
128
+ });
129
+ // if it's berry ensure we set the node_linker to node-modules
130
+ if (packageManager === 'yarn' && pmc.ciInstall.includes('immutable')) {
131
+ (0, child_process_2.execSync)(pmc.preInstall, {
132
+ cwd: 'yarn config set nodeLinker node-modules',
133
+ stdio: ['ignore', 'ignore', 'ignore'],
134
+ });
135
+ }
136
+ }
137
+ (0, child_process_2.execSync)(pmc.install, {
123
138
  cwd: tmpDir,
124
139
  stdio: ['ignore', 'ignore', 'ignore'],
125
140
  });
@@ -862,7 +862,19 @@ function runInstall() {
862
862
  async function executeMigrations(root, migrations, isVerbose, shouldCreateCommits, commitPrefix) {
863
863
  const depsBeforeMigrations = getStringifiedPackageJsonDeps(root);
864
864
  const migrationsWithNoChanges = [];
865
- for (const m of migrations) {
865
+ const sortedMigrations = migrations.sort((a, b) => {
866
+ // special case for the split configuration migration to run first
867
+ if (a.name === '15-7-0-split-configuration-into-project-json-files') {
868
+ return -1;
869
+ }
870
+ if (b.name === '15-7-0-split-configuration-into-project-json-files') {
871
+ return 1;
872
+ }
873
+ return (0, semver_1.lt)(normalizeVersion(a.version), normalizeVersion(b.version))
874
+ ? -1
875
+ : 1;
876
+ });
877
+ for (const m of sortedMigrations) {
866
878
  try {
867
879
  const { collection, collectionPath } = readMigrationCollection(m.package, root);
868
880
  if (!isAngularMigration(collection, collectionPath, m.name)) {
@@ -1,8 +1,23 @@
1
+ import { NxReleaseChangelogConfiguration } from '../../config/nx-json';
1
2
  import { ChangelogOptions } from './command-object';
3
+ import { ReleaseVersion } from './utils/shared';
4
+ export interface NxReleaseChangelogResult {
5
+ workspaceChangelog?: {
6
+ releaseVersion: ReleaseVersion;
7
+ contents: string;
8
+ };
9
+ projectChangelogs?: {
10
+ [projectName: string]: {
11
+ releaseVersion: ReleaseVersion;
12
+ contents: string;
13
+ };
14
+ };
15
+ }
2
16
  export declare const releaseChangelogCLIHandler: (args: ChangelogOptions) => Promise<any>;
3
17
  /**
4
18
  * NOTE: This function is also exported for programmatic usage and forms part of the public API
5
19
  * of Nx. We intentionally do not wrap the implementation with handleErrors because users need
6
20
  * to have control over their own error handling when using the API.
7
21
  */
8
- export declare function releaseChangelog(args: ChangelogOptions): Promise<number>;
22
+ export declare function releaseChangelog(args: ChangelogOptions): Promise<NxReleaseChangelogResult>;
23
+ export declare function shouldCreateGitHubRelease(changelogConfig: NxReleaseChangelogConfiguration | false | undefined, createReleaseArg?: ChangelogOptions['createRelease'] | undefined): boolean;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.releaseChangelog = exports.releaseChangelogCLIHandler = void 0;
3
+ exports.shouldCreateGitHubRelease = exports.releaseChangelog = exports.releaseChangelogCLIHandler = void 0;
4
4
  const chalk = require("chalk");
5
5
  const node_fs_1 = require("node:fs");
6
6
  const semver_1 = require("semver");
@@ -10,7 +10,6 @@ const tree_1 = require("../../generators/tree");
10
10
  const register_1 = require("../../plugins/js/utils/register");
11
11
  const project_graph_1 = require("../../project-graph/project-graph");
12
12
  const utils_1 = require("../../tasks-runner/utils");
13
- const logger_1 = require("../../utils/logger");
14
13
  const output_1 = require("../../utils/output");
15
14
  const params_1 = require("../../utils/params");
16
15
  const path_1 = require("../../utils/path");
@@ -75,7 +74,7 @@ async function releaseChangelog(args) {
75
74
  `To explicitly enable changelog generation, configure "release.changelog.workspaceChangelog" or "release.changelog.projectChangelogs" in nx.json.`,
76
75
  ],
77
76
  });
78
- return 0;
77
+ return {};
79
78
  }
80
79
  const useAutomaticFromRef = nxReleaseConfig.changelog?.automaticFromRef || args.firstRelease;
81
80
  /**
@@ -129,7 +128,26 @@ async function releaseChangelog(args) {
129
128
  // Make sure that the fromRef is actually resolvable
130
129
  const workspaceChangelogFromSHA = await (0, git_1.getCommitHash)(workspaceChangelogFromRef);
131
130
  const workspaceChangelogCommits = await getCommits(workspaceChangelogFromSHA, toSHA);
132
- await generateChangelogForWorkspace(tree, args, projectGraph, nxReleaseConfig, workspaceChangelogVersion, workspaceChangelogCommits, postGitTasks);
131
+ const workspaceChangelog = await generateChangelogForWorkspace(tree, args, projectGraph, nxReleaseConfig, workspaceChangelogVersion, workspaceChangelogCommits);
132
+ if (workspaceChangelog &&
133
+ shouldCreateGitHubRelease(nxReleaseConfig.changelog.workspaceChangelog, args.createRelease)) {
134
+ let hasPushed = false;
135
+ postGitTasks.push(async (latestCommit) => {
136
+ if (!hasPushed) {
137
+ output_1.output.logSingleLine(`Pushing to git remote`);
138
+ // Before we can create/update the release we need to ensure the commit exists on the remote
139
+ await (0, git_1.gitPush)({
140
+ gitRemote: args.gitRemote,
141
+ dryRun: args.dryRun,
142
+ verbose: args.verbose,
143
+ });
144
+ hasPushed = true;
145
+ }
146
+ output_1.output.logSingleLine(`Creating GitHub Release`);
147
+ await (0, github_1.createOrUpdateGithubRelease)(workspaceChangelog.releaseVersion, workspaceChangelog.contents, latestCommit, { dryRun: args.dryRun });
148
+ });
149
+ }
150
+ const allProjectChangelogs = {};
133
151
  for (const releaseGroup of releaseGroups) {
134
152
  const config = releaseGroup.changelog;
135
153
  // The entire feature is disabled at the release group level, exit early
@@ -165,7 +183,28 @@ async function releaseChangelog(args) {
165
183
  if (!commits) {
166
184
  commits = await getCommits(fromRef, toSHA);
167
185
  }
168
- await generateChangelogForProjects(tree, args, projectGraph, commits, projectsVersionData, postGitTasks, releaseGroup, [project]);
186
+ const projectChangelogs = await generateChangelogForProjects(tree, args, projectGraph, commits, projectsVersionData, postGitTasks, releaseGroup, [project]);
187
+ let hasPushed = false;
188
+ for (const [projectName, projectChangelog] of Object.entries(projectChangelogs)) {
189
+ if (projectChangelogs &&
190
+ shouldCreateGitHubRelease(releaseGroup.changelog, args.createRelease)) {
191
+ postGitTasks.push(async (latestCommit) => {
192
+ if (!hasPushed) {
193
+ output_1.output.logSingleLine(`Pushing to git remote`);
194
+ // Before we can create/update the release we need to ensure the commit exists on the remote
195
+ await (0, git_1.gitPush)({
196
+ gitRemote: args.gitRemote,
197
+ dryRun: args.dryRun,
198
+ verbose: args.verbose,
199
+ });
200
+ hasPushed = true;
201
+ }
202
+ output_1.output.logSingleLine(`Creating GitHub Release`);
203
+ await (0, github_1.createOrUpdateGithubRelease)(projectChangelog.releaseVersion, projectChangelog.contents, latestCommit, { dryRun: args.dryRun });
204
+ });
205
+ }
206
+ allProjectChangelogs[projectName] = projectChangelog;
207
+ }
169
208
  }
170
209
  }
171
210
  else {
@@ -177,10 +216,35 @@ async function releaseChangelog(args) {
177
216
  // Make sure that the fromRef is actually resolvable
178
217
  const fromSHA = await (0, git_1.getCommitHash)(fromRef);
179
218
  const commits = await getCommits(fromSHA, toSHA);
180
- await generateChangelogForProjects(tree, args, projectGraph, commits, projectsVersionData, postGitTasks, releaseGroup, projectNodes);
219
+ const projectChangelogs = await generateChangelogForProjects(tree, args, projectGraph, commits, projectsVersionData, postGitTasks, releaseGroup, projectNodes);
220
+ let hasPushed = false;
221
+ for (const [projectName, projectChangelog] of Object.entries(projectChangelogs)) {
222
+ if (projectChangelogs &&
223
+ shouldCreateGitHubRelease(releaseGroup.changelog, args.createRelease)) {
224
+ postGitTasks.push(async (latestCommit) => {
225
+ if (!hasPushed) {
226
+ output_1.output.logSingleLine(`Pushing to git remote`);
227
+ // Before we can create/update the release we need to ensure the commit exists on the remote
228
+ await (0, git_1.gitPush)({
229
+ gitRemote: args.gitRemote,
230
+ dryRun: args.dryRun,
231
+ verbose: args.verbose,
232
+ });
233
+ hasPushed = true;
234
+ }
235
+ output_1.output.logSingleLine(`Creating GitHub Release`);
236
+ await (0, github_1.createOrUpdateGithubRelease)(projectChangelog.releaseVersion, projectChangelog.contents, latestCommit, { dryRun: args.dryRun });
237
+ });
238
+ }
239
+ allProjectChangelogs[projectName] = projectChangelog;
240
+ }
181
241
  }
182
242
  }
183
- return await applyChangesAndExit(args, nxReleaseConfig, tree, toSHA, postGitTasks, commitMessageValues, gitTagValues);
243
+ await applyChangesAndExit(args, nxReleaseConfig, tree, toSHA, postGitTasks, commitMessageValues, gitTagValues);
244
+ return {
245
+ workspaceChangelog,
246
+ projectChangelogs: allProjectChangelogs,
247
+ };
184
248
  }
185
249
  exports.releaseChangelog = releaseChangelog;
186
250
  function resolveChangelogVersions(args, releaseGroups, releaseGroupToFilteredProjects) {
@@ -238,7 +302,7 @@ async function applyChangesAndExit(args, nxReleaseConfig, tree, toSHA, postGitTa
238
302
  `No changes were detected for any changelog files, so no changelog entries will be generated.`,
239
303
  ],
240
304
  });
241
- return 0;
305
+ return;
242
306
  }
243
307
  // Generate a new commit for the changes, if configured to do so
244
308
  if (args.gitCommit ?? nxReleaseConfig.changelog.git.commit) {
@@ -272,10 +336,7 @@ async function applyChangesAndExit(args, nxReleaseConfig, tree, toSHA, postGitTa
272
336
  for (const postGitTask of postGitTasks) {
273
337
  await postGitTask(latestCommit);
274
338
  }
275
- if (args.dryRun) {
276
- logger_1.logger.warn(`\nNOTE: The "dryRun" flag means no changelogs were actually created.`);
277
- }
278
- return 0;
339
+ return;
279
340
  }
280
341
  function resolveChangelogRenderer(changelogRendererPath) {
281
342
  // Try and load the provided (or default) changelog renderer
@@ -296,7 +357,7 @@ function resolveChangelogRenderer(changelogRendererPath) {
296
357
  }
297
358
  return changelogRenderer;
298
359
  }
299
- async function generateChangelogForWorkspace(tree, args, projectGraph, nxReleaseConfig, workspaceChangelogVersion, commits, postGitTasks) {
360
+ async function generateChangelogForWorkspace(tree, args, projectGraph, nxReleaseConfig, workspaceChangelogVersion, commits) {
300
361
  const config = nxReleaseConfig.changelog.workspaceChangelog;
301
362
  // The entire feature is disabled at the workspace level, exit early
302
363
  if (config === false) {
@@ -348,21 +409,12 @@ async function generateChangelogForWorkspace(tree, args, projectGraph, nxRelease
348
409
  version: workspaceChangelogVersion,
349
410
  releaseTagPattern: nxReleaseConfig.releaseTagPattern,
350
411
  });
351
- // We are either creating/previewing a changelog file, a GitHub release, or both
352
- let logTitle = dryRun ? 'Previewing a' : 'Generating a';
353
- switch (true) {
354
- case interpolatedTreePath && config.createRelease === 'github':
355
- logTitle += ` GitHub release and an entry in ${interpolatedTreePath} for ${chalk.white(releaseVersion.gitTag)}`;
356
- break;
357
- case !!interpolatedTreePath:
358
- logTitle += `n entry in ${interpolatedTreePath} for ${chalk.white(releaseVersion.gitTag)}`;
359
- break;
360
- case config.createRelease === 'github':
361
- logTitle += ` GitHub release for ${chalk.white(releaseVersion.gitTag)}`;
362
- }
363
- output_1.output.log({
364
- title: logTitle,
365
- });
412
+ if (interpolatedTreePath) {
413
+ const prefix = dryRun ? 'Previewing' : 'Generating';
414
+ output_1.output.log({
415
+ title: `${prefix} an entry in ${interpolatedTreePath} for ${chalk.white(releaseVersion.gitTag)}`,
416
+ });
417
+ }
366
418
  const githubRepoSlug = (0, github_1.getGitHubRepoSlug)(gitRemote);
367
419
  let contents = await changelogRenderer({
368
420
  projectGraph,
@@ -386,12 +438,6 @@ async function generateChangelogForWorkspace(tree, args, projectGraph, nxRelease
386
438
  await (0, launch_editor_1.launchEditor)(changelogPath);
387
439
  contents = (0, node_fs_1.readFileSync)(changelogPath, 'utf-8');
388
440
  }
389
- /**
390
- * The exact logic we use for printing the summary/diff to the user is dependent upon whether they are creating
391
- * a changelog file, a GitHub release, or both.
392
- */
393
- let printSummary = () => { };
394
- const noDiffInChangelogMessage = chalk.yellow(`NOTE: There was no diff detected for the changelog entry. Maybe you intended to pass alternative git references via --from and --to?`);
395
441
  if (interpolatedTreePath) {
396
442
  let rootChangelogContents = tree.exists(interpolatedTreePath)
397
443
  ? tree.read(interpolatedTreePath).toString()
@@ -413,79 +459,12 @@ async function generateChangelogForWorkspace(tree, args, projectGraph, nxRelease
413
459
  rootChangelogContents = contents;
414
460
  }
415
461
  tree.write(interpolatedTreePath, rootChangelogContents);
416
- printSummary = () => (0, print_changes_1.printAndFlushChanges)(tree, !!dryRun, 3, false, noDiffInChangelogMessage);
417
- }
418
- if (config.createRelease === 'github') {
419
- if (!githubRepoSlug) {
420
- output_1.output.error({
421
- title: `Unable to create a GitHub release because the GitHub repo slug could not be determined.`,
422
- bodyLines: [
423
- `Please ensure you have a valid GitHub remote configured. You can run \`git remote -v\` to list your current remotes.`,
424
- ],
425
- });
426
- process.exit(1);
427
- }
428
- const token = await (0, github_1.resolveGithubToken)();
429
- const githubRequestConfig = {
430
- repo: githubRepoSlug,
431
- token,
432
- };
433
- let existingGithubReleaseForVersion;
434
- try {
435
- existingGithubReleaseForVersion = await (0, github_1.getGithubReleaseByTag)(githubRequestConfig, releaseVersion.gitTag);
436
- }
437
- catch (err) {
438
- if (err.response?.status === 401) {
439
- output_1.output.error({
440
- title: `Unable to resolve data via the GitHub API. You can use any of the following options to resolve this:`,
441
- bodyLines: [
442
- '- Set the `GITHUB_TOKEN` or `GH_TOKEN` environment variable to a valid GitHub token with `repo` scope',
443
- '- Have an active session via the official gh CLI tool (https://cli.github.com) in your current terminal',
444
- ],
445
- });
446
- process.exit(1);
447
- }
448
- if (err.response?.status === 404) {
449
- // No existing release found, this is fine
450
- }
451
- else {
452
- // Rethrow unknown errors for now
453
- throw err;
454
- }
455
- }
456
- let existingPrintSummaryFn = printSummary;
457
- printSummary = () => {
458
- const logTitle = `https://github.com/${githubRepoSlug}/releases/tag/${releaseVersion.gitTag}`;
459
- if (existingGithubReleaseForVersion) {
460
- console.error(`${chalk.white('UPDATE')} ${logTitle}${dryRun ? chalk.keyword('orange')(' [dry-run]') : ''}`);
461
- }
462
- else {
463
- console.error(`${chalk.green('CREATE')} ${logTitle}${dryRun ? chalk.keyword('orange')(' [dry-run]') : ''}`);
464
- }
465
- // Only print the diff here if we are not already going to be printing changes from the Tree
466
- if (!interpolatedTreePath) {
467
- console.log('');
468
- (0, print_changes_1.printDiff)(existingGithubReleaseForVersion
469
- ? existingGithubReleaseForVersion.body
470
- : '', contents, 3, noDiffInChangelogMessage);
471
- }
472
- existingPrintSummaryFn();
473
- };
474
- // Only schedule the actual GitHub update when not in dry-run mode
475
- if (!dryRun) {
476
- postGitTasks.push(async (latestCommit) => {
477
- // Before we can create/update the release we need to ensure the commit exists on the remote
478
- await (0, git_1.gitPush)();
479
- await (0, github_1.createOrUpdateGithubRelease)(githubRequestConfig, {
480
- version: releaseVersion.gitTag,
481
- prerelease: releaseVersion.isPrerelease,
482
- body: contents,
483
- commit: latestCommit,
484
- }, existingGithubReleaseForVersion);
485
- });
486
- }
462
+ (0, print_changes_1.printAndFlushChanges)(tree, !!dryRun, 3, false, shared_1.noDiffInChangelogMessage);
487
463
  }
488
- printSummary();
464
+ return {
465
+ releaseVersion,
466
+ contents,
467
+ };
489
468
  }
490
469
  async function generateChangelogForProjects(tree, args, projectGraph, commits, projectsVersionData, postGitTasks, releaseGroup, projects) {
491
470
  const config = releaseGroup.changelog;
@@ -498,6 +477,7 @@ async function generateChangelogForProjects(tree, args, projectGraph, commits, p
498
477
  const dryRun = !!args.dryRun;
499
478
  const gitRemote = args.gitRemote;
500
479
  const changelogRenderer = resolveChangelogRenderer(config.renderer);
480
+ const projectChangelogs = {};
501
481
  for (const project of projects) {
502
482
  let interpolatedTreePath = config.file || '';
503
483
  if (interpolatedTreePath) {
@@ -519,21 +499,12 @@ async function generateChangelogForProjects(tree, args, projectGraph, commits, p
519
499
  releaseTagPattern: releaseGroup.releaseTagPattern,
520
500
  projectName: project.name,
521
501
  });
522
- // We are either creating/previewing a changelog file, a GitHub release, or both
523
- let logTitle = dryRun ? 'Previewing a' : 'Generating a';
524
- switch (true) {
525
- case interpolatedTreePath && config.createRelease === 'github':
526
- logTitle += ` GitHub release and an entry in ${interpolatedTreePath} for ${chalk.white(releaseVersion.gitTag)}`;
527
- break;
528
- case !!interpolatedTreePath:
529
- logTitle += `n entry in ${interpolatedTreePath} for ${chalk.white(releaseVersion.gitTag)}`;
530
- break;
531
- case config.createRelease === 'github':
532
- logTitle += ` GitHub release for ${chalk.white(releaseVersion.gitTag)}`;
502
+ if (interpolatedTreePath) {
503
+ const prefix = dryRun ? 'Previewing' : 'Generating';
504
+ output_1.output.log({
505
+ title: `${prefix} an entry in ${interpolatedTreePath} for ${chalk.white(releaseVersion.gitTag)}`,
506
+ });
533
507
  }
534
- output_1.output.log({
535
- title: logTitle,
536
- });
537
508
  const githubRepoSlug = config.createRelease === 'github'
538
509
  ? (0, github_1.getGitHubRepoSlug)(gitRemote)
539
510
  : undefined;
@@ -565,12 +536,6 @@ async function generateChangelogForProjects(tree, args, projectGraph, commits, p
565
536
  await (0, launch_editor_1.launchEditor)(changelogPath);
566
537
  contents = (0, node_fs_1.readFileSync)(changelogPath, 'utf-8');
567
538
  }
568
- /**
569
- * The exact logic we use for printing the summary/diff to the user is dependent upon whether they are creating
570
- * a changelog file, a GitHub release, or both.
571
- */
572
- let printSummary = () => { };
573
- const noDiffInChangelogMessage = chalk.yellow(`NOTE: There was no diff detected for the changelog entry. Maybe you intended to pass alternative git references via --from and --to?`);
574
539
  if (interpolatedTreePath) {
575
540
  let changelogContents = tree.exists(interpolatedTreePath)
576
541
  ? tree.read(interpolatedTreePath).toString()
@@ -592,82 +557,16 @@ async function generateChangelogForProjects(tree, args, projectGraph, commits, p
592
557
  changelogContents = contents;
593
558
  }
594
559
  tree.write(interpolatedTreePath, changelogContents);
595
- printSummary = () => (0, print_changes_1.printAndFlushChanges)(tree, !!dryRun, 3, false, noDiffInChangelogMessage,
560
+ (0, print_changes_1.printAndFlushChanges)(tree, !!dryRun, 3, false, shared_1.noDiffInChangelogMessage,
596
561
  // Only print the change for the current changelog file at this point
597
562
  (f) => f.path === interpolatedTreePath);
598
563
  }
599
- if (config.createRelease === 'github') {
600
- if (!githubRepoSlug) {
601
- output_1.output.error({
602
- title: `Unable to create a GitHub release because the GitHub repo slug could not be determined.`,
603
- bodyLines: [
604
- `Please ensure you have a valid GitHub remote configured. You can run \`git remote -v\` to list your current remotes.`,
605
- ],
606
- });
607
- process.exit(1);
608
- }
609
- const token = await (0, github_1.resolveGithubToken)();
610
- const githubRequestConfig = {
611
- repo: githubRepoSlug,
612
- token,
613
- };
614
- let existingGithubReleaseForVersion;
615
- try {
616
- existingGithubReleaseForVersion = await (0, github_1.getGithubReleaseByTag)(githubRequestConfig, releaseVersion.gitTag);
617
- }
618
- catch (err) {
619
- if (err.response?.status === 401) {
620
- output_1.output.error({
621
- title: `Unable to resolve data via the GitHub API. You can use any of the following options to resolve this:`,
622
- bodyLines: [
623
- '- Set the `GITHUB_TOKEN` or `GH_TOKEN` environment variable to a valid GitHub token with `repo` scope',
624
- '- Have an active session via the official gh CLI tool (https://cli.github.com) in your current terminal',
625
- ],
626
- });
627
- process.exit(1);
628
- }
629
- if (err.response?.status === 404) {
630
- // No existing release found, this is fine
631
- }
632
- else {
633
- // Rethrow unknown errors for now
634
- throw err;
635
- }
636
- }
637
- let existingPrintSummaryFn = printSummary;
638
- printSummary = () => {
639
- const logTitle = `https://github.com/${githubRepoSlug}/releases/tag/${releaseVersion.gitTag}`;
640
- if (existingGithubReleaseForVersion) {
641
- console.error(`${chalk.white('UPDATE')} ${logTitle}${dryRun ? chalk.keyword('orange')(' [dry-run]') : ''}`);
642
- }
643
- else {
644
- console.error(`${chalk.green('CREATE')} ${logTitle}${dryRun ? chalk.keyword('orange')(' [dry-run]') : ''}`);
645
- }
646
- // Only print the diff here if we are not already going to be printing changes from the Tree
647
- if (!interpolatedTreePath) {
648
- console.log('');
649
- (0, print_changes_1.printDiff)(existingGithubReleaseForVersion
650
- ? existingGithubReleaseForVersion.body
651
- : '', contents, 3, noDiffInChangelogMessage);
652
- }
653
- existingPrintSummaryFn();
654
- };
655
- // Only schedule the actual GitHub update when not in dry-run mode
656
- if (!dryRun) {
657
- postGitTasks.push(async (latestCommit) => {
658
- // Before we can create/update the release we need to ensure the commit exists on the remote
659
- await (0, git_1.gitPush)(gitRemote);
660
- await (0, github_1.createOrUpdateGithubRelease)(githubRequestConfig, {
661
- version: releaseVersion.gitTag,
662
- prerelease: releaseVersion.isPrerelease,
663
- body: contents,
664
- commit: latestCommit,
665
- }, existingGithubReleaseForVersion);
666
- });
667
- }
668
- }
669
- printSummary();
564
+ projectChangelogs[project.name] = {
565
+ releaseVersion,
566
+ contents,
567
+ };
670
568
  }
569
+ return projectChangelogs;
671
570
  }
672
571
  function checkChangelogFilesEnabled(nxReleaseConfig) {
673
572
  if (nxReleaseConfig.changelog.workspaceChangelog &&
@@ -694,3 +593,10 @@ async function getCommits(fromSHA, toSHA) {
694
593
  return false;
695
594
  });
696
595
  }
596
+ function shouldCreateGitHubRelease(changelogConfig, createReleaseArg = undefined) {
597
+ if (createReleaseArg !== undefined) {
598
+ return createReleaseArg === 'github';
599
+ }
600
+ return (changelogConfig || {}).createRelease === 'github';
601
+ }
602
+ exports.shouldCreateGitHubRelease = shouldCreateGitHubRelease;
@@ -29,6 +29,7 @@ export type ChangelogOptions = NxReleaseArgs & GitCommitAndTagOptions & {
29
29
  from?: string;
30
30
  interactive?: string;
31
31
  gitRemote?: string;
32
+ createRelease?: false | 'github';
32
33
  };
33
34
  export type PublishOptions = NxReleaseArgs & Partial<RunManyOptions> & {
34
35
  outputStyle?: OutputStyle;