nx 16.9.0-beta.0 → 16.9.0-beta.2

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 (89) hide show
  1. package/bin/nx.js +6 -1
  2. package/package.json +14 -13
  3. package/src/command-line/affected/affected.js +5 -1
  4. package/src/command-line/affected/print-affected.js +1 -2
  5. package/src/command-line/generate/generate.d.ts +4 -0
  6. package/src/command-line/generate/generate.js +2 -1
  7. package/src/command-line/graph/graph.js +0 -2
  8. package/src/command-line/nx-commands.js +2 -0
  9. package/src/command-line/release/changelog.d.ts +2 -0
  10. package/src/command-line/release/changelog.js +111 -0
  11. package/src/command-line/release/command-object.d.ts +25 -0
  12. package/src/command-line/release/command-object.js +128 -0
  13. package/src/command-line/release/config/config.d.ts +2 -0
  14. package/src/command-line/release/config/config.js +12 -0
  15. package/src/command-line/release/config/create-release-groups.d.ts +25 -0
  16. package/src/command-line/release/config/create-release-groups.js +167 -0
  17. package/src/command-line/release/publish.d.ts +4 -0
  18. package/src/command-line/release/publish.js +148 -0
  19. package/src/command-line/release/utils/git.d.ts +26 -0
  20. package/src/command-line/release/utils/git.js +115 -0
  21. package/src/command-line/release/utils/github.d.ts +22 -0
  22. package/src/command-line/release/utils/github.js +262 -0
  23. package/src/command-line/release/utils/launch-editor.d.ts +1 -0
  24. package/src/command-line/release/utils/launch-editor.js +42 -0
  25. package/src/command-line/release/utils/print-diff.d.ts +1 -0
  26. package/src/command-line/release/utils/print-diff.js +17 -0
  27. package/src/command-line/release/utils/resolve-nx-json-error-message.d.ts +1 -0
  28. package/src/command-line/release/utils/resolve-nx-json-error-message.js +49 -0
  29. package/src/command-line/release/utils/semver.d.ts +3 -0
  30. package/src/command-line/release/utils/semver.js +30 -0
  31. package/src/command-line/release/version.d.ts +13 -0
  32. package/src/command-line/release/version.js +261 -0
  33. package/src/command-line/run/run-one.js +5 -1
  34. package/src/command-line/run-many/run-many.js +5 -1
  35. package/src/command-line/yargs-utils/shared-options.d.ts +27 -76
  36. package/src/command-line/yargs-utils/shared-options.js +10 -7
  37. package/src/config/nx-json.d.ts +28 -0
  38. package/src/core/graph/main.js +1 -1
  39. package/src/core/graph/polyfills.js +1 -1
  40. package/src/daemon/server/handle-hash-tasks.js +1 -2
  41. package/src/daemon/server/handle-request-file-data.js +3 -2
  42. package/src/daemon/server/project-graph-incremental-recomputation.js +7 -5
  43. package/src/daemon/server/server.js +4 -2
  44. package/src/devkit-exports.d.ts +9 -2
  45. package/src/devkit-exports.js +10 -2
  46. package/src/devkit-internals.d.ts +1 -0
  47. package/src/devkit-internals.js +3 -1
  48. package/src/generators/utils/deprecated.js +2 -1
  49. package/src/generators/utils/glob.d.ts +11 -0
  50. package/src/generators/utils/glob.js +35 -0
  51. package/src/hasher/file-hasher.d.ts +0 -13
  52. package/src/hasher/file-hasher.js +1 -63
  53. package/src/hasher/task-hasher.d.ts +1 -3
  54. package/src/hasher/task-hasher.js +12 -6
  55. package/src/native/index.d.ts +14 -14
  56. package/src/native/index.js +2 -4
  57. package/src/plugins/js/index.js +1 -1
  58. package/src/plugins/js/lock-file/lock-file.d.ts +3 -2
  59. package/src/plugins/js/lock-file/lock-file.js +4 -4
  60. package/src/plugins/js/lock-file/npm-parser.d.ts +3 -2
  61. package/src/plugins/js/lock-file/npm-parser.js +12 -12
  62. package/src/plugins/js/lock-file/pnpm-parser.d.ts +3 -2
  63. package/src/plugins/js/lock-file/pnpm-parser.js +7 -7
  64. package/src/plugins/js/lock-file/yarn-parser.d.ts +3 -2
  65. package/src/plugins/js/lock-file/yarn-parser.js +5 -5
  66. package/src/plugins/js/project-graph/build-dependencies/build-dependencies.d.ts +2 -2
  67. package/src/plugins/js/project-graph/build-dependencies/explicit-package-json-dependencies.d.ts +2 -2
  68. package/src/plugins/js/project-graph/build-dependencies/explicit-package-json-dependencies.js +16 -17
  69. package/src/plugins/js/project-graph/build-dependencies/explicit-project-dependencies.d.ts +2 -2
  70. package/src/plugins/js/project-graph/build-dependencies/explicit-project-dependencies.js +33 -13
  71. package/src/project-graph/build-project-graph.js +9 -3
  72. package/src/project-graph/file-map-utils.js +3 -3
  73. package/src/project-graph/project-graph-builder.d.ts +50 -7
  74. package/src/project-graph/project-graph-builder.js +46 -30
  75. package/src/project-graph/utils/retrieve-workspace-files.d.ts +4 -0
  76. package/src/project-graph/utils/retrieve-workspace-files.js +8 -11
  77. package/src/tasks-runner/run-command.d.ts +1 -1
  78. package/src/tasks-runner/run-command.js +2 -6
  79. package/src/utils/all-file-data.js +3 -3
  80. package/src/utils/command-line-utils.d.ts +2 -1
  81. package/src/utils/command-line-utils.js +16 -11
  82. package/src/utils/nx-plugin.d.ts +8 -7
  83. package/src/utils/package-json.js +8 -0
  84. package/src/utils/workspace-context.d.ts +8 -0
  85. package/src/utils/workspace-context.js +46 -0
  86. package/src/utils/testing/mock-fs.d.ts +0 -0
  87. package/src/utils/testing/mock-fs.js +0 -30
  88. package/src/utils/testing/temp-fs.d.ts +0 -20
  89. package/src/utils/testing/temp-fs.js +0 -59
package/bin/nx.js CHANGED
@@ -15,6 +15,8 @@ const child_process_1 = require("child_process");
15
15
  const path_1 = require("path");
16
16
  const assert_supported_platform_1 = require("../src/native/assert-supported-platform");
17
17
  const perf_hooks_1 = require("perf_hooks");
18
+ const workspace_context_1 = require("../src/utils/workspace-context");
19
+ const client_1 = require("../src/daemon/client/client");
18
20
  function main() {
19
21
  if (process.argv[2] !== 'report' &&
20
22
  process.argv[2] !== '--version' &&
@@ -42,9 +44,12 @@ function main() {
42
44
  // Angular CLI, and prettier both use ESM so we need to disable it in these cases.
43
45
  if (workspace &&
44
46
  workspace.type === 'nx' &&
45
- !['format', 'format:check', 'format:write', 'g', 'generate'].some((cmd) => process.argv[3] === cmd)) {
47
+ !['format', 'format:check', 'format:write', 'g', 'generate'].some((cmd) => process.argv[2] === cmd)) {
46
48
  require('v8-compile-cache');
47
49
  }
50
+ if (!client_1.daemonClient.enabled() && workspace !== null) {
51
+ (0, workspace_context_1.setupWorkspaceContext)(workspace.dir);
52
+ }
48
53
  // polyfill rxjs observable to avoid issues with multiple version of Observable installed in node_modules
49
54
  // https://twitter.com/BenLesh/status/1192478226385428483?s=20
50
55
  if (!Symbol.observable)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nx",
3
- "version": "16.9.0-beta.0",
3
+ "version": "16.9.0-beta.2",
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": {
@@ -32,7 +32,7 @@
32
32
  },
33
33
  "homepage": "https://nx.dev",
34
34
  "dependencies": {
35
- "@nrwl/tao": "16.9.0-beta.0",
35
+ "@nrwl/tao": "16.9.0-beta.2",
36
36
  "@parcel/watcher": "2.0.4",
37
37
  "@yarnpkg/lockfile": "^1.1.0",
38
38
  "@yarnpkg/parsers": "3.0.0-rc.46",
@@ -50,6 +50,7 @@
50
50
  "fs-extra": "^11.1.0",
51
51
  "glob": "7.1.4",
52
52
  "ignore": "^5.0.4",
53
+ "jest-diff": "^29.4.1",
53
54
  "js-yaml": "4.1.0",
54
55
  "jsonc-parser": "3.2.0",
55
56
  "lines-and-columns": "~2.0.3",
@@ -81,16 +82,16 @@
81
82
  }
82
83
  },
83
84
  "optionalDependencies": {
84
- "@nx/nx-darwin-arm64": "16.9.0-beta.0",
85
- "@nx/nx-darwin-x64": "16.9.0-beta.0",
86
- "@nx/nx-freebsd-x64": "16.9.0-beta.0",
87
- "@nx/nx-linux-arm-gnueabihf": "16.9.0-beta.0",
88
- "@nx/nx-linux-arm64-gnu": "16.9.0-beta.0",
89
- "@nx/nx-linux-arm64-musl": "16.9.0-beta.0",
90
- "@nx/nx-linux-x64-gnu": "16.9.0-beta.0",
91
- "@nx/nx-linux-x64-musl": "16.9.0-beta.0",
92
- "@nx/nx-win32-arm64-msvc": "16.9.0-beta.0",
93
- "@nx/nx-win32-x64-msvc": "16.9.0-beta.0"
85
+ "@nx/nx-darwin-arm64": "16.9.0-beta.2",
86
+ "@nx/nx-darwin-x64": "16.9.0-beta.2",
87
+ "@nx/nx-freebsd-x64": "16.9.0-beta.2",
88
+ "@nx/nx-linux-arm-gnueabihf": "16.9.0-beta.2",
89
+ "@nx/nx-linux-arm64-gnu": "16.9.0-beta.2",
90
+ "@nx/nx-linux-arm64-musl": "16.9.0-beta.2",
91
+ "@nx/nx-linux-x64-gnu": "16.9.0-beta.2",
92
+ "@nx/nx-linux-x64-musl": "16.9.0-beta.2",
93
+ "@nx/nx-win32-arm64-msvc": "16.9.0-beta.2",
94
+ "@nx/nx-win32-x64-msvc": "16.9.0-beta.2"
94
95
  },
95
96
  "nx-migrations": {
96
97
  "migrations": "./migrations.json",
@@ -177,5 +178,5 @@
177
178
  },
178
179
  "main": "./bin/nx.js",
179
180
  "type": "commonjs",
180
- "gitHead": "822fb12c3f0bbaeb6d4a6fbc6cb1064a291e907f"
181
+ "gitHead": "e11d538fa2c7266066d554d9405abab8e0a65040"
181
182
  }
@@ -62,7 +62,11 @@ async function affected(command, args, extraTargetDependencies = {}) {
62
62
  }, projectNames);
63
63
  }
64
64
  else {
65
- await (0, run_command_1.runCommand)(projectsWithTarget, projectGraph, { nxJson }, nxArgs, overrides, null, extraTargetDependencies, { excludeTaskDependencies: false, loadDotEnvFiles: true });
65
+ const status = await (0, run_command_1.runCommand)(projectsWithTarget, projectGraph, { nxJson }, nxArgs, overrides, null, extraTargetDependencies, { excludeTaskDependencies: false, loadDotEnvFiles: true });
66
+ // fix for https://github.com/nrwl/nx/issues/1666
67
+ if (process.stdin['unref'])
68
+ process.stdin.unref();
69
+ process.exit(status);
66
70
  }
67
71
  break;
68
72
  }
@@ -6,7 +6,6 @@ const create_task_graph_1 = require("../../tasks-runner/create-task-graph");
6
6
  const task_hasher_1 = require("../../hasher/task-hasher");
7
7
  const hash_task_1 = require("../../hasher/hash-task");
8
8
  const package_manager_1 = require("../../utils/package-manager");
9
- const file_hasher_1 = require("../../hasher/file-hasher");
10
9
  const command_object_1 = require("./command-object");
11
10
  const logger_1 = require("../../utils/logger");
12
11
  /**
@@ -35,7 +34,7 @@ exports.printAffected = printAffected;
35
34
  async function createTasks(affectedProjectsWithTargetAndConfig, projectGraph, nxArgs, nxJson, overrides) {
36
35
  const defaultDependencyConfigs = (0, create_task_graph_1.mapTargetDefaultsToDependencies)(nxJson.targetDefaults);
37
36
  const taskGraph = (0, create_task_graph_1.createTaskGraph)(projectGraph, defaultDependencyConfigs, affectedProjectsWithTargetAndConfig.map((p) => p.name), nxArgs.targets, nxArgs.configuration, overrides);
38
- const hasher = new task_hasher_1.InProcessTaskHasher({}, [], projectGraph, nxJson, {}, file_hasher_1.fileHasher);
37
+ const hasher = new task_hasher_1.InProcessTaskHasher({}, [], projectGraph, nxJson, {});
39
38
  const execCommand = (0, package_manager_1.getPackageManagerCommand)().exec;
40
39
  const tasks = Object.values(taskGraph.tasks);
41
40
  await Promise.all(tasks.map((t) => (0, hash_task_1.hashTask)(hasher, projectGraph, taskGraph, t)));
@@ -12,6 +12,10 @@ export interface GenerateOptions {
12
12
  quiet: boolean;
13
13
  }
14
14
  export declare function printChanges(fileChanges: FileChange[]): void;
15
+ export declare function parseGeneratorString(value: string): {
16
+ collection?: string;
17
+ generator: string;
18
+ };
15
19
  export declare function printGenHelp(opts: GenerateOptions, schema: Schema, normalizedGeneratorName: string, aliases: string[]): void;
16
20
  export declare function generate(cwd: string, args: {
17
21
  [k: string]: any;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.workspaceGenerators = exports.generate = exports.printGenHelp = exports.printChanges = void 0;
3
+ exports.workspaceGenerators = exports.generate = exports.printGenHelp = exports.parseGeneratorString = exports.printChanges = void 0;
4
4
  const chalk = require("chalk");
5
5
  const enquirer_1 = require("enquirer");
6
6
  const path_1 = require("path");
@@ -145,6 +145,7 @@ function parseGeneratorString(value) {
145
145
  };
146
146
  }
147
147
  }
148
+ exports.parseGeneratorString = parseGeneratorString;
148
149
  async function convertToGenerateOptions(generatorOptions, defaultCollectionName, mode, projectsConfiguration) {
149
150
  let collectionName = null;
150
151
  let generatorName = null;
@@ -18,7 +18,6 @@ const project_graph_1 = require("../../project-graph/project-graph");
18
18
  const create_task_graph_1 = require("../../tasks-runner/create-task-graph");
19
19
  const client_1 = require("../../daemon/client/client");
20
20
  const nx_deps_cache_1 = require("../../project-graph/nx-deps-cache");
21
- const file_hasher_1 = require("../../hasher/file-hasher");
22
21
  const affected_1 = require("../affected/affected");
23
22
  const command_line_utils_1 = require("../../utils/command-line-utils");
24
23
  // maps file extention to MIME types
@@ -381,7 +380,6 @@ function createFileWatcher() {
381
380
  }
382
381
  async function createDepGraphClientResponse(affected = []) {
383
382
  perf_hooks_1.performance.mark('project graph watch calculation:start');
384
- await file_hasher_1.fileHasher.init();
385
383
  let graph = (0, operators_1.pruneExternalNodes)(await (0, project_graph_1.createProjectGraphAsync)({ exitOnError: true }));
386
384
  let fileMap = (0, nx_deps_cache_1.readProjectFileMapCache)().projectFileMap;
387
385
  perf_hooks_1.performance.mark('project graph watch calculation:end');
@@ -22,6 +22,7 @@ const command_object_16 = require("./show/command-object");
22
22
  const command_object_17 = require("./watch/command-object");
23
23
  const command_object_18 = require("./workspace-lint/command-object");
24
24
  const command_object_19 = require("./reset/command-object");
25
+ const command_object_20 = require("./release/command-object");
25
26
  // Ensure that the output takes up the available width of the terminal.
26
27
  yargs.wrap(yargs.terminalWidth());
27
28
  exports.parserConfiguration = {
@@ -57,6 +58,7 @@ exports.commandsObject = yargs
57
58
  .command(command_object_10.yargsMigrateCommand)
58
59
  .command(command_object_11.yargsNewCommand)
59
60
  .command(command_object_1.yargsPrintAffectedCommand)
61
+ .command(command_object_20.yargsReleaseCommand)
60
62
  .command(command_object_12.yargsRepairCommand)
61
63
  .command(command_object_13.yargsReportCommand)
62
64
  .command(command_object_19.yargsResetCommand)
@@ -0,0 +1,2 @@
1
+ import { ChangelogOptions } from './command-object';
2
+ export declare function changelogHandler(args: ChangelogOptions): Promise<void>;
@@ -0,0 +1,111 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.changelogHandler = void 0;
4
+ const chalk = require("chalk");
5
+ const node_fs_1 = require("node:fs");
6
+ const tmp_1 = require("tmp");
7
+ const devkit_exports_1 = require("../../devkit-exports");
8
+ const git_1 = require("./utils/git");
9
+ const github_1 = require("./utils/github");
10
+ const launch_editor_1 = require("./utils/launch-editor");
11
+ const print_diff_1 = require("./utils/print-diff");
12
+ async function changelogHandler(args) {
13
+ /**
14
+ * TODO: allow the prefix and version to be controllable via config as well once we flesh out
15
+ * changelog customization, and how it will interact with independently released projects.
16
+ */
17
+ const tagVersionPrefix = args.tagVersionPrefix ?? 'v';
18
+ const releaseVersion = `${tagVersionPrefix}${args.version}`;
19
+ const githubRemote = (0, github_1.getGitHubRemote)(args.gitRemote);
20
+ const token = await (0, github_1.resolveGithubToken)();
21
+ const githubRequestConfig = {
22
+ repo: githubRemote,
23
+ token,
24
+ };
25
+ const from = args.from || (await (0, git_1.getLastGitTag)());
26
+ if (!from) {
27
+ throw new Error(`Could not determine the previous git tag, please provide and explicit reference using --from`);
28
+ }
29
+ const to = args.to;
30
+ const rawCommits = await (0, git_1.getGitDiff)(from, args.to);
31
+ // Parse as conventional commits
32
+ const commits = (0, git_1.parseCommits)(rawCommits).filter((c) => {
33
+ const type = c.type;
34
+ // Always ignore non user-facing commits for now
35
+ // TODO: allow this filter to be configurable via config in a future release
36
+ if (type === 'feat' || type === 'fix' || type === 'perf') {
37
+ return true;
38
+ }
39
+ return false;
40
+ });
41
+ const initialMarkdown = await (0, github_1.generateMarkdown)(commits, releaseVersion, githubRequestConfig);
42
+ let finalMarkdown = initialMarkdown;
43
+ /**
44
+ * If interactive mode, make the markdown available for the user to modify in their editor of choice,
45
+ * in a similar style to git interactive rebases/merges.
46
+ */
47
+ if (args.interactive) {
48
+ const tmpDir = (0, tmp_1.dirSync)().name;
49
+ const changelogPath = (0, devkit_exports_1.joinPathFragments)(tmpDir, 'c.md');
50
+ (0, node_fs_1.writeFileSync)(changelogPath, initialMarkdown);
51
+ await (0, launch_editor_1.launchEditor)(changelogPath);
52
+ finalMarkdown = (0, node_fs_1.readFileSync)(changelogPath, 'utf-8');
53
+ }
54
+ let existingGithubReleaseForVersion;
55
+ try {
56
+ existingGithubReleaseForVersion = await (0, github_1.getGithubReleaseByTag)(githubRequestConfig, releaseVersion);
57
+ }
58
+ catch (err) {
59
+ if (err.response?.status === 401) {
60
+ devkit_exports_1.output.error({
61
+ title: `Unable to resolve data via the Github API. You can use any of the following options to resolve this:`,
62
+ bodyLines: [
63
+ '- Set the `GITHUB_TOKEN` or `GH_TOKEN` environment variable to a valid Github token with `repo` scope',
64
+ '- Have an active session via the official gh CLI tool (https://cli.github.com) in your current terminal',
65
+ ],
66
+ });
67
+ process.exit(1);
68
+ }
69
+ if (err.response?.status === 404) {
70
+ // No existing release found, this is fine
71
+ }
72
+ else {
73
+ // Rethrow unknown errors for now
74
+ throw err;
75
+ }
76
+ }
77
+ const changesRangeText = to === 'HEAD' ? `since ${from}` : `between ${from} and ${to}`;
78
+ if (existingGithubReleaseForVersion) {
79
+ devkit_exports_1.output.log({
80
+ title: `Found existing Github release for ${chalk.white(releaseVersion)}, regenerating with changes ${chalk.cyan(changesRangeText)}`,
81
+ });
82
+ }
83
+ else {
84
+ devkit_exports_1.output.log({
85
+ title: `Creating a new Github release for ${chalk.white(releaseVersion)}, including changes ${chalk.cyan(changesRangeText)}`,
86
+ });
87
+ }
88
+ printReleaseLog(releaseVersion, githubRemote, args.dryRun, finalMarkdown, existingGithubReleaseForVersion);
89
+ if (args.dryRun) {
90
+ devkit_exports_1.logger.warn(`\nNOTE: The "dryRun" flag means no changes were made.`);
91
+ }
92
+ else {
93
+ await (0, github_1.createOrUpdateGithubRelease)(githubRequestConfig, {
94
+ version: releaseVersion,
95
+ body: finalMarkdown,
96
+ }, existingGithubReleaseForVersion);
97
+ }
98
+ process.exit(0);
99
+ }
100
+ exports.changelogHandler = changelogHandler;
101
+ function printReleaseLog(releaseVersion, githubRemote, isDryRun, finalMarkdown, existingGithubReleaseForVersion) {
102
+ const logTitle = `https://github.com/${githubRemote}/releases/tag/${releaseVersion}`;
103
+ if (existingGithubReleaseForVersion) {
104
+ console.error(`${chalk.white('UPDATE')} ${logTitle}${isDryRun ? chalk.keyword('orange')(' [dry-run]') : ''}`);
105
+ }
106
+ else {
107
+ console.error(`${chalk.green('CREATE')} ${logTitle}${isDryRun ? chalk.keyword('orange')(' [dry-run]') : ''}`);
108
+ }
109
+ console.log('');
110
+ (0, print_diff_1.printDiff)('', finalMarkdown);
111
+ }
@@ -0,0 +1,25 @@
1
+ import { CommandModule } from 'yargs';
2
+ import { RunManyOptions } from '../yargs-utils/shared-options';
3
+ export interface NxReleaseArgs {
4
+ groups?: string[];
5
+ projects?: string[];
6
+ dryRun?: boolean;
7
+ verbose?: boolean;
8
+ }
9
+ export type VersionOptions = NxReleaseArgs & {
10
+ specifier?: string;
11
+ preid?: string;
12
+ };
13
+ export type ChangelogOptions = NxReleaseArgs & {
14
+ version: string;
15
+ to: string;
16
+ from?: string;
17
+ interactive?: boolean;
18
+ gitRemote?: string;
19
+ tagVersionPrefix?: string;
20
+ };
21
+ export type PublishOptions = NxReleaseArgs & RunManyOptions & {
22
+ registry?: string;
23
+ tag?: string;
24
+ };
25
+ export declare const yargsReleaseCommand: CommandModule<Record<string, unknown>, NxReleaseArgs>;
@@ -0,0 +1,128 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.yargsReleaseCommand = void 0;
4
+ const yargs_1 = require("yargs");
5
+ const file_utils_1 = require("../../project-graph/file-utils");
6
+ const shared_options_1 = require("../yargs-utils/shared-options");
7
+ exports.yargsReleaseCommand = {
8
+ command: 'release',
9
+ describe: '**ALPHA**: Orchestrate versioning and publishing of applications and libraries',
10
+ builder: (yargs) => yargs
11
+ .command(versionCommand)
12
+ .command(changelogCommand)
13
+ .command(publishCommand)
14
+ .demandCommand()
15
+ .option('groups', {
16
+ description: 'One or more release groups to target with the current command.',
17
+ type: 'string',
18
+ coerce: shared_options_1.parseCSV,
19
+ alias: ['group', 'g'],
20
+ })
21
+ .option('projects', {
22
+ type: 'string',
23
+ alias: 'p',
24
+ coerce: shared_options_1.parseCSV,
25
+ describe: 'Projects to run. (comma/space delimited project names and/or patterns)',
26
+ })
27
+ .option('dryRun', {
28
+ describe: 'Preview the changes without updating files/creating releases',
29
+ alias: 'd',
30
+ type: 'boolean',
31
+ default: false,
32
+ })
33
+ .option('verbose', {
34
+ type: 'boolean',
35
+ describe: 'Prints additional information about the commands (e.g., stack traces)',
36
+ })
37
+ .check((argv) => {
38
+ if (argv.groups && argv.projects) {
39
+ throw new Error('The --projects and --groups options are mutually exclusive, please use one or the other.');
40
+ }
41
+ const nxJson = (0, file_utils_1.readNxJson)();
42
+ if (argv.groups?.length) {
43
+ for (const group of argv.groups) {
44
+ if (!nxJson.release?.groups?.[group]) {
45
+ throw new Error(`The specified release group "${group}" was not found in nx.json`);
46
+ }
47
+ }
48
+ }
49
+ return true;
50
+ }),
51
+ handler: async () => {
52
+ (0, yargs_1.showHelp)();
53
+ process.exit(1);
54
+ },
55
+ };
56
+ const versionCommand = {
57
+ command: 'version [specifier]',
58
+ aliases: ['v'],
59
+ describe: 'Create a version and release for one or more applications and libraries',
60
+ builder: (yargs) => yargs
61
+ .positional('specifier', {
62
+ type: 'string',
63
+ describe: 'Exact version or semver keyword to apply to the selected release group.',
64
+ })
65
+ .option('preid', {
66
+ type: 'string',
67
+ describe: 'The optional prerelease identifier to apply to the version, in the case that specifier has been set to prerelease.',
68
+ default: '',
69
+ }),
70
+ handler: (args) => Promise.resolve().then(() => require('./version')).then((m) => m.versionHandler(args)),
71
+ };
72
+ const changelogCommand = {
73
+ command: 'changelog [version]',
74
+ aliases: ['c'],
75
+ describe: 'Generate a changelog for one or more projects, and optionally push to Github',
76
+ builder: (yargs) => yargs
77
+ // Disable default meaning of yargs version for this command
78
+ .version(false)
79
+ .positional('version', {
80
+ type: 'string',
81
+ description: 'The version to create a Github release and changelog for',
82
+ })
83
+ .option('from', {
84
+ type: 'string',
85
+ description: 'The git reference to use as the start of the changelog. If not set it will attempt to resolve the latest tag and use that',
86
+ })
87
+ .option('to', {
88
+ type: 'string',
89
+ description: 'The git reference to use as the end of the changelog',
90
+ default: 'HEAD',
91
+ })
92
+ .option('interactive', {
93
+ alias: 'i',
94
+ type: 'boolean',
95
+ })
96
+ .option('gitRemote', {
97
+ type: 'string',
98
+ description: 'Alternate git remote in the form {user}/{repo} on which to create the Github release (useful for testing)',
99
+ default: 'origin',
100
+ })
101
+ .option('tagVersionPrefix', {
102
+ type: 'string',
103
+ description: 'Prefix to apply to the version when creating the Github release tag',
104
+ default: 'v',
105
+ })
106
+ .check((argv) => {
107
+ if (!argv.version) {
108
+ throw new Error('A target version must be specified');
109
+ }
110
+ return true;
111
+ }),
112
+ handler: (args) => Promise.resolve().then(() => require('./changelog')).then((m) => m.changelogHandler(args)),
113
+ };
114
+ const publishCommand = {
115
+ command: 'publish',
116
+ aliases: ['p'],
117
+ describe: 'Publish a versioned project to a registry',
118
+ builder: (yargs) => (0, shared_options_1.withRunManyOptions)(yargs)
119
+ .option('registry', {
120
+ type: 'string',
121
+ description: 'The registry to publish to',
122
+ })
123
+ .option('tag', {
124
+ type: 'string',
125
+ description: 'The distribution tag to apply to the published package',
126
+ }),
127
+ handler: (args) => Promise.resolve().then(() => require('./publish')).then((m) => m.publishHandler((0, shared_options_1.withOverrides)(args, 2))),
128
+ };
@@ -0,0 +1,2 @@
1
+ import { NxJsonConfiguration } from '../../../config/nx-json';
2
+ export declare function createNxReleaseConfig(userConfig?: NxJsonConfiguration['release']): Required<NxJsonConfiguration['release']>;
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createNxReleaseConfig = void 0;
4
+ // Apply default configuration to any optional user configuration
5
+ function createNxReleaseConfig(userConfig = {}) {
6
+ const nxReleaseConfig = {
7
+ ...userConfig,
8
+ groups: userConfig.groups || {},
9
+ };
10
+ return nxReleaseConfig;
11
+ }
12
+ exports.createNxReleaseConfig = createNxReleaseConfig;
@@ -0,0 +1,25 @@
1
+ import type { NxJsonConfiguration } from '../../../config/nx-json';
2
+ import { type ProjectGraph } from '../../../devkit-exports';
3
+ export interface ReleaseGroup {
4
+ name: string;
5
+ projects: string[];
6
+ version: {
7
+ generator: string;
8
+ generatorOptions: Record<string, unknown>;
9
+ };
10
+ }
11
+ interface CreateReleaseGroupsError {
12
+ code: 'RELEASE_GROUP_MATCHES_NO_PROJECTS' | 'PROJECT_MATCHES_MULTIPLE_GROUPS' | 'PROJECTS_MISSING_TARGET';
13
+ data: Record<string, string | string[]>;
14
+ }
15
+ export declare const CATCH_ALL_RELEASE_GROUP = "__default__";
16
+ /**
17
+ * Create a set of release groups based on the relevant user specified config ready
18
+ * to be consumed by the release commands.
19
+ */
20
+ export declare function createReleaseGroups(projectGraph: ProjectGraph, userSpecifiedGroups?: NxJsonConfiguration['release']['groups'], requiredTargetName?: 'nx-release-publish'): Promise<{
21
+ error: null | CreateReleaseGroupsError;
22
+ releaseGroups: ReleaseGroup[];
23
+ }>;
24
+ export declare function handleCreateReleaseGroupsError(error: CreateReleaseGroupsError): Promise<void>;
25
+ export {};
@@ -0,0 +1,167 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.handleCreateReleaseGroupsError = exports.createReleaseGroups = exports.CATCH_ALL_RELEASE_GROUP = void 0;
4
+ const devkit_exports_1 = require("../../../devkit-exports");
5
+ const find_matching_projects_1 = require("../../../utils/find-matching-projects");
6
+ const project_graph_utils_1 = require("../../../utils/project-graph-utils");
7
+ const resolve_nx_json_error_message_1 = require("../utils/resolve-nx-json-error-message");
8
+ exports.CATCH_ALL_RELEASE_GROUP = '__default__';
9
+ /**
10
+ * Create a set of release groups based on the relevant user specified config ready
11
+ * to be consumed by the release commands.
12
+ */
13
+ async function createReleaseGroups(projectGraph, userSpecifiedGroups = {}, requiredTargetName) {
14
+ const DEFAULT_VERSION_GENERATOR = '@nx/js:release-version';
15
+ const DEFAULT_VERSION_GENERATOR_OPTIONS = {};
16
+ const allProjects = (0, find_matching_projects_1.findMatchingProjects)(['*'], projectGraph.nodes);
17
+ /**
18
+ * No user specified release groups, so we treat all projects as being in one release group
19
+ * together in which all projects are released in lock step.
20
+ */
21
+ if (Object.keys(userSpecifiedGroups).length === 0) {
22
+ // Ensure all projects have the relevant target available, if applicable
23
+ if (requiredTargetName) {
24
+ const error = ensureProjectsHaveTarget(allProjects, projectGraph, requiredTargetName);
25
+ if (error) {
26
+ return {
27
+ error,
28
+ releaseGroups: [],
29
+ };
30
+ }
31
+ }
32
+ return {
33
+ error: null,
34
+ releaseGroups: [
35
+ {
36
+ name: exports.CATCH_ALL_RELEASE_GROUP,
37
+ projects: allProjects,
38
+ version: {
39
+ generator: DEFAULT_VERSION_GENERATOR,
40
+ generatorOptions: DEFAULT_VERSION_GENERATOR_OPTIONS,
41
+ },
42
+ },
43
+ ],
44
+ };
45
+ }
46
+ /**
47
+ * The user has specified at least one release group.
48
+ *
49
+ * Resolve all the project names into their release groups, and check
50
+ * that individual projects are not found in multiple groups.
51
+ */
52
+ const releaseGroups = [];
53
+ const alreadyMatchedProjects = new Set();
54
+ for (const [releaseGroupName, userSpecifiedGroup] of Object.entries(userSpecifiedGroups)) {
55
+ // Ensure that the user config for the release group can resolve at least one project
56
+ const matchingProjects = (0, find_matching_projects_1.findMatchingProjects)(Array.isArray(userSpecifiedGroup.projects)
57
+ ? userSpecifiedGroup.projects
58
+ : [userSpecifiedGroup.projects], projectGraph.nodes);
59
+ if (!matchingProjects.length) {
60
+ return {
61
+ error: {
62
+ code: 'RELEASE_GROUP_MATCHES_NO_PROJECTS',
63
+ data: {
64
+ releaseGroupName: releaseGroupName,
65
+ },
66
+ },
67
+ releaseGroups: [],
68
+ };
69
+ }
70
+ // Ensure all matching projects have the relevant target available, if applicable
71
+ if (requiredTargetName) {
72
+ const error = ensureProjectsHaveTarget(matchingProjects, projectGraph, requiredTargetName);
73
+ if (error) {
74
+ return {
75
+ error,
76
+ releaseGroups: [],
77
+ };
78
+ }
79
+ }
80
+ for (const project of matchingProjects) {
81
+ if (alreadyMatchedProjects.has(project)) {
82
+ return {
83
+ error: {
84
+ code: 'PROJECT_MATCHES_MULTIPLE_GROUPS',
85
+ data: {
86
+ project,
87
+ },
88
+ },
89
+ releaseGroups: [],
90
+ };
91
+ }
92
+ alreadyMatchedProjects.add(project);
93
+ }
94
+ releaseGroups.push({
95
+ name: releaseGroupName,
96
+ projects: matchingProjects,
97
+ version: userSpecifiedGroup.version
98
+ ? {
99
+ generator: userSpecifiedGroup.version.generator || DEFAULT_VERSION_GENERATOR,
100
+ generatorOptions: userSpecifiedGroup.version.generatorOptions ||
101
+ DEFAULT_VERSION_GENERATOR_OPTIONS,
102
+ }
103
+ : {
104
+ generator: DEFAULT_VERSION_GENERATOR,
105
+ generatorOptions: DEFAULT_VERSION_GENERATOR_OPTIONS,
106
+ },
107
+ });
108
+ }
109
+ return {
110
+ error: null,
111
+ releaseGroups,
112
+ };
113
+ }
114
+ exports.createReleaseGroups = createReleaseGroups;
115
+ async function handleCreateReleaseGroupsError(error) {
116
+ switch (error.code) {
117
+ case 'RELEASE_GROUP_MATCHES_NO_PROJECTS':
118
+ {
119
+ const nxJsonMessage = await (0, resolve_nx_json_error_message_1.resolveNxJsonConfigErrorMessage)([
120
+ 'release',
121
+ 'groups',
122
+ ]);
123
+ devkit_exports_1.output.error({
124
+ title: `Release group "${error.data.releaseGroupName}" matches no projects. Please ensure all release groups match at least one project:`,
125
+ bodyLines: [nxJsonMessage],
126
+ });
127
+ }
128
+ break;
129
+ case 'PROJECT_MATCHES_MULTIPLE_GROUPS':
130
+ {
131
+ const nxJsonMessage = await (0, resolve_nx_json_error_message_1.resolveNxJsonConfigErrorMessage)([
132
+ 'release',
133
+ 'groups',
134
+ ]);
135
+ devkit_exports_1.output.error({
136
+ title: `Project "${error.data.project}" matches multiple release groups. Please ensure all projects are part of only one release group:`,
137
+ bodyLines: [nxJsonMessage],
138
+ });
139
+ }
140
+ break;
141
+ case 'PROJECTS_MISSING_TARGET':
142
+ {
143
+ devkit_exports_1.output.error({
144
+ title: `Based on your config, the following projects were matched for release but do not have a "${error.data.targetName}" target specified. Please ensure you have an appropriate plugin such as @nx/js installed, or have configured the target manually, or exclude the projects using release groups config in nx.json:`,
145
+ bodyLines: Array.from(error.data.projects).map((name) => `- ${name}`),
146
+ });
147
+ }
148
+ break;
149
+ default:
150
+ throw new Error(`Unhandled error code: ${error.code}`);
151
+ }
152
+ process.exit(1);
153
+ }
154
+ exports.handleCreateReleaseGroupsError = handleCreateReleaseGroupsError;
155
+ function ensureProjectsHaveTarget(projects, projectGraph, requiredTargetName) {
156
+ const missingTargetProjects = projects.filter((project) => !(0, project_graph_utils_1.projectHasTarget)(projectGraph.nodes[project], requiredTargetName));
157
+ if (missingTargetProjects.length) {
158
+ return {
159
+ code: 'PROJECTS_MISSING_TARGET',
160
+ data: {
161
+ targetName: requiredTargetName,
162
+ projects: missingTargetProjects,
163
+ },
164
+ };
165
+ }
166
+ return null;
167
+ }
@@ -0,0 +1,4 @@
1
+ import { PublishOptions } from './command-object';
2
+ export declare function publishHandler(args: PublishOptions & {
3
+ __overrides_unparsed__: string[];
4
+ }): Promise<void>;