nx 18.0.4 → 18.0.6

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 (38) hide show
  1. package/package.json +13 -12
  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 -194
  9. package/src/command-line/release/command-object.d.ts +1 -0
  10. package/src/command-line/release/release.js +56 -3
  11. package/src/command-line/release/utils/git.d.ts +5 -1
  12. package/src/command-line/release/utils/git.js +41 -12
  13. package/src/command-line/release/utils/github.d.ts +4 -8
  14. package/src/command-line/release/utils/github.js +61 -2
  15. package/src/command-line/release/utils/shared.d.ts +1 -0
  16. package/src/command-line/release/utils/shared.js +3 -1
  17. package/src/core/graph/3rdpartylicenses.txt +0 -51
  18. package/src/core/graph/main.js +1 -1
  19. package/src/core/graph/polyfills.js +1 -1
  20. package/src/core/graph/runtime.js +1 -1
  21. package/src/core/graph/styles.js +1 -1
  22. package/src/migrations/update-17-0-0/rm-default-collection-npm-scope.js +3 -3
  23. package/src/plugins/js/utils/register.js +1 -0
  24. package/src/plugins/target-defaults/target-defaults-plugin.d.ts +2 -3
  25. package/src/plugins/target-defaults/target-defaults-plugin.js +24 -32
  26. package/src/project-graph/utils/project-configuration-utils.js +13 -6
  27. package/src/tasks-runner/life-cycles/dynamic-run-many-terminal-output-life-cycle.js +20 -23
  28. package/src/tasks-runner/life-cycles/dynamic-run-one-terminal-output-life-cycle.js +16 -16
  29. package/src/tasks-runner/life-cycles/static-run-many-terminal-output-life-cycle.js +1 -1
  30. package/src/tasks-runner/life-cycles/view-logs-utils.js +1 -1
  31. package/src/tasks-runner/task-orchestrator.js +23 -1
  32. package/src/utils/json.js +3 -1
  33. package/src/utils/logger.js +1 -1
  34. package/src/utils/output.d.ts +0 -1
  35. package/src/utils/output.js +6 -7
  36. package/src/utils/package-json.d.ts +1 -1
  37. package/src/utils/package-json.js +12 -11
  38. 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.4",
3
+ "version": "18.0.6",
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,7 +66,7 @@
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.4"
69
+ "@nrwl/tao": "18.0.6"
70
70
  },
71
71
  "peerDependencies": {
72
72
  "@swc-node/register": "^1.8.0",
@@ -81,16 +81,16 @@
81
81
  }
82
82
  },
83
83
  "optionalDependencies": {
84
- "@nx/nx-darwin-x64": "18.0.4",
85
- "@nx/nx-darwin-arm64": "18.0.4",
86
- "@nx/nx-linux-x64-gnu": "18.0.4",
87
- "@nx/nx-linux-x64-musl": "18.0.4",
88
- "@nx/nx-win32-x64-msvc": "18.0.4",
89
- "@nx/nx-linux-arm64-gnu": "18.0.4",
90
- "@nx/nx-linux-arm64-musl": "18.0.4",
91
- "@nx/nx-linux-arm-gnueabihf": "18.0.4",
92
- "@nx/nx-win32-arm64-msvc": "18.0.4",
93
- "@nx/nx-freebsd-x64": "18.0.4"
84
+ "@nx/nx-darwin-x64": "18.0.6",
85
+ "@nx/nx-darwin-arm64": "18.0.6",
86
+ "@nx/nx-linux-x64-gnu": "18.0.6",
87
+ "@nx/nx-linux-x64-musl": "18.0.6",
88
+ "@nx/nx-win32-x64-msvc": "18.0.6",
89
+ "@nx/nx-linux-arm64-gnu": "18.0.6",
90
+ "@nx/nx-linux-arm64-musl": "18.0.6",
91
+ "@nx/nx-linux-arm-gnueabihf": "18.0.6",
92
+ "@nx/nx-win32-arm64-msvc": "18.0.6",
93
+ "@nx/nx-freebsd-x64": "18.0.6"
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");
@@ -74,7 +74,7 @@ async function releaseChangelog(args) {
74
74
  `To explicitly enable changelog generation, configure "release.changelog.workspaceChangelog" or "release.changelog.projectChangelogs" in nx.json.`,
75
75
  ],
76
76
  });
77
- return 0;
77
+ return {};
78
78
  }
79
79
  const useAutomaticFromRef = nxReleaseConfig.changelog?.automaticFromRef || args.firstRelease;
80
80
  /**
@@ -128,7 +128,26 @@ async function releaseChangelog(args) {
128
128
  // Make sure that the fromRef is actually resolvable
129
129
  const workspaceChangelogFromSHA = await (0, git_1.getCommitHash)(workspaceChangelogFromRef);
130
130
  const workspaceChangelogCommits = await getCommits(workspaceChangelogFromSHA, toSHA);
131
- 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 = {};
132
151
  for (const releaseGroup of releaseGroups) {
133
152
  const config = releaseGroup.changelog;
134
153
  // The entire feature is disabled at the release group level, exit early
@@ -164,7 +183,28 @@ async function releaseChangelog(args) {
164
183
  if (!commits) {
165
184
  commits = await getCommits(fromRef, toSHA);
166
185
  }
167
- 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
+ }
168
208
  }
169
209
  }
170
210
  else {
@@ -176,10 +216,35 @@ async function releaseChangelog(args) {
176
216
  // Make sure that the fromRef is actually resolvable
177
217
  const fromSHA = await (0, git_1.getCommitHash)(fromRef);
178
218
  const commits = await getCommits(fromSHA, toSHA);
179
- 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
+ }
180
241
  }
181
242
  }
182
- 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
+ };
183
248
  }
184
249
  exports.releaseChangelog = releaseChangelog;
185
250
  function resolveChangelogVersions(args, releaseGroups, releaseGroupToFilteredProjects) {
@@ -237,7 +302,7 @@ async function applyChangesAndExit(args, nxReleaseConfig, tree, toSHA, postGitTa
237
302
  `No changes were detected for any changelog files, so no changelog entries will be generated.`,
238
303
  ],
239
304
  });
240
- return 0;
305
+ return;
241
306
  }
242
307
  // Generate a new commit for the changes, if configured to do so
243
308
  if (args.gitCommit ?? nxReleaseConfig.changelog.git.commit) {
@@ -271,7 +336,7 @@ async function applyChangesAndExit(args, nxReleaseConfig, tree, toSHA, postGitTa
271
336
  for (const postGitTask of postGitTasks) {
272
337
  await postGitTask(latestCommit);
273
338
  }
274
- return 0;
339
+ return;
275
340
  }
276
341
  function resolveChangelogRenderer(changelogRendererPath) {
277
342
  // Try and load the provided (or default) changelog renderer
@@ -292,7 +357,7 @@ function resolveChangelogRenderer(changelogRendererPath) {
292
357
  }
293
358
  return changelogRenderer;
294
359
  }
295
- async function generateChangelogForWorkspace(tree, args, projectGraph, nxReleaseConfig, workspaceChangelogVersion, commits, postGitTasks) {
360
+ async function generateChangelogForWorkspace(tree, args, projectGraph, nxReleaseConfig, workspaceChangelogVersion, commits) {
296
361
  const config = nxReleaseConfig.changelog.workspaceChangelog;
297
362
  // The entire feature is disabled at the workspace level, exit early
298
363
  if (config === false) {
@@ -344,21 +409,12 @@ async function generateChangelogForWorkspace(tree, args, projectGraph, nxRelease
344
409
  version: workspaceChangelogVersion,
345
410
  releaseTagPattern: nxReleaseConfig.releaseTagPattern,
346
411
  });
347
- // We are either creating/previewing a changelog file, a GitHub release, or both
348
- let logTitle = dryRun ? 'Previewing a' : 'Generating a';
349
- switch (true) {
350
- case interpolatedTreePath && config.createRelease === 'github':
351
- logTitle += ` GitHub release and an entry in ${interpolatedTreePath} for ${chalk.white(releaseVersion.gitTag)}`;
352
- break;
353
- case !!interpolatedTreePath:
354
- logTitle += `n entry in ${interpolatedTreePath} for ${chalk.white(releaseVersion.gitTag)}`;
355
- break;
356
- case config.createRelease === 'github':
357
- logTitle += ` GitHub release for ${chalk.white(releaseVersion.gitTag)}`;
358
- }
359
- output_1.output.log({
360
- title: logTitle,
361
- });
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
+ }
362
418
  const githubRepoSlug = (0, github_1.getGitHubRepoSlug)(gitRemote);
363
419
  let contents = await changelogRenderer({
364
420
  projectGraph,
@@ -382,12 +438,6 @@ async function generateChangelogForWorkspace(tree, args, projectGraph, nxRelease
382
438
  await (0, launch_editor_1.launchEditor)(changelogPath);
383
439
  contents = (0, node_fs_1.readFileSync)(changelogPath, 'utf-8');
384
440
  }
385
- /**
386
- * The exact logic we use for printing the summary/diff to the user is dependent upon whether they are creating
387
- * a changelog file, a GitHub release, or both.
388
- */
389
- let printSummary = () => { };
390
- 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?`);
391
441
  if (interpolatedTreePath) {
392
442
  let rootChangelogContents = tree.exists(interpolatedTreePath)
393
443
  ? tree.read(interpolatedTreePath).toString()
@@ -409,79 +459,12 @@ async function generateChangelogForWorkspace(tree, args, projectGraph, nxRelease
409
459
  rootChangelogContents = contents;
410
460
  }
411
461
  tree.write(interpolatedTreePath, rootChangelogContents);
412
- printSummary = () => (0, print_changes_1.printAndFlushChanges)(tree, !!dryRun, 3, false, noDiffInChangelogMessage);
413
- }
414
- if (config.createRelease === 'github') {
415
- if (!githubRepoSlug) {
416
- output_1.output.error({
417
- title: `Unable to create a GitHub release because the GitHub repo slug could not be determined.`,
418
- bodyLines: [
419
- `Please ensure you have a valid GitHub remote configured. You can run \`git remote -v\` to list your current remotes.`,
420
- ],
421
- });
422
- process.exit(1);
423
- }
424
- const token = await (0, github_1.resolveGithubToken)();
425
- const githubRequestConfig = {
426
- repo: githubRepoSlug,
427
- token,
428
- };
429
- let existingGithubReleaseForVersion;
430
- try {
431
- existingGithubReleaseForVersion = await (0, github_1.getGithubReleaseByTag)(githubRequestConfig, releaseVersion.gitTag);
432
- }
433
- catch (err) {
434
- if (err.response?.status === 401) {
435
- output_1.output.error({
436
- title: `Unable to resolve data via the GitHub API. You can use any of the following options to resolve this:`,
437
- bodyLines: [
438
- '- Set the `GITHUB_TOKEN` or `GH_TOKEN` environment variable to a valid GitHub token with `repo` scope',
439
- '- Have an active session via the official gh CLI tool (https://cli.github.com) in your current terminal',
440
- ],
441
- });
442
- process.exit(1);
443
- }
444
- if (err.response?.status === 404) {
445
- // No existing release found, this is fine
446
- }
447
- else {
448
- // Rethrow unknown errors for now
449
- throw err;
450
- }
451
- }
452
- let existingPrintSummaryFn = printSummary;
453
- printSummary = () => {
454
- const logTitle = `https://github.com/${githubRepoSlug}/releases/tag/${releaseVersion.gitTag}`;
455
- if (existingGithubReleaseForVersion) {
456
- console.error(`${chalk.white('UPDATE')} ${logTitle}${dryRun ? chalk.keyword('orange')(' [dry-run]') : ''}`);
457
- }
458
- else {
459
- console.error(`${chalk.green('CREATE')} ${logTitle}${dryRun ? chalk.keyword('orange')(' [dry-run]') : ''}`);
460
- }
461
- // Only print the diff here if we are not already going to be printing changes from the Tree
462
- if (!interpolatedTreePath) {
463
- console.log('');
464
- (0, print_changes_1.printDiff)(existingGithubReleaseForVersion
465
- ? existingGithubReleaseForVersion.body
466
- : '', contents, 3, noDiffInChangelogMessage);
467
- }
468
- existingPrintSummaryFn();
469
- };
470
- // Only schedule the actual GitHub update when not in dry-run mode
471
- if (!dryRun) {
472
- postGitTasks.push(async (latestCommit) => {
473
- // Before we can create/update the release we need to ensure the commit exists on the remote
474
- await (0, git_1.gitPush)();
475
- await (0, github_1.createOrUpdateGithubRelease)(githubRequestConfig, {
476
- version: releaseVersion.gitTag,
477
- prerelease: releaseVersion.isPrerelease,
478
- body: contents,
479
- commit: latestCommit,
480
- }, existingGithubReleaseForVersion);
481
- });
482
- }
462
+ (0, print_changes_1.printAndFlushChanges)(tree, !!dryRun, 3, false, shared_1.noDiffInChangelogMessage);
483
463
  }
484
- printSummary();
464
+ return {
465
+ releaseVersion,
466
+ contents,
467
+ };
485
468
  }
486
469
  async function generateChangelogForProjects(tree, args, projectGraph, commits, projectsVersionData, postGitTasks, releaseGroup, projects) {
487
470
  const config = releaseGroup.changelog;
@@ -494,6 +477,7 @@ async function generateChangelogForProjects(tree, args, projectGraph, commits, p
494
477
  const dryRun = !!args.dryRun;
495
478
  const gitRemote = args.gitRemote;
496
479
  const changelogRenderer = resolveChangelogRenderer(config.renderer);
480
+ const projectChangelogs = {};
497
481
  for (const project of projects) {
498
482
  let interpolatedTreePath = config.file || '';
499
483
  if (interpolatedTreePath) {
@@ -515,21 +499,12 @@ async function generateChangelogForProjects(tree, args, projectGraph, commits, p
515
499
  releaseTagPattern: releaseGroup.releaseTagPattern,
516
500
  projectName: project.name,
517
501
  });
518
- // We are either creating/previewing a changelog file, a GitHub release, or both
519
- let logTitle = dryRun ? 'Previewing a' : 'Generating a';
520
- switch (true) {
521
- case interpolatedTreePath && config.createRelease === 'github':
522
- logTitle += ` GitHub release and an entry in ${interpolatedTreePath} for ${chalk.white(releaseVersion.gitTag)}`;
523
- break;
524
- case !!interpolatedTreePath:
525
- logTitle += `n entry in ${interpolatedTreePath} for ${chalk.white(releaseVersion.gitTag)}`;
526
- break;
527
- case config.createRelease === 'github':
528
- 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
+ });
529
507
  }
530
- output_1.output.log({
531
- title: logTitle,
532
- });
533
508
  const githubRepoSlug = config.createRelease === 'github'
534
509
  ? (0, github_1.getGitHubRepoSlug)(gitRemote)
535
510
  : undefined;
@@ -561,12 +536,6 @@ async function generateChangelogForProjects(tree, args, projectGraph, commits, p
561
536
  await (0, launch_editor_1.launchEditor)(changelogPath);
562
537
  contents = (0, node_fs_1.readFileSync)(changelogPath, 'utf-8');
563
538
  }
564
- /**
565
- * The exact logic we use for printing the summary/diff to the user is dependent upon whether they are creating
566
- * a changelog file, a GitHub release, or both.
567
- */
568
- let printSummary = () => { };
569
- 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?`);
570
539
  if (interpolatedTreePath) {
571
540
  let changelogContents = tree.exists(interpolatedTreePath)
572
541
  ? tree.read(interpolatedTreePath).toString()
@@ -588,82 +557,16 @@ async function generateChangelogForProjects(tree, args, projectGraph, commits, p
588
557
  changelogContents = contents;
589
558
  }
590
559
  tree.write(interpolatedTreePath, changelogContents);
591
- printSummary = () => (0, print_changes_1.printAndFlushChanges)(tree, !!dryRun, 3, false, noDiffInChangelogMessage,
560
+ (0, print_changes_1.printAndFlushChanges)(tree, !!dryRun, 3, false, shared_1.noDiffInChangelogMessage,
592
561
  // Only print the change for the current changelog file at this point
593
562
  (f) => f.path === interpolatedTreePath);
594
563
  }
595
- if (config.createRelease === 'github') {
596
- if (!githubRepoSlug) {
597
- output_1.output.error({
598
- title: `Unable to create a GitHub release because the GitHub repo slug could not be determined.`,
599
- bodyLines: [
600
- `Please ensure you have a valid GitHub remote configured. You can run \`git remote -v\` to list your current remotes.`,
601
- ],
602
- });
603
- process.exit(1);
604
- }
605
- const token = await (0, github_1.resolveGithubToken)();
606
- const githubRequestConfig = {
607
- repo: githubRepoSlug,
608
- token,
609
- };
610
- let existingGithubReleaseForVersion;
611
- try {
612
- existingGithubReleaseForVersion = await (0, github_1.getGithubReleaseByTag)(githubRequestConfig, releaseVersion.gitTag);
613
- }
614
- catch (err) {
615
- if (err.response?.status === 401) {
616
- output_1.output.error({
617
- title: `Unable to resolve data via the GitHub API. You can use any of the following options to resolve this:`,
618
- bodyLines: [
619
- '- Set the `GITHUB_TOKEN` or `GH_TOKEN` environment variable to a valid GitHub token with `repo` scope',
620
- '- Have an active session via the official gh CLI tool (https://cli.github.com) in your current terminal',
621
- ],
622
- });
623
- process.exit(1);
624
- }
625
- if (err.response?.status === 404) {
626
- // No existing release found, this is fine
627
- }
628
- else {
629
- // Rethrow unknown errors for now
630
- throw err;
631
- }
632
- }
633
- let existingPrintSummaryFn = printSummary;
634
- printSummary = () => {
635
- const logTitle = `https://github.com/${githubRepoSlug}/releases/tag/${releaseVersion.gitTag}`;
636
- if (existingGithubReleaseForVersion) {
637
- console.error(`${chalk.white('UPDATE')} ${logTitle}${dryRun ? chalk.keyword('orange')(' [dry-run]') : ''}`);
638
- }
639
- else {
640
- console.error(`${chalk.green('CREATE')} ${logTitle}${dryRun ? chalk.keyword('orange')(' [dry-run]') : ''}`);
641
- }
642
- // Only print the diff here if we are not already going to be printing changes from the Tree
643
- if (!interpolatedTreePath) {
644
- console.log('');
645
- (0, print_changes_1.printDiff)(existingGithubReleaseForVersion
646
- ? existingGithubReleaseForVersion.body
647
- : '', contents, 3, noDiffInChangelogMessage);
648
- }
649
- existingPrintSummaryFn();
650
- };
651
- // Only schedule the actual GitHub update when not in dry-run mode
652
- if (!dryRun) {
653
- postGitTasks.push(async (latestCommit) => {
654
- // Before we can create/update the release we need to ensure the commit exists on the remote
655
- await (0, git_1.gitPush)(gitRemote);
656
- await (0, github_1.createOrUpdateGithubRelease)(githubRequestConfig, {
657
- version: releaseVersion.gitTag,
658
- prerelease: releaseVersion.isPrerelease,
659
- body: contents,
660
- commit: latestCommit,
661
- }, existingGithubReleaseForVersion);
662
- });
663
- }
664
- }
665
- printSummary();
564
+ projectChangelogs[project.name] = {
565
+ releaseVersion,
566
+ contents,
567
+ };
666
568
  }
569
+ return projectChangelogs;
667
570
  }
668
571
  function checkChangelogFilesEnabled(nxReleaseConfig) {
669
572
  if (nxReleaseConfig.changelog.workspaceChangelog &&
@@ -690,3 +593,10 @@ async function getCommits(fromSHA, toSHA) {
690
593
  return false;
691
594
  });
692
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;