nx 17.0.3 → 17.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.
- package/LICENSE +1 -1
- package/README.md +9 -4
- package/bin/init-local.js +10 -60
- package/bin/nx-cloud.js +6 -0
- package/bin/nx.js +1 -9
- package/bin/post-install.js +5 -1
- package/bin/run-executor.js +1 -1
- package/migrations.json +18 -0
- package/package.json +21 -18
- package/plugins/package-json.js +1 -1
- package/{changelog-renderer → release/changelog-renderer}/index.d.ts +18 -3
- package/{changelog-renderer → release/changelog-renderer}/index.js +78 -34
- package/release/index.d.ts +4 -0
- package/release/index.js +11 -0
- package/schemas/nx-schema.json +203 -19
- package/schemas/project-schema.json +20 -0
- package/src/adapter/angular-json.js +28 -18
- package/src/adapter/compat.d.ts +2 -2
- package/src/adapter/compat.js +6 -1
- package/src/adapter/ngcli-adapter.d.ts +16 -4
- package/src/adapter/ngcli-adapter.js +85 -28
- package/src/command-line/add/add.d.ts +2 -0
- package/src/command-line/add/add.js +169 -0
- package/src/command-line/add/command-object.d.ts +7 -0
- package/src/command-line/add/command-object.js +24 -0
- package/src/command-line/affected/affected.js +0 -3
- package/src/command-line/affected/command-object.d.ts +4 -4
- package/src/command-line/affected/command-object.js +53 -26
- package/src/command-line/affected/print-affected.js +10 -1
- package/src/command-line/connect/command-object.d.ts +1 -2
- package/src/command-line/connect/command-object.js +3 -7
- package/src/command-line/connect/connect-to-nx-cloud.d.ts +4 -5
- package/src/command-line/connect/connect-to-nx-cloud.js +43 -31
- package/src/command-line/connect/view-logs.js +5 -21
- package/src/command-line/examples.js +18 -0
- package/src/command-line/exec/command-object.js +2 -1
- package/src/command-line/exec/exec.d.ts +1 -1
- package/src/command-line/exec/exec.js +78 -35
- package/src/command-line/format/format.js +13 -4
- package/src/command-line/generate/generate.js +9 -9
- package/src/command-line/generate/generator-utils.d.ts +3 -2
- package/src/command-line/generate/generator-utils.js +5 -5
- package/src/command-line/graph/graph.d.ts +1 -1
- package/src/command-line/graph/graph.js +82 -37
- package/src/command-line/init/command-object.js +70 -43
- package/src/command-line/init/implementation/add-nx-to-monorepo.d.ts +4 -2
- package/src/command-line/init/implementation/add-nx-to-monorepo.js +11 -2
- package/src/command-line/init/implementation/add-nx-to-nest.d.ts +1 -1
- package/src/command-line/init/implementation/add-nx-to-nest.js +9 -6
- package/src/command-line/init/implementation/add-nx-to-npm-repo.d.ts +4 -2
- package/src/command-line/init/implementation/add-nx-to-npm-repo.js +14 -4
- package/src/command-line/init/implementation/angular/index.js +4 -1
- package/src/command-line/init/implementation/angular/legacy-angular-versions.js +10 -5
- package/src/command-line/init/implementation/angular/standalone-workspace.js +1 -1
- package/src/command-line/init/implementation/angular/types.d.ts +1 -1
- package/src/command-line/init/implementation/dot-nx/nxw.js +47 -16
- package/src/command-line/init/implementation/react/index.d.ts +1 -1
- package/src/command-line/init/implementation/react/index.js +4 -2
- package/src/command-line/init/implementation/react/rename-js-to-jsx.js +4 -2
- package/src/command-line/init/implementation/utils.d.ts +5 -5
- package/src/command-line/init/implementation/utils.js +46 -44
- package/src/command-line/init/{init.js → init-v1.js} +5 -13
- package/src/command-line/init/init-v2.d.ts +7 -0
- package/src/command-line/init/init-v2.js +201 -0
- package/src/command-line/list/list.js +6 -5
- package/src/command-line/migrate/command-object.js +19 -4
- package/src/command-line/migrate/migrate.js +21 -17
- package/src/command-line/new/new.js +1 -1
- package/src/command-line/nx-commands.js +4 -1
- package/src/command-line/release/changelog.d.ts +22 -1
- package/src/command-line/release/changelog.js +459 -257
- package/src/command-line/release/command-object.d.ts +29 -7
- package/src/command-line/release/command-object.js +120 -20
- package/src/command-line/release/config/config.d.ts +26 -21
- package/src/command-line/release/config/config.js +416 -59
- package/src/command-line/release/config/conventional-commits.d.ts +2 -0
- package/src/command-line/release/config/conventional-commits.js +98 -0
- package/src/command-line/release/config/filter-release-groups.d.ts +1 -2
- package/src/command-line/release/config/filter-release-groups.js +38 -1
- package/src/command-line/release/index.d.ts +16 -0
- package/src/command-line/release/index.js +23 -0
- package/src/command-line/release/publish.d.ts +7 -3
- package/src/command-line/release/publish.js +89 -37
- package/src/command-line/release/release.d.ts +4 -0
- package/src/command-line/release/release.js +176 -0
- package/src/command-line/release/utils/batch-projects-by-generator-config.d.ts +7 -0
- package/src/command-line/release/utils/batch-projects-by-generator-config.js +37 -0
- package/src/command-line/release/utils/exec-command.d.ts +1 -0
- package/src/command-line/release/utils/exec-command.js +34 -0
- package/src/command-line/release/utils/git.d.ts +34 -1
- package/src/command-line/release/utils/git.js +238 -34
- package/src/command-line/release/utils/github.d.ts +5 -5
- package/src/command-line/release/utils/github.js +155 -8
- package/src/command-line/release/utils/markdown.js +6 -1
- package/src/command-line/release/utils/print-changes.d.ts +1 -1
- package/src/command-line/release/utils/print-changes.js +3 -3
- package/src/command-line/release/utils/resolve-nx-json-error-message.js +4 -1
- package/src/command-line/release/utils/resolve-semver-specifier.d.ts +4 -0
- package/src/command-line/release/utils/resolve-semver-specifier.js +58 -0
- package/src/command-line/release/utils/semver.d.ts +8 -0
- package/src/command-line/release/utils/semver.js +30 -1
- package/src/command-line/release/utils/shared.d.ts +39 -0
- package/src/command-line/release/utils/shared.js +213 -0
- package/src/command-line/release/version.d.ts +37 -3
- package/src/command-line/release/version.js +312 -117
- package/src/command-line/repair/repair.js +13 -9
- package/src/command-line/report/report.d.ts +3 -0
- package/src/command-line/report/report.js +22 -5
- package/src/command-line/run/command-object.d.ts +4 -0
- package/src/command-line/run/command-object.js +18 -2
- package/src/command-line/run/executor-utils.d.ts +2 -1
- package/src/command-line/run/executor-utils.js +4 -4
- package/src/command-line/run/run-one.js +3 -6
- package/src/command-line/run/run.js +34 -9
- package/src/command-line/run-many/command-object.js +4 -1
- package/src/command-line/run-many/run-many.js +0 -3
- package/src/command-line/show/command-object.d.ts +3 -0
- package/src/command-line/show/command-object.js +29 -2
- package/src/command-line/show/show.js +9 -0
- package/src/command-line/yargs-utils/shared-options.d.ts +4 -1
- package/src/command-line/yargs-utils/shared-options.js +23 -9
- package/src/commands-runner/command-graph.d.ts +13 -0
- package/src/commands-runner/command-graph.js +2 -0
- package/src/commands-runner/create-command-graph.d.ts +4 -0
- package/src/commands-runner/create-command-graph.js +44 -0
- package/src/commands-runner/get-command-projects.d.ts +3 -0
- package/src/commands-runner/get-command-projects.js +19 -0
- package/src/config/nx-json.d.ts +160 -25
- package/src/config/project-graph.d.ts +3 -3
- package/src/config/workspace-json-project-json.d.ts +23 -1
- package/src/config/workspaces.d.ts +1 -1
- package/src/config/workspaces.js +4 -6
- package/src/core/graph/3rdpartylicenses.txt +144 -74
- package/src/core/graph/environment.js +1 -1
- package/src/core/graph/index.html +4 -6
- package/src/core/graph/main.js +1 -1
- package/src/core/graph/runtime.js +1 -1
- package/src/core/graph/styles.css +3 -3
- package/src/core/graph/styles.js +1 -1
- package/src/daemon/client/client.d.ts +5 -1
- package/src/daemon/client/client.js +27 -8
- package/src/daemon/client/{socket-messenger.d.ts → daemon-socket-messenger.d.ts} +1 -1
- package/src/daemon/client/{socket-messenger.js → daemon-socket-messenger.js} +3 -3
- package/src/daemon/daemon-project-graph-error.d.ts +8 -0
- package/src/daemon/daemon-project-graph-error.js +13 -0
- package/src/daemon/server/handle-hash-tasks.js +12 -2
- package/src/daemon/server/handle-request-project-graph.js +1 -1
- package/src/daemon/server/project-graph-incremental-recomputation.d.ts +14 -13
- package/src/daemon/server/project-graph-incremental-recomputation.js +98 -33
- package/src/daemon/server/shutdown-utils.js +2 -4
- package/src/daemon/server/watcher.js +0 -3
- package/src/daemon/socket-utils.d.ts +2 -1
- package/src/daemon/socket-utils.js +15 -4
- package/src/daemon/tmp-dir.d.ts +1 -0
- package/src/daemon/tmp-dir.js +4 -4
- package/src/devkit-exports.d.ts +2 -2
- package/src/devkit-exports.js +3 -2
- package/src/devkit-internals.d.ts +3 -0
- package/src/devkit-internals.js +7 -1
- package/src/executors/noop/schema.json +1 -1
- package/src/executors/run-commands/run-commands.impl.d.ts +10 -2
- package/src/executors/run-commands/run-commands.impl.js +152 -48
- package/src/executors/run-commands/schema.json +11 -1
- package/src/executors/run-script/run-script.impl.js +43 -11
- package/src/executors/utils/convert-nx-executor.js +1 -1
- package/src/generators/internal-utils/format-changed-files-with-prettier-if-available.d.ts +3 -1
- package/src/generators/internal-utils/format-changed-files-with-prettier-if-available.js +4 -2
- package/src/generators/testing-utils/create-tree-with-empty-workspace.js +0 -6
- package/src/generators/tree.d.ts +1 -0
- package/src/generators/utils/glob.js +2 -2
- package/src/generators/utils/project-configuration.js +28 -9
- package/src/hasher/create-task-hasher.d.ts +4 -0
- package/src/hasher/create-task-hasher.js +16 -0
- package/src/hasher/hash-task.js +9 -3
- package/src/hasher/native-task-hasher-impl.d.ts +19 -0
- package/src/hasher/native-task-hasher-impl.js +37 -0
- package/src/hasher/node-task-hasher-impl.d.ts +49 -0
- package/src/hasher/node-task-hasher-impl.js +431 -0
- package/src/hasher/task-hasher.d.ts +33 -21
- package/src/hasher/task-hasher.js +30 -428
- package/src/migrations/update-15-0-0/migrate-to-inputs.js +5 -5
- package/src/migrations/update-15-1-0/set-project-names.js +2 -1
- package/src/migrations/update-15-8-2/update-nxw.js +2 -6
- package/src/migrations/update-17-0-0/rm-default-collection-npm-scope.js +3 -3
- package/src/migrations/update-17-0-0/use-minimal-config-for-tasks-runner-options.js +49 -13
- package/src/migrations/update-17-2-0/move-default-base.d.ts +5 -0
- package/src/migrations/update-17-2-0/move-default-base.js +21 -0
- package/src/migrations/update-17-3-0/nx-release-path.d.ts +3 -0
- package/src/migrations/update-17-3-0/nx-release-path.js +48 -0
- package/src/migrations/update-17-3-0/update-nxw.d.ts +2 -0
- package/src/migrations/update-17-3-0/update-nxw.js +7 -0
- package/src/migrations/update-18-0-0/disable-crystal-for-existing-workspaces.d.ts +2 -0
- package/src/migrations/update-18-0-0/disable-crystal-for-existing-workspaces.js +9 -0
- package/src/native/index.d.ts +65 -15
- package/src/native/index.js +6 -2
- package/src/native/transform-objects.js +2 -0
- package/src/nx-cloud/generators/connect-to-nx-cloud/connect-to-nx-cloud.d.ts +1 -0
- package/src/nx-cloud/generators/connect-to-nx-cloud/connect-to-nx-cloud.js +13 -12
- package/src/nx-cloud/generators/connect-to-nx-cloud/schema.json +6 -1
- package/src/nx-cloud/update-manager.js +2 -1
- package/src/plugins/js/index.d.ts +1 -1
- package/src/plugins/js/index.js +3 -3
- package/src/plugins/js/lock-file/lock-file.d.ts +2 -2
- package/src/plugins/js/lock-file/lock-file.js +15 -3
- package/src/plugins/js/package-json/create-package-json.js +1 -1
- package/src/plugins/js/project-graph/build-dependencies/strip-source-code.d.ts +1 -1
- package/src/plugins/js/project-graph/build-dependencies/strip-source-code.js +1 -1
- package/src/plugins/js/project-graph/build-dependencies/typescript-import-locator.d.ts +1 -1
- package/src/plugins/js/project-graph/build-dependencies/typescript-import-locator.js +1 -1
- package/src/plugins/js/utils/register.d.ts +1 -1
- package/src/plugins/js/utils/register.js +28 -8
- package/src/plugins/js/versions.d.ts +1 -1
- package/src/plugins/js/versions.js +1 -1
- package/{plugins/package-json-workspaces.d.ts → src/plugins/package-json-workspaces/create-nodes.d.ts} +4 -4
- package/{plugins/package-json-workspaces.js → src/plugins/package-json-workspaces/create-nodes.js} +34 -12
- package/src/plugins/package-json-workspaces/index.d.ts +1 -0
- package/src/plugins/package-json-workspaces/index.js +4 -0
- package/src/plugins/project-json/build-nodes/package-json-next-to-project-json.d.ts +2 -0
- package/src/plugins/project-json/build-nodes/package-json-next-to-project-json.js +47 -0
- package/src/plugins/project-json/build-nodes/project-json.d.ts +2 -5
- package/src/plugins/project-json/build-nodes/project-json.js +6 -44
- package/src/plugins/target-defaults/target-defaults-plugin.d.ts +66 -0
- package/src/plugins/target-defaults/target-defaults-plugin.js +182 -0
- package/src/project-graph/affected/locators/project-glob-changes.js +3 -3
- package/src/project-graph/affected/locators/workspace-projects.d.ts +0 -2
- package/src/project-graph/affected/locators/workspace-projects.js +16 -29
- package/src/project-graph/build-project-graph.d.ts +20 -1
- package/src/project-graph/build-project-graph.js +91 -33
- package/src/project-graph/file-map-utils.d.ts +9 -5
- package/src/project-graph/file-map-utils.js +16 -63
- package/src/project-graph/file-utils.d.ts +1 -1
- package/src/project-graph/file-utils.js +44 -2
- package/src/project-graph/nx-deps-cache.js +1 -1
- package/src/project-graph/project-graph-builder.d.ts +1 -1
- package/src/project-graph/project-graph-builder.js +1 -1
- package/src/project-graph/project-graph.d.ts +32 -1
- package/src/project-graph/project-graph.js +147 -23
- package/src/project-graph/utils/build-all-workspace-files.d.ts +2 -0
- package/src/project-graph/utils/build-all-workspace-files.js +15 -0
- package/src/project-graph/utils/normalize-project-nodes.d.ts +2 -3
- package/src/project-graph/utils/normalize-project-nodes.js +7 -33
- package/src/project-graph/utils/project-configuration-utils.d.ts +66 -4
- package/src/project-graph/utils/project-configuration-utils.js +509 -62
- package/src/project-graph/utils/retrieve-workspace-files.d.ts +12 -31
- package/src/project-graph/utils/retrieve-workspace-files.js +27 -90
- package/src/tasks-runner/batch/run-batch.js +3 -3
- package/src/tasks-runner/cache.js +6 -3
- package/src/tasks-runner/create-task-graph.js +1 -1
- package/src/tasks-runner/fork.d.ts +1 -0
- package/src/tasks-runner/fork.js +23 -0
- package/src/tasks-runner/forked-process-task-runner.d.ts +13 -5
- package/src/tasks-runner/forked-process-task-runner.js +112 -21
- package/src/tasks-runner/init-tasks-runner.js +1 -1
- package/src/tasks-runner/life-cycles/dynamic-run-many-terminal-output-life-cycle.js +28 -28
- package/src/tasks-runner/life-cycles/dynamic-run-one-terminal-output-life-cycle.js +19 -22
- package/src/tasks-runner/life-cycles/empty-terminal-output-life-cycle.js +1 -3
- package/src/tasks-runner/life-cycles/invoke-runner-terminal-output-life-cycle.js +1 -3
- package/src/tasks-runner/life-cycles/static-run-many-terminal-output-life-cycle.js +2 -4
- package/src/tasks-runner/life-cycles/static-run-one-terminal-output-life-cycle.d.ts +1 -0
- package/src/tasks-runner/life-cycles/static-run-one-terminal-output-life-cycle.js +11 -5
- package/src/tasks-runner/life-cycles/view-logs-utils.js +1 -1
- package/src/tasks-runner/pseudo-ipc.d.ts +49 -0
- package/src/tasks-runner/pseudo-ipc.js +140 -0
- package/src/tasks-runner/pseudo-terminal.d.ts +43 -0
- package/src/tasks-runner/pseudo-terminal.js +159 -0
- package/src/tasks-runner/run-command.d.ts +1 -1
- package/src/tasks-runner/run-command.js +13 -19
- package/src/tasks-runner/task-env.js +1 -2
- package/src/tasks-runner/task-graph-utils.d.ts +7 -3
- package/src/tasks-runner/task-graph-utils.js +15 -15
- package/src/tasks-runner/task-orchestrator.js +68 -12
- package/src/tasks-runner/tasks-schedule.js +3 -3
- package/src/tasks-runner/utils.d.ts +16 -7
- package/src/tasks-runner/utils.js +30 -16
- package/src/utils/ab-testing.d.ts +36 -2
- package/src/utils/ab-testing.js +34 -16
- package/src/utils/assert-workspace-validity.js +1 -1
- package/src/utils/cache-directory.d.ts +1 -0
- package/src/utils/cache-directory.js +5 -1
- package/src/utils/child-process.d.ts +15 -1
- package/src/utils/child-process.js +91 -1
- package/src/utils/command-line-utils.js +2 -1
- package/src/utils/exit-codes.d.ts +6 -0
- package/src/utils/exit-codes.js +20 -0
- package/src/utils/fileutils.d.ts +1 -0
- package/src/utils/find-matching-projects.js +5 -5
- package/src/utils/find-workspace-root.js +1 -0
- package/src/utils/ignore.js +8 -1
- package/src/utils/json-diff.d.ts +1 -0
- package/src/utils/json-diff.js +2 -1
- package/src/utils/json.js +3 -1
- package/src/utils/logger.js +1 -1
- package/src/utils/nx-cloud-utils.d.ts +1 -1
- package/src/utils/nx-cloud-utils.js +9 -4
- package/src/utils/nx-plugin.d.ts +32 -15
- package/src/utils/nx-plugin.deprecated.d.ts +10 -5
- package/src/utils/nx-plugin.deprecated.js +23 -0
- package/src/utils/nx-plugin.js +71 -80
- package/src/utils/output.d.ts +4 -2
- package/src/utils/output.js +44 -9
- package/src/utils/package-json.d.ts +4 -4
- package/src/utils/package-json.js +18 -12
- package/src/utils/package-manager.d.ts +7 -0
- package/src/utils/package-manager.js +24 -4
- package/src/utils/params.d.ts +12 -4
- package/src/utils/params.js +37 -4
- package/src/utils/plugins/core-plugins.js +8 -0
- package/src/utils/plugins/installed-plugins.d.ts +2 -1
- package/src/utils/plugins/installed-plugins.js +2 -2
- package/src/utils/plugins/local-plugins.js +1 -1
- package/src/utils/plugins/plugin-capabilities.d.ts +3 -2
- package/src/utils/plugins/plugin-capabilities.js +7 -7
- package/src/utils/typescript.js +1 -1
- package/src/utils/update-nxw.d.ts +2 -0
- package/src/utils/update-nxw.js +12 -0
- package/src/utils/workspace-configuration-check.js +1 -1
- package/src/utils/workspace-context.d.ts +6 -4
- package/src/utils/workspace-context.js +19 -9
- package/src/core/graph/polyfills.js +0 -1
- /package/src/command-line/init/{init.d.ts → init-v1.d.ts} +0 -0
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.shouldCreateGitHubRelease = exports.releaseChangelog = exports.releaseChangelogCLIHandler = void 0;
|
|
4
4
|
const chalk = require("chalk");
|
|
5
|
+
const enquirer_1 = require("enquirer");
|
|
5
6
|
const node_fs_1 = require("node:fs");
|
|
6
7
|
const semver_1 = require("semver");
|
|
7
8
|
const tmp_1 = require("tmp");
|
|
8
9
|
const nx_json_1 = require("../../config/nx-json");
|
|
9
10
|
const tree_1 = require("../../generators/tree");
|
|
10
11
|
const register_1 = require("../../plugins/js/utils/register");
|
|
12
|
+
const file_map_utils_1 = require("../../project-graph/file-map-utils");
|
|
11
13
|
const project_graph_1 = require("../../project-graph/project-graph");
|
|
12
14
|
const utils_1 = require("../../tasks-runner/utils");
|
|
13
|
-
const
|
|
15
|
+
const is_ci_1 = require("../../utils/is-ci");
|
|
14
16
|
const output_1 = require("../../utils/output");
|
|
17
|
+
const params_1 = require("../../utils/params");
|
|
15
18
|
const path_1 = require("../../utils/path");
|
|
16
19
|
const typescript_1 = require("../../utils/typescript");
|
|
17
20
|
const workspace_root_1 = require("../../utils/workspace-root");
|
|
@@ -22,100 +25,345 @@ const github_1 = require("./utils/github");
|
|
|
22
25
|
const launch_editor_1 = require("./utils/launch-editor");
|
|
23
26
|
const markdown_1 = require("./utils/markdown");
|
|
24
27
|
const print_changes_1 = require("./utils/print-changes");
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
this.isPrerelease = isPrerelease(version);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
async function changelogHandler(args) {
|
|
39
|
-
// Right now, the given version must be valid semver in order to proceed
|
|
40
|
-
if (!(0, semver_1.valid)(args.version)) {
|
|
41
|
-
output_1.output.error({
|
|
42
|
-
title: `The given version "${args.version}" is not a valid semver version. Please provide your version in the format "1.0.0", "1.0.0-beta.1" etc`,
|
|
43
|
-
});
|
|
44
|
-
process.exit(1);
|
|
45
|
-
}
|
|
28
|
+
const resolve_nx_json_error_message_1 = require("./utils/resolve-nx-json-error-message");
|
|
29
|
+
const shared_1 = require("./utils/shared");
|
|
30
|
+
const releaseChangelogCLIHandler = (args) => (0, params_1.handleErrors)(args.verbose, () => releaseChangelog(args));
|
|
31
|
+
exports.releaseChangelogCLIHandler = releaseChangelogCLIHandler;
|
|
32
|
+
/**
|
|
33
|
+
* NOTE: This function is also exported for programmatic usage and forms part of the public API
|
|
34
|
+
* of Nx. We intentionally do not wrap the implementation with handleErrors because users need
|
|
35
|
+
* to have control over their own error handling when using the API.
|
|
36
|
+
*/
|
|
37
|
+
async function releaseChangelog(args) {
|
|
46
38
|
const projectGraph = await (0, project_graph_1.createProjectGraphAsync)({ exitOnError: true });
|
|
47
39
|
const nxJson = (0, nx_json_1.readNxJson)();
|
|
48
40
|
if (args.verbose) {
|
|
49
41
|
process.env.NX_VERBOSE_LOGGING = 'true';
|
|
50
42
|
}
|
|
51
43
|
// Apply default configuration to any optional user configuration
|
|
52
|
-
const { error: configError, nxReleaseConfig } = await (0, config_1.createNxReleaseConfig)(projectGraph, nxJson.release);
|
|
44
|
+
const { error: configError, nxReleaseConfig } = await (0, config_1.createNxReleaseConfig)(projectGraph, await (0, file_map_utils_1.createProjectFileMapUsingProjectGraph)(projectGraph), nxJson.release);
|
|
53
45
|
if (configError) {
|
|
54
46
|
return await (0, config_1.handleNxReleaseConfigError)(configError);
|
|
55
47
|
}
|
|
48
|
+
// The nx release top level command will always override these three git args. This is how we can tell
|
|
49
|
+
// if the top level release command was used or if the user is using the changelog subcommand.
|
|
50
|
+
// If the user explicitly overrides these args, then it doesn't matter if the top level config is set,
|
|
51
|
+
// as all of the git options would be overridden anyway.
|
|
52
|
+
if ((args.gitCommit === undefined ||
|
|
53
|
+
args.gitTag === undefined ||
|
|
54
|
+
args.stageChanges === undefined) &&
|
|
55
|
+
nxJson.release?.git) {
|
|
56
|
+
const nxJsonMessage = await (0, resolve_nx_json_error_message_1.resolveNxJsonConfigErrorMessage)([
|
|
57
|
+
'release',
|
|
58
|
+
'git',
|
|
59
|
+
]);
|
|
60
|
+
output_1.output.error({
|
|
61
|
+
title: `The "release.git" property in nx.json may not be used with the "nx release changelog" subcommand or programmatic API. Instead, configure git options for subcommands directly with "release.version.git" and "release.changelog.git".`,
|
|
62
|
+
bodyLines: [nxJsonMessage],
|
|
63
|
+
});
|
|
64
|
+
process.exit(1);
|
|
65
|
+
}
|
|
56
66
|
const { error: filterError, releaseGroups, releaseGroupToFilteredProjects, } = (0, filter_release_groups_1.filterReleaseGroups)(projectGraph, nxReleaseConfig, args.projects, args.groups);
|
|
57
67
|
if (filterError) {
|
|
58
68
|
output_1.output.error(filterError);
|
|
59
69
|
process.exit(1);
|
|
60
70
|
}
|
|
61
|
-
const
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
71
|
+
const changelogGenerationEnabled = !!nxReleaseConfig.changelog.workspaceChangelog ||
|
|
72
|
+
Object.values(nxReleaseConfig.groups).some((g) => g.changelog);
|
|
73
|
+
if (!changelogGenerationEnabled) {
|
|
74
|
+
output_1.output.warn({
|
|
75
|
+
title: `Changelogs are disabled. No changelog entries will be generated`,
|
|
76
|
+
bodyLines: [
|
|
77
|
+
`To explicitly enable changelog generation, configure "release.changelog.workspaceChangelog" or "release.changelog.projectChangelogs" in nx.json.`,
|
|
78
|
+
],
|
|
69
79
|
});
|
|
70
|
-
|
|
80
|
+
return {};
|
|
81
|
+
}
|
|
82
|
+
const useAutomaticFromRef = nxReleaseConfig.changelog?.automaticFromRef || args.firstRelease;
|
|
83
|
+
/**
|
|
84
|
+
* For determining the versions to use within changelog files, there are a few different possibilities:
|
|
85
|
+
* - the user is using the nx CLI, and therefore passes a single --version argument which represents the version for any and all changelog
|
|
86
|
+
* files which will be generated (i.e. both the workspace changelog, and all project changelogs, depending on which of those has been enabled)
|
|
87
|
+
* - the user is using the nxReleaseChangelog API programmatically, and:
|
|
88
|
+
* - passes only a version property
|
|
89
|
+
* - this works in the same way as described above for the CLI
|
|
90
|
+
* - passes only a versionData object
|
|
91
|
+
* - this is a special case where the user is providing a version for each project, and therefore the version argument is not needed
|
|
92
|
+
* - NOTE: it is not possible to generate a workspace level changelog with only a versionData object, and this will produce an error
|
|
93
|
+
* - passes both a version and a versionData object
|
|
94
|
+
* - in this case, the version property will be used as the reference for the workspace changelog, and the versionData object will be used
|
|
95
|
+
* to generate project changelogs
|
|
96
|
+
*/
|
|
97
|
+
const { workspaceChangelogVersion, projectsVersionData } = resolveChangelogVersions(args, releaseGroups, releaseGroupToFilteredProjects);
|
|
98
|
+
const to = args.to || 'HEAD';
|
|
99
|
+
const toSHA = await (0, git_1.getCommitHash)(to);
|
|
100
|
+
const headSHA = to === 'HEAD' ? toSHA : await (0, git_1.getCommitHash)('HEAD');
|
|
101
|
+
/**
|
|
102
|
+
* Protect the user against attempting to create a new commit when recreating an old release changelog,
|
|
103
|
+
* this seems like it would always be unintentional.
|
|
104
|
+
*/
|
|
105
|
+
const autoCommitEnabled = args.gitCommit ?? nxReleaseConfig.changelog.git.commit;
|
|
106
|
+
if (autoCommitEnabled && headSHA !== toSHA) {
|
|
107
|
+
throw new Error(`You are attempting to recreate the changelog for an old release, but you have enabled auto-commit mode. Please disable auto-commit mode by updating your nx.json, or passing --git-commit=false`);
|
|
71
108
|
}
|
|
72
|
-
const rawCommits = await (0, git_1.getGitDiff)(from, args.to);
|
|
73
|
-
// Parse as conventional commits
|
|
74
|
-
const commits = (0, git_1.parseCommits)(rawCommits).filter((c) => {
|
|
75
|
-
const type = c.type;
|
|
76
|
-
// Always ignore non user-facing commits for now
|
|
77
|
-
// TODO: allow this filter to be configurable via config in a future release
|
|
78
|
-
if (type === 'feat' || type === 'fix' || type === 'perf') {
|
|
79
|
-
return true;
|
|
80
|
-
}
|
|
81
|
-
return false;
|
|
82
|
-
});
|
|
83
109
|
const tree = new tree_1.FsTree(workspace_root_1.workspaceRoot, args.verbose);
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
110
|
+
const commitMessage = args.gitCommitMessage || nxReleaseConfig.changelog.git.commitMessage;
|
|
111
|
+
const commitMessageValues = (0, shared_1.createCommitMessageValues)(releaseGroups, releaseGroupToFilteredProjects, projectsVersionData, commitMessage);
|
|
112
|
+
// Resolve any git tags as early as possible so that we can hard error in case of any duplicates before reaching the actual git command
|
|
113
|
+
const gitTagValues = args.gitTag ?? nxReleaseConfig.changelog.git.tag
|
|
114
|
+
? (0, shared_1.createGitTagValues)(releaseGroups, releaseGroupToFilteredProjects, projectsVersionData)
|
|
115
|
+
: [];
|
|
116
|
+
(0, shared_1.handleDuplicateGitTags)(gitTagValues);
|
|
117
|
+
const postGitTasks = [];
|
|
118
|
+
let workspaceChangelogFromRef = args.from ||
|
|
119
|
+
(await (0, git_1.getLatestGitTagForPattern)(nxReleaseConfig.releaseTagPattern))?.tag;
|
|
120
|
+
if (!workspaceChangelogFromRef) {
|
|
121
|
+
if (useAutomaticFromRef) {
|
|
122
|
+
workspaceChangelogFromRef = await (0, git_1.getFirstGitCommit)();
|
|
123
|
+
if (args.verbose) {
|
|
124
|
+
console.log(`Determined workspace --from ref from the first commit in workspace: ${workspaceChangelogFromRef}`);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
throw new Error(`Unable to determine the previous git tag. If this is the first release of your workspace, use the --first-release option or set the "release.changelog.automaticFromRef" config property in nx.json to generate a changelog from the first commit. Otherwise, be sure to configure the "release.releaseTagPattern" property in nx.json to match the structure of your repository's git tags.`);
|
|
96
129
|
}
|
|
97
|
-
return process.exit(0);
|
|
98
130
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
131
|
+
// Make sure that the fromRef is actually resolvable
|
|
132
|
+
const workspaceChangelogFromSHA = await (0, git_1.getCommitHash)(workspaceChangelogFromRef);
|
|
133
|
+
const workspaceChangelogCommits = await getCommits(workspaceChangelogFromSHA, toSHA, nxReleaseConfig.conventionalCommits);
|
|
134
|
+
const workspaceChangelog = await generateChangelogForWorkspace(tree, args, projectGraph, nxReleaseConfig, workspaceChangelogVersion, workspaceChangelogCommits);
|
|
135
|
+
if (workspaceChangelog &&
|
|
136
|
+
shouldCreateGitHubRelease(nxReleaseConfig.changelog.workspaceChangelog, args.createRelease)) {
|
|
137
|
+
let hasPushed = false;
|
|
138
|
+
postGitTasks.push(async (latestCommit) => {
|
|
139
|
+
if (!hasPushed) {
|
|
140
|
+
output_1.output.logSingleLine(`Pushing to git remote`);
|
|
141
|
+
// Before we can create/update the release we need to ensure the commit exists on the remote
|
|
142
|
+
await (0, git_1.gitPush)({
|
|
143
|
+
gitRemote: args.gitRemote,
|
|
144
|
+
dryRun: args.dryRun,
|
|
145
|
+
verbose: args.verbose,
|
|
146
|
+
});
|
|
147
|
+
hasPushed = true;
|
|
148
|
+
}
|
|
149
|
+
output_1.output.logSingleLine(`Creating GitHub Release`);
|
|
150
|
+
await (0, github_1.createOrUpdateGithubRelease)(workspaceChangelog.releaseVersion, workspaceChangelog.contents, latestCommit, { dryRun: args.dryRun });
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
const allProjectChangelogs = {};
|
|
102
154
|
for (const releaseGroup of releaseGroups) {
|
|
103
|
-
const
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
155
|
+
const config = releaseGroup.changelog;
|
|
156
|
+
// The entire feature is disabled at the release group level, exit early
|
|
157
|
+
if (config === false) {
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
const projects = args.projects?.length
|
|
161
|
+
? // If the user has passed a list of projects, we need to use the filtered list of projects within the release group
|
|
162
|
+
Array.from(releaseGroupToFilteredProjects.get(releaseGroup))
|
|
163
|
+
: // Otherwise, we use the full list of projects within the release group
|
|
164
|
+
releaseGroup.projects;
|
|
165
|
+
const projectNodes = projects.map((name) => projectGraph.nodes[name]);
|
|
166
|
+
if (releaseGroup.projectsRelationship === 'independent') {
|
|
167
|
+
for (const project of projectNodes) {
|
|
168
|
+
let fromRef = args.from ||
|
|
169
|
+
(await (0, git_1.getLatestGitTagForPattern)(releaseGroup.releaseTagPattern, {
|
|
170
|
+
projectName: project.name,
|
|
171
|
+
}))?.tag;
|
|
172
|
+
let commits = null;
|
|
173
|
+
if (!fromRef && useAutomaticFromRef) {
|
|
174
|
+
const firstCommit = await (0, git_1.getFirstGitCommit)();
|
|
175
|
+
const allCommits = await getCommits(firstCommit, toSHA, nxReleaseConfig.conventionalCommits);
|
|
176
|
+
const commitsForProject = allCommits.filter((c) => c.affectedFiles.find((f) => f.startsWith(project.data.root)));
|
|
177
|
+
fromRef = commitsForProject[0]?.shortHash;
|
|
178
|
+
if (args.verbose) {
|
|
179
|
+
console.log(`Determined --from ref for ${project.name} from the first commit in which it exists: ${fromRef}`);
|
|
180
|
+
}
|
|
181
|
+
commits = commitsForProject;
|
|
182
|
+
}
|
|
183
|
+
if (!fromRef && !commits) {
|
|
184
|
+
throw new Error(`Unable to determine the previous git tag. If this is the first release of your workspace, use the --first-release option or set the "release.changelog.automaticFromRef" config property in nx.json to generate a changelog from the first commit. Otherwise, be sure to configure the "release.releaseTagPattern" property in nx.json to match the structure of your repository's git tags.`);
|
|
185
|
+
}
|
|
186
|
+
if (!commits) {
|
|
187
|
+
commits = await getCommits(fromRef, toSHA, nxReleaseConfig.conventionalCommits);
|
|
188
|
+
}
|
|
189
|
+
const projectChangelogs = await generateChangelogForProjects(tree, args, projectGraph, commits, projectsVersionData, releaseGroup, [project], nxReleaseConfig);
|
|
190
|
+
let hasPushed = false;
|
|
191
|
+
for (const [projectName, projectChangelog] of Object.entries(projectChangelogs)) {
|
|
192
|
+
if (projectChangelogs &&
|
|
193
|
+
shouldCreateGitHubRelease(releaseGroup.changelog, args.createRelease)) {
|
|
194
|
+
postGitTasks.push(async (latestCommit) => {
|
|
195
|
+
if (!hasPushed) {
|
|
196
|
+
output_1.output.logSingleLine(`Pushing to git remote`);
|
|
197
|
+
// Before we can create/update the release we need to ensure the commit exists on the remote
|
|
198
|
+
await (0, git_1.gitPush)({
|
|
199
|
+
gitRemote: args.gitRemote,
|
|
200
|
+
dryRun: args.dryRun,
|
|
201
|
+
verbose: args.verbose,
|
|
202
|
+
});
|
|
203
|
+
hasPushed = true;
|
|
204
|
+
}
|
|
205
|
+
output_1.output.logSingleLine(`Creating GitHub Release`);
|
|
206
|
+
await (0, github_1.createOrUpdateGithubRelease)(projectChangelog.releaseVersion, projectChangelog.contents, latestCommit, { dryRun: args.dryRun });
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
allProjectChangelogs[projectName] = projectChangelog;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
else {
|
|
214
|
+
const fromRef = args.from ||
|
|
215
|
+
(await (0, git_1.getLatestGitTagForPattern)(releaseGroup.releaseTagPattern))?.tag;
|
|
216
|
+
if (!fromRef) {
|
|
217
|
+
throw new Error(`Unable to determine the previous git tag, please provide an explicit git reference using --from`);
|
|
218
|
+
}
|
|
219
|
+
// Make sure that the fromRef is actually resolvable
|
|
220
|
+
const fromSHA = await (0, git_1.getCommitHash)(fromRef);
|
|
221
|
+
const commits = await getCommits(fromSHA, toSHA, nxReleaseConfig.conventionalCommits);
|
|
222
|
+
const projectChangelogs = await generateChangelogForProjects(tree, args, projectGraph, commits, projectsVersionData, releaseGroup, projectNodes, nxReleaseConfig);
|
|
223
|
+
let hasPushed = false;
|
|
224
|
+
for (const [projectName, projectChangelog] of Object.entries(projectChangelogs)) {
|
|
225
|
+
if (projectChangelogs &&
|
|
226
|
+
shouldCreateGitHubRelease(releaseGroup.changelog, args.createRelease)) {
|
|
227
|
+
postGitTasks.push(async (latestCommit) => {
|
|
228
|
+
if (!hasPushed) {
|
|
229
|
+
output_1.output.logSingleLine(`Pushing to git remote`);
|
|
230
|
+
// Before we can create/update the release we need to ensure the commit exists on the remote
|
|
231
|
+
await (0, git_1.gitPush)({
|
|
232
|
+
gitRemote: args.gitRemote,
|
|
233
|
+
dryRun: args.dryRun,
|
|
234
|
+
verbose: args.verbose,
|
|
235
|
+
});
|
|
236
|
+
hasPushed = true;
|
|
237
|
+
}
|
|
238
|
+
output_1.output.logSingleLine(`Creating GitHub Release`);
|
|
239
|
+
await (0, github_1.createOrUpdateGithubRelease)(projectChangelog.releaseVersion, projectChangelog.contents, latestCommit, { dryRun: args.dryRun });
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
allProjectChangelogs[projectName] = projectChangelog;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
107
245
|
}
|
|
108
|
-
|
|
109
|
-
|
|
246
|
+
await applyChangesAndExit(args, nxReleaseConfig, tree, toSHA, postGitTasks, commitMessageValues, gitTagValues);
|
|
247
|
+
return {
|
|
248
|
+
workspaceChangelog,
|
|
249
|
+
projectChangelogs: allProjectChangelogs,
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
exports.releaseChangelog = releaseChangelog;
|
|
253
|
+
function resolveChangelogVersions(args, releaseGroups, releaseGroupToFilteredProjects) {
|
|
254
|
+
if (!args.version && !args.versionData) {
|
|
255
|
+
throw new Error(`You must provide a version string and/or a versionData object.`);
|
|
110
256
|
}
|
|
111
|
-
|
|
257
|
+
/**
|
|
258
|
+
* TODO: revaluate this assumption holistically in a dedicated PR when we add support for calver
|
|
259
|
+
* (e.g. the Release class also uses semver utils to check if prerelease).
|
|
260
|
+
*
|
|
261
|
+
* Right now, the given version must be valid semver in order to proceed
|
|
262
|
+
*/
|
|
263
|
+
if (args.version && !(0, semver_1.valid)(args.version)) {
|
|
264
|
+
throw new Error(`The given version "${args.version}" is not a valid semver version. Please provide your version in the format "1.0.0", "1.0.0-beta.1" etc`);
|
|
265
|
+
}
|
|
266
|
+
const versionData = releaseGroups.reduce((versionData, releaseGroup) => {
|
|
267
|
+
const releaseGroupProjectNames = Array.from(releaseGroupToFilteredProjects.get(releaseGroup));
|
|
268
|
+
for (const projectName of releaseGroupProjectNames) {
|
|
269
|
+
if (!args.versionData) {
|
|
270
|
+
versionData[projectName] = {
|
|
271
|
+
newVersion: args.version,
|
|
272
|
+
currentVersion: '', // not relevant within changelog/commit generation
|
|
273
|
+
dependentProjects: [], // not relevant within changelog/commit generation
|
|
274
|
+
};
|
|
275
|
+
continue;
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* In the case where a versionData object was provided, we need to make sure all projects are present,
|
|
279
|
+
* otherwise it suggests a filtering mismatch between the version and changelog command invocations.
|
|
280
|
+
*/
|
|
281
|
+
if (!args.versionData[projectName]) {
|
|
282
|
+
throw new Error(`The provided versionData object does not contain a version for project "${projectName}". This suggests a filtering mismatch between the version and changelog command invocations.`);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
return versionData;
|
|
286
|
+
}, args.versionData || {});
|
|
287
|
+
return {
|
|
288
|
+
workspaceChangelogVersion: args.version,
|
|
289
|
+
projectsVersionData: versionData,
|
|
290
|
+
};
|
|
112
291
|
}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
292
|
+
async function applyChangesAndExit(args, nxReleaseConfig, tree, toSHA, postGitTasks, commitMessageValues, gitTagValues) {
|
|
293
|
+
let latestCommit = toSHA;
|
|
294
|
+
const changes = tree.listChanges();
|
|
295
|
+
/**
|
|
296
|
+
* In the case where we are expecting changelog file updates, but there is nothing
|
|
297
|
+
* to flush from the tree, we exit early. This could happen we using conventional
|
|
298
|
+
* commits, for example.
|
|
299
|
+
*/
|
|
300
|
+
const changelogFilesEnabled = checkChangelogFilesEnabled(nxReleaseConfig);
|
|
301
|
+
if (changelogFilesEnabled && !changes.length) {
|
|
302
|
+
output_1.output.warn({
|
|
303
|
+
title: `No changes detected for changelogs`,
|
|
304
|
+
bodyLines: [
|
|
305
|
+
`No changes were detected for any changelog files, so no changelog entries will be generated.`,
|
|
306
|
+
],
|
|
307
|
+
});
|
|
308
|
+
if (!postGitTasks.length) {
|
|
309
|
+
// no GitHub releases to create so we can just exit
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
if ((0, is_ci_1.isCI)()) {
|
|
313
|
+
output_1.output.warn({
|
|
314
|
+
title: `Skipped GitHub release creation because no changes were detected for any changelog files.`,
|
|
315
|
+
});
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
// prompt the user to see if they want to create a GitHub release anyway
|
|
319
|
+
// we know that the user has configured GitHub releases because we have postGitTasks
|
|
320
|
+
const shouldCreateGitHubReleaseAnyway = await promptForGitHubRelease();
|
|
321
|
+
if (!shouldCreateGitHubReleaseAnyway) {
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
324
|
+
for (const postGitTask of postGitTasks) {
|
|
325
|
+
await postGitTask(latestCommit);
|
|
326
|
+
}
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
329
|
+
// Generate a new commit for the changes, if configured to do so
|
|
330
|
+
if (args.gitCommit ?? nxReleaseConfig.changelog.git.commit) {
|
|
331
|
+
await (0, shared_1.commitChanges)(changes.map((f) => f.path), !!args.dryRun, !!args.verbose, commitMessageValues, args.gitCommitArgs || nxReleaseConfig.changelog.git.commitArgs);
|
|
332
|
+
// Resolve the commit we just made
|
|
333
|
+
latestCommit = await (0, git_1.getCommitHash)('HEAD');
|
|
334
|
+
}
|
|
335
|
+
else if ((args.stageChanges ?? nxReleaseConfig.changelog.git.stageChanges) &&
|
|
336
|
+
changes.length) {
|
|
337
|
+
output_1.output.logSingleLine(`Staging changed files with git`);
|
|
338
|
+
await (0, git_1.gitAdd)({
|
|
339
|
+
changedFiles: changes.map((f) => f.path),
|
|
340
|
+
dryRun: args.dryRun,
|
|
341
|
+
verbose: args.verbose,
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
// Generate a one or more git tags for the changes, if configured to do so
|
|
345
|
+
if (args.gitTag ?? nxReleaseConfig.changelog.git.tag) {
|
|
346
|
+
output_1.output.logSingleLine(`Tagging commit with git`);
|
|
347
|
+
for (const tag of gitTagValues) {
|
|
348
|
+
await (0, git_1.gitTag)({
|
|
349
|
+
tag,
|
|
350
|
+
message: args.gitTagMessage || nxReleaseConfig.changelog.git.tagMessage,
|
|
351
|
+
additionalArgs: args.gitTagArgs || nxReleaseConfig.changelog.git.tagArgs,
|
|
352
|
+
dryRun: args.dryRun,
|
|
353
|
+
verbose: args.verbose,
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
// Run any post-git tasks in series
|
|
358
|
+
for (const postGitTask of postGitTasks) {
|
|
359
|
+
await postGitTask(latestCommit);
|
|
360
|
+
}
|
|
361
|
+
return;
|
|
117
362
|
}
|
|
118
363
|
function resolveChangelogRenderer(changelogRendererPath) {
|
|
364
|
+
const interpolatedChangelogRendererPath = (0, utils_1.interpolate)(changelogRendererPath, {
|
|
365
|
+
workspaceRoot: workspace_root_1.workspaceRoot,
|
|
366
|
+
});
|
|
119
367
|
// Try and load the provided (or default) changelog renderer
|
|
120
368
|
let changelogRenderer;
|
|
121
369
|
let cleanupTranspiler = () => { };
|
|
@@ -124,7 +372,7 @@ function resolveChangelogRenderer(changelogRendererPath) {
|
|
|
124
372
|
if (rootTsconfigPath) {
|
|
125
373
|
cleanupTranspiler = (0, register_1.registerTsProject)(rootTsconfigPath);
|
|
126
374
|
}
|
|
127
|
-
const r = require(
|
|
375
|
+
const r = require(interpolatedChangelogRendererPath);
|
|
128
376
|
changelogRenderer = r.default || r;
|
|
129
377
|
}
|
|
130
378
|
catch {
|
|
@@ -134,45 +382,74 @@ function resolveChangelogRenderer(changelogRendererPath) {
|
|
|
134
382
|
}
|
|
135
383
|
return changelogRenderer;
|
|
136
384
|
}
|
|
137
|
-
async function generateChangelogForWorkspace(tree,
|
|
385
|
+
async function generateChangelogForWorkspace(tree, args, projectGraph, nxReleaseConfig, workspaceChangelogVersion, commits) {
|
|
386
|
+
const config = nxReleaseConfig.changelog.workspaceChangelog;
|
|
138
387
|
// The entire feature is disabled at the workspace level, exit early
|
|
139
388
|
if (config === false) {
|
|
140
389
|
return;
|
|
141
390
|
}
|
|
391
|
+
// If explicitly null it must mean that no changes were detected (e.g. when using conventional commits), so do nothing
|
|
392
|
+
if (workspaceChangelogVersion === null) {
|
|
393
|
+
return;
|
|
394
|
+
}
|
|
395
|
+
// The user explicitly passed workspaceChangelog=true but does not have a workspace changelog config in nx.json
|
|
396
|
+
if (!config) {
|
|
397
|
+
throw new Error(`Workspace changelog is enabled but no configuration was provided. Please provide a workspaceChangelog object in your nx.json`);
|
|
398
|
+
}
|
|
399
|
+
if (Object.entries(nxReleaseConfig.groups).length > 1) {
|
|
400
|
+
output_1.output.warn({
|
|
401
|
+
title: `Workspace changelog is enabled, but you have multiple release groups configured. This is not supported, so workspace changelog will be disabled.`,
|
|
402
|
+
bodyLines: [
|
|
403
|
+
`A single workspace version cannot be determined when defining multiple release groups because versions differ between each group.`,
|
|
404
|
+
`Project level changelogs can be enabled with the "release.changelog.projectChangelogs" property.`,
|
|
405
|
+
],
|
|
406
|
+
});
|
|
407
|
+
return;
|
|
408
|
+
}
|
|
409
|
+
if (Object.values(nxReleaseConfig.groups)[0].projectsRelationship ===
|
|
410
|
+
'independent') {
|
|
411
|
+
output_1.output.warn({
|
|
412
|
+
title: `Workspace changelog is enabled, but you have configured an independent projects relationship. This is not supported, so workspace changelog will be disabled.`,
|
|
413
|
+
bodyLines: [
|
|
414
|
+
`A single workspace version cannot be determined when using independent projects because versions differ between each project.`,
|
|
415
|
+
`Project level changelogs can be enabled with the "release.changelog.projectChangelogs" property.`,
|
|
416
|
+
],
|
|
417
|
+
});
|
|
418
|
+
return;
|
|
419
|
+
}
|
|
420
|
+
// Only trigger interactive mode for the workspace changelog if the user explicitly requested it via "all" or "workspace"
|
|
421
|
+
const interactive = args.interactive === 'all' || args.interactive === 'workspace';
|
|
422
|
+
const dryRun = !!args.dryRun;
|
|
423
|
+
const gitRemote = args.gitRemote;
|
|
142
424
|
const changelogRenderer = resolveChangelogRenderer(config.renderer);
|
|
143
425
|
let interpolatedTreePath = config.file || '';
|
|
144
426
|
if (interpolatedTreePath) {
|
|
145
427
|
interpolatedTreePath = (0, utils_1.interpolate)(interpolatedTreePath, {
|
|
146
|
-
projectName: '',
|
|
147
|
-
projectRoot: '',
|
|
428
|
+
projectName: '', // n/a for the workspace changelog
|
|
429
|
+
projectRoot: '', // n/a for the workspace changelog
|
|
148
430
|
workspaceRoot: '', // within the tree, workspaceRoot is the root
|
|
149
431
|
});
|
|
150
432
|
}
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
case interpolatedTreePath && config.createRelease === 'github':
|
|
155
|
-
logTitle += ` Github release and an entry in ${interpolatedTreePath} for ${chalk.white(releaseVersion.gitTag)}`;
|
|
156
|
-
break;
|
|
157
|
-
case !!interpolatedTreePath:
|
|
158
|
-
logTitle += `n entry in ${interpolatedTreePath} for ${chalk.white(releaseVersion.gitTag)}`;
|
|
159
|
-
break;
|
|
160
|
-
case config.createRelease === 'github':
|
|
161
|
-
logTitle += ` Github release for ${chalk.white(releaseVersion.gitTag)}`;
|
|
162
|
-
}
|
|
163
|
-
output_1.output.log({
|
|
164
|
-
title: logTitle,
|
|
433
|
+
const releaseVersion = new shared_1.ReleaseVersion({
|
|
434
|
+
version: workspaceChangelogVersion,
|
|
435
|
+
releaseTagPattern: nxReleaseConfig.releaseTagPattern,
|
|
165
436
|
});
|
|
166
|
-
|
|
167
|
-
?
|
|
168
|
-
|
|
437
|
+
if (interpolatedTreePath) {
|
|
438
|
+
const prefix = dryRun ? 'Previewing' : 'Generating';
|
|
439
|
+
output_1.output.log({
|
|
440
|
+
title: `${prefix} an entry in ${interpolatedTreePath} for ${chalk.white(releaseVersion.gitTag)}`,
|
|
441
|
+
});
|
|
442
|
+
}
|
|
443
|
+
const githubRepoSlug = (0, github_1.getGitHubRepoSlug)(gitRemote);
|
|
169
444
|
let contents = await changelogRenderer({
|
|
445
|
+
projectGraph,
|
|
170
446
|
commits,
|
|
171
447
|
releaseVersion: releaseVersion.rawVersion,
|
|
172
448
|
project: null,
|
|
173
449
|
repoSlug: githubRepoSlug,
|
|
174
450
|
entryWhenNoChanges: config.entryWhenNoChanges,
|
|
175
451
|
changelogRenderOptions: config.renderOptions,
|
|
452
|
+
conventionalCommitsConfig: nxReleaseConfig.conventionalCommits,
|
|
176
453
|
});
|
|
177
454
|
/**
|
|
178
455
|
* If interactive mode, make the changelog contents available for the user to modify in their editor of choice,
|
|
@@ -187,14 +464,10 @@ async function generateChangelogForWorkspace(tree, releaseVersion, dryRun, inter
|
|
|
187
464
|
await (0, launch_editor_1.launchEditor)(changelogPath);
|
|
188
465
|
contents = (0, node_fs_1.readFileSync)(changelogPath, 'utf-8');
|
|
189
466
|
}
|
|
190
|
-
/**
|
|
191
|
-
* The exact logic we use for printing the summary/diff to the user is dependent upon whether they are creating
|
|
192
|
-
* a changelog file, a Github release, or both.
|
|
193
|
-
*/
|
|
194
|
-
let printSummary = () => { };
|
|
195
|
-
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?`);
|
|
196
467
|
if (interpolatedTreePath) {
|
|
197
|
-
let rootChangelogContents = tree.
|
|
468
|
+
let rootChangelogContents = tree.exists(interpolatedTreePath)
|
|
469
|
+
? tree.read(interpolatedTreePath).toString()
|
|
470
|
+
: '';
|
|
198
471
|
if (rootChangelogContents) {
|
|
199
472
|
// NOTE: right now existing releases are always expected to be in markdown format, but in the future we could potentially support others via a custom parser option
|
|
200
473
|
const changelogReleases = (0, markdown_1.parseChangelogMarkdown)(rootChangelogContents).releases;
|
|
@@ -212,80 +485,25 @@ async function generateChangelogForWorkspace(tree, releaseVersion, dryRun, inter
|
|
|
212
485
|
rootChangelogContents = contents;
|
|
213
486
|
}
|
|
214
487
|
tree.write(interpolatedTreePath, rootChangelogContents);
|
|
215
|
-
|
|
216
|
-
}
|
|
217
|
-
if (config.createRelease === 'github') {
|
|
218
|
-
if (!githubRepoSlug) {
|
|
219
|
-
output_1.output.error({
|
|
220
|
-
title: `Unable to create a Github release because the Github repo slug could not be determined.`,
|
|
221
|
-
bodyLines: [
|
|
222
|
-
`Please ensure you have a valid Github remote configured. You can run \`git remote -v\` to list your current remotes.`,
|
|
223
|
-
],
|
|
224
|
-
});
|
|
225
|
-
process.exit(1);
|
|
226
|
-
}
|
|
227
|
-
const token = await (0, github_1.resolveGithubToken)();
|
|
228
|
-
const githubRequestConfig = {
|
|
229
|
-
repo: githubRepoSlug,
|
|
230
|
-
token,
|
|
231
|
-
};
|
|
232
|
-
let existingGithubReleaseForVersion;
|
|
233
|
-
try {
|
|
234
|
-
existingGithubReleaseForVersion = await (0, github_1.getGithubReleaseByTag)(githubRequestConfig, releaseVersion.gitTag);
|
|
235
|
-
}
|
|
236
|
-
catch (err) {
|
|
237
|
-
if (err.response?.status === 401) {
|
|
238
|
-
output_1.output.error({
|
|
239
|
-
title: `Unable to resolve data via the Github API. You can use any of the following options to resolve this:`,
|
|
240
|
-
bodyLines: [
|
|
241
|
-
'- Set the `GITHUB_TOKEN` or `GH_TOKEN` environment variable to a valid Github token with `repo` scope',
|
|
242
|
-
'- Have an active session via the official gh CLI tool (https://cli.github.com) in your current terminal',
|
|
243
|
-
],
|
|
244
|
-
});
|
|
245
|
-
process.exit(1);
|
|
246
|
-
}
|
|
247
|
-
if (err.response?.status === 404) {
|
|
248
|
-
// No existing release found, this is fine
|
|
249
|
-
}
|
|
250
|
-
else {
|
|
251
|
-
// Rethrow unknown errors for now
|
|
252
|
-
throw err;
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
let existingPrintSummaryFn = printSummary;
|
|
256
|
-
printSummary = () => {
|
|
257
|
-
const logTitle = `https://github.com/${githubRepoSlug}/releases/tag/${releaseVersion.gitTag}`;
|
|
258
|
-
if (existingGithubReleaseForVersion) {
|
|
259
|
-
console.error(`${chalk.white('UPDATE')} ${logTitle}${dryRun ? chalk.keyword('orange')(' [dry-run]') : ''}`);
|
|
260
|
-
}
|
|
261
|
-
else {
|
|
262
|
-
console.error(`${chalk.green('CREATE')} ${logTitle}${dryRun ? chalk.keyword('orange')(' [dry-run]') : ''}`);
|
|
263
|
-
}
|
|
264
|
-
// Only print the diff here if we are not already going to be printing changes from the Tree
|
|
265
|
-
if (!interpolatedTreePath) {
|
|
266
|
-
console.log('');
|
|
267
|
-
(0, print_changes_1.printDiff)(existingGithubReleaseForVersion
|
|
268
|
-
? existingGithubReleaseForVersion.body
|
|
269
|
-
: '', contents, 3, noDiffInChangelogMessage);
|
|
270
|
-
}
|
|
271
|
-
existingPrintSummaryFn();
|
|
272
|
-
};
|
|
273
|
-
if (!dryRun) {
|
|
274
|
-
await (0, github_1.createOrUpdateGithubRelease)(githubRequestConfig, {
|
|
275
|
-
version: releaseVersion.gitTag,
|
|
276
|
-
prerelease: releaseVersion.isPrerelease,
|
|
277
|
-
body: contents,
|
|
278
|
-
}, existingGithubReleaseForVersion);
|
|
279
|
-
}
|
|
488
|
+
(0, print_changes_1.printAndFlushChanges)(tree, !!dryRun, 3, false, shared_1.noDiffInChangelogMessage);
|
|
280
489
|
}
|
|
281
|
-
|
|
490
|
+
return {
|
|
491
|
+
releaseVersion,
|
|
492
|
+
contents,
|
|
493
|
+
};
|
|
282
494
|
}
|
|
283
|
-
async function generateChangelogForProjects(tree,
|
|
284
|
-
|
|
495
|
+
async function generateChangelogForProjects(tree, args, projectGraph, commits, projectsVersionData, releaseGroup, projects, nxReleaseConfig) {
|
|
496
|
+
const config = releaseGroup.changelog;
|
|
497
|
+
// The entire feature is disabled at the release group level, exit early
|
|
285
498
|
if (config === false) {
|
|
286
499
|
return;
|
|
287
500
|
}
|
|
501
|
+
// Only trigger interactive mode for the project changelog if the user explicitly requested it via "all" or "projects"
|
|
502
|
+
const interactive = args.interactive === 'all' || args.interactive === 'projects';
|
|
503
|
+
const dryRun = !!args.dryRun;
|
|
504
|
+
const gitRemote = args.gitRemote;
|
|
288
505
|
const changelogRenderer = resolveChangelogRenderer(config.renderer);
|
|
506
|
+
const projectChangelogs = {};
|
|
289
507
|
for (const project of projects) {
|
|
290
508
|
let interpolatedTreePath = config.file || '';
|
|
291
509
|
if (interpolatedTreePath) {
|
|
@@ -295,33 +513,32 @@ async function generateChangelogForProjects(tree, rawVersion, dryRun, interactiv
|
|
|
295
513
|
workspaceRoot: '', // within the tree, workspaceRoot is the root
|
|
296
514
|
});
|
|
297
515
|
}
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
516
|
+
/**
|
|
517
|
+
* newVersion will be null in the case that no changes were detected (e.g. in conventional commits mode),
|
|
518
|
+
* no changelog entry is relevant in that case.
|
|
519
|
+
*/
|
|
520
|
+
if (projectsVersionData[project.name].newVersion === null) {
|
|
521
|
+
continue;
|
|
522
|
+
}
|
|
523
|
+
const releaseVersion = new shared_1.ReleaseVersion({
|
|
524
|
+
version: projectsVersionData[project.name].newVersion,
|
|
525
|
+
releaseTagPattern: releaseGroup.releaseTagPattern,
|
|
301
526
|
projectName: project.name,
|
|
302
527
|
});
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
break;
|
|
309
|
-
case !!interpolatedTreePath:
|
|
310
|
-
logTitle += `n entry in ${interpolatedTreePath} for ${chalk.white(releaseVersion.gitTag)}`;
|
|
311
|
-
break;
|
|
312
|
-
case config.createRelease === 'github':
|
|
313
|
-
logTitle += ` Github release for ${chalk.white(releaseVersion.gitTag)}`;
|
|
528
|
+
if (interpolatedTreePath) {
|
|
529
|
+
const prefix = dryRun ? 'Previewing' : 'Generating';
|
|
530
|
+
output_1.output.log({
|
|
531
|
+
title: `${prefix} an entry in ${interpolatedTreePath} for ${chalk.white(releaseVersion.gitTag)}`,
|
|
532
|
+
});
|
|
314
533
|
}
|
|
315
|
-
output_1.output.log({
|
|
316
|
-
title: logTitle,
|
|
317
|
-
});
|
|
318
534
|
const githubRepoSlug = config.createRelease === 'github'
|
|
319
535
|
? (0, github_1.getGitHubRepoSlug)(gitRemote)
|
|
320
536
|
: undefined;
|
|
321
537
|
let contents = await changelogRenderer({
|
|
538
|
+
projectGraph,
|
|
322
539
|
commits,
|
|
323
540
|
releaseVersion: releaseVersion.rawVersion,
|
|
324
|
-
project:
|
|
541
|
+
project: project.name,
|
|
325
542
|
repoSlug: githubRepoSlug,
|
|
326
543
|
entryWhenNoChanges: typeof config.entryWhenNoChanges === 'string'
|
|
327
544
|
? (0, utils_1.interpolate)(config.entryWhenNoChanges, {
|
|
@@ -331,6 +548,7 @@ async function generateChangelogForProjects(tree, rawVersion, dryRun, interactiv
|
|
|
331
548
|
})
|
|
332
549
|
: false,
|
|
333
550
|
changelogRenderOptions: config.renderOptions,
|
|
551
|
+
conventionalCommitsConfig: nxReleaseConfig.conventionalCommits,
|
|
334
552
|
});
|
|
335
553
|
/**
|
|
336
554
|
* If interactive mode, make the changelog contents available for the user to modify in their editor of choice,
|
|
@@ -345,14 +563,10 @@ async function generateChangelogForProjects(tree, rawVersion, dryRun, interactiv
|
|
|
345
563
|
await (0, launch_editor_1.launchEditor)(changelogPath);
|
|
346
564
|
contents = (0, node_fs_1.readFileSync)(changelogPath, 'utf-8');
|
|
347
565
|
}
|
|
348
|
-
/**
|
|
349
|
-
* The exact logic we use for printing the summary/diff to the user is dependent upon whether they are creating
|
|
350
|
-
* a changelog file, a Github release, or both.
|
|
351
|
-
*/
|
|
352
|
-
let printSummary = () => { };
|
|
353
|
-
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?`);
|
|
354
566
|
if (interpolatedTreePath) {
|
|
355
|
-
let changelogContents = tree.
|
|
567
|
+
let changelogContents = tree.exists(interpolatedTreePath)
|
|
568
|
+
? tree.read(interpolatedTreePath).toString()
|
|
569
|
+
: '';
|
|
356
570
|
if (changelogContents) {
|
|
357
571
|
// NOTE: right now existing releases are always expected to be in markdown format, but in the future we could potentially support others via a custom parser option
|
|
358
572
|
const changelogReleases = (0, markdown_1.parseChangelogMarkdown)(changelogContents).releases;
|
|
@@ -370,74 +584,62 @@ async function generateChangelogForProjects(tree, rawVersion, dryRun, interactiv
|
|
|
370
584
|
changelogContents = contents;
|
|
371
585
|
}
|
|
372
586
|
tree.write(interpolatedTreePath, changelogContents);
|
|
373
|
-
|
|
587
|
+
(0, print_changes_1.printAndFlushChanges)(tree, !!dryRun, 3, false, shared_1.noDiffInChangelogMessage,
|
|
374
588
|
// Only print the change for the current changelog file at this point
|
|
375
589
|
(f) => f.path === interpolatedTreePath);
|
|
376
590
|
}
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
process.exit(1);
|
|
406
|
-
}
|
|
407
|
-
if (err.response?.status === 404) {
|
|
408
|
-
// No existing release found, this is fine
|
|
409
|
-
}
|
|
410
|
-
else {
|
|
411
|
-
// Rethrow unknown errors for now
|
|
412
|
-
throw err;
|
|
413
|
-
}
|
|
414
|
-
}
|
|
415
|
-
let existingPrintSummaryFn = printSummary;
|
|
416
|
-
printSummary = () => {
|
|
417
|
-
const logTitle = `https://github.com/${githubRepoSlug}/releases/tag/${releaseVersion.gitTag}`;
|
|
418
|
-
if (existingGithubReleaseForVersion) {
|
|
419
|
-
console.error(`${chalk.white('UPDATE')} ${logTitle}${dryRun ? chalk.keyword('orange')(' [dry-run]') : ''}`);
|
|
420
|
-
}
|
|
421
|
-
else {
|
|
422
|
-
console.error(`${chalk.green('CREATE')} ${logTitle}${dryRun ? chalk.keyword('orange')(' [dry-run]') : ''}`);
|
|
423
|
-
}
|
|
424
|
-
// Only print the diff here if we are not already going to be printing changes from the Tree
|
|
425
|
-
if (!interpolatedTreePath) {
|
|
426
|
-
console.log('');
|
|
427
|
-
(0, print_changes_1.printDiff)(existingGithubReleaseForVersion
|
|
428
|
-
? existingGithubReleaseForVersion.body
|
|
429
|
-
: '', contents, 3, noDiffInChangelogMessage);
|
|
430
|
-
}
|
|
431
|
-
existingPrintSummaryFn();
|
|
432
|
-
};
|
|
433
|
-
if (!dryRun) {
|
|
434
|
-
await (0, github_1.createOrUpdateGithubRelease)(githubRequestConfig, {
|
|
435
|
-
version: releaseVersion.gitTag,
|
|
436
|
-
prerelease: releaseVersion.isPrerelease,
|
|
437
|
-
body: contents,
|
|
438
|
-
}, existingGithubReleaseForVersion);
|
|
439
|
-
}
|
|
591
|
+
projectChangelogs[project.name] = {
|
|
592
|
+
releaseVersion,
|
|
593
|
+
contents,
|
|
594
|
+
};
|
|
595
|
+
}
|
|
596
|
+
return projectChangelogs;
|
|
597
|
+
}
|
|
598
|
+
function checkChangelogFilesEnabled(nxReleaseConfig) {
|
|
599
|
+
if (nxReleaseConfig.changelog.workspaceChangelog &&
|
|
600
|
+
nxReleaseConfig.changelog.workspaceChangelog.file) {
|
|
601
|
+
return true;
|
|
602
|
+
}
|
|
603
|
+
for (const releaseGroup of Object.values(nxReleaseConfig.groups)) {
|
|
604
|
+
if (releaseGroup.changelog && releaseGroup.changelog.file) {
|
|
605
|
+
return true;
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
return false;
|
|
609
|
+
}
|
|
610
|
+
async function getCommits(fromSHA, toSHA, conventionalCommitsConfig) {
|
|
611
|
+
const rawCommits = await (0, git_1.getGitDiff)(fromSHA, toSHA);
|
|
612
|
+
// Parse as conventional commits
|
|
613
|
+
return (0, git_1.parseCommits)(rawCommits).filter((c) => {
|
|
614
|
+
const type = c.type;
|
|
615
|
+
const typeConfig = conventionalCommitsConfig.types[type];
|
|
616
|
+
if (!typeConfig) {
|
|
617
|
+
// don't include commits with unknown types
|
|
618
|
+
return false;
|
|
440
619
|
}
|
|
441
|
-
|
|
620
|
+
return !typeConfig.changelog.hidden;
|
|
621
|
+
});
|
|
622
|
+
}
|
|
623
|
+
function shouldCreateGitHubRelease(changelogConfig, createReleaseArg = undefined) {
|
|
624
|
+
if (createReleaseArg !== undefined) {
|
|
625
|
+
return createReleaseArg === 'github';
|
|
626
|
+
}
|
|
627
|
+
return (changelogConfig || {}).createRelease === 'github';
|
|
628
|
+
}
|
|
629
|
+
exports.shouldCreateGitHubRelease = shouldCreateGitHubRelease;
|
|
630
|
+
async function promptForGitHubRelease() {
|
|
631
|
+
try {
|
|
632
|
+
const result = await (0, enquirer_1.prompt)([
|
|
633
|
+
{
|
|
634
|
+
name: 'confirmation',
|
|
635
|
+
message: 'Do you want to create a GitHub release anyway?',
|
|
636
|
+
type: 'confirm',
|
|
637
|
+
},
|
|
638
|
+
]);
|
|
639
|
+
return result.confirmation;
|
|
640
|
+
}
|
|
641
|
+
catch (e) {
|
|
642
|
+
// Handle the case where the user exits the prompt with ctrl+c
|
|
643
|
+
return false;
|
|
442
644
|
}
|
|
443
645
|
}
|