nx 17.1.0-beta.2 → 17.1.0-beta.3
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/bin/nx-cloud.js +6 -0
- package/package.json +12 -12
- 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 +75 -35
- package/src/command-line/init/implementation/angular/legacy-angular-versions.js +4 -2
- package/src/command-line/init/implementation/angular/standalone-workspace.js +1 -1
- package/src/command-line/release/changelog.js +73 -67
- package/src/command-line/release/utils/git.d.ts +1 -0
- package/src/command-line/release/utils/git.js +10 -1
- package/src/command-line/release/utils/github.d.ts +6 -2
- package/src/command-line/release/utils/github.js +7 -4
- 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/core/graph/main.js +1 -1
- package/src/core/graph/polyfills.js +1 -1
- package/src/migrations/update-17-0-0/use-minimal-config-for-tasks-runner-options.js +49 -13
- package/src/plugins/js/versions.d.ts +1 -1
- package/src/plugins/js/versions.js +1 -1
- 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 +45 -0
- package/src/plugins/project-json/build-nodes/project-json.d.ts +1 -4
- package/src/plugins/project-json/build-nodes/project-json.js +1 -38
- 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/utils.d.ts +8 -0
- package/src/tasks-runner/utils.js +17 -8
- package/src/utils/nx-plugin.js +5 -5
package/bin/nx-cloud.js
CHANGED
|
@@ -35,6 +35,12 @@ async function invokeCommandWithNxCloudClient(options) {
|
|
|
35
35
|
catch (e) {
|
|
36
36
|
const body = ['Cannot run commands from the `nx-cloud` CLI.'];
|
|
37
37
|
if (e instanceof update_manager_1.NxCloudEnterpriseOutdatedError) {
|
|
38
|
+
try {
|
|
39
|
+
// TODO: Remove this when all enterprise customers have updated.
|
|
40
|
+
// Try requiring the bin from the `nx-cloud` package.
|
|
41
|
+
return require('nx-cloud/bin/nx-cloud');
|
|
42
|
+
}
|
|
43
|
+
catch { }
|
|
38
44
|
body.push('If you are an Nx Enterprise customer, please reach out to your assigned Developer Productivity Engineer.', 'If you are NOT an Nx Enterprise customer but are seeing this message, please reach out to cloud-support@nrwl.io.');
|
|
39
45
|
}
|
|
40
46
|
if (e instanceof update_manager_1.NxCloudClientUnavailableError) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nx",
|
|
3
|
-
"version": "17.1.0-beta.
|
|
3
|
+
"version": "17.1.0-beta.3",
|
|
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": {
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
"yargs": "^17.6.2",
|
|
68
68
|
"yargs-parser": "21.1.1",
|
|
69
69
|
"node-machine-id": "1.1.12",
|
|
70
|
-
"@nrwl/tao": "17.1.0-beta.
|
|
70
|
+
"@nrwl/tao": "17.1.0-beta.3"
|
|
71
71
|
},
|
|
72
72
|
"peerDependencies": {
|
|
73
73
|
"@swc-node/register": "^1.6.7",
|
|
@@ -82,16 +82,16 @@
|
|
|
82
82
|
}
|
|
83
83
|
},
|
|
84
84
|
"optionalDependencies": {
|
|
85
|
-
"@nx/nx-darwin-x64": "17.1.0-beta.
|
|
86
|
-
"@nx/nx-darwin-arm64": "17.1.0-beta.
|
|
87
|
-
"@nx/nx-linux-x64-gnu": "17.1.0-beta.
|
|
88
|
-
"@nx/nx-linux-x64-musl": "17.1.0-beta.
|
|
89
|
-
"@nx/nx-win32-x64-msvc": "17.1.0-beta.
|
|
90
|
-
"@nx/nx-linux-arm64-gnu": "17.1.0-beta.
|
|
91
|
-
"@nx/nx-linux-arm64-musl": "17.1.0-beta.
|
|
92
|
-
"@nx/nx-linux-arm-gnueabihf": "17.1.0-beta.
|
|
93
|
-
"@nx/nx-win32-arm64-msvc": "17.1.0-beta.
|
|
94
|
-
"@nx/nx-freebsd-x64": "17.1.0-beta.
|
|
85
|
+
"@nx/nx-darwin-x64": "17.1.0-beta.3",
|
|
86
|
+
"@nx/nx-darwin-arm64": "17.1.0-beta.3",
|
|
87
|
+
"@nx/nx-linux-x64-gnu": "17.1.0-beta.3",
|
|
88
|
+
"@nx/nx-linux-x64-musl": "17.1.0-beta.3",
|
|
89
|
+
"@nx/nx-win32-x64-msvc": "17.1.0-beta.3",
|
|
90
|
+
"@nx/nx-linux-arm64-gnu": "17.1.0-beta.3",
|
|
91
|
+
"@nx/nx-linux-arm64-musl": "17.1.0-beta.3",
|
|
92
|
+
"@nx/nx-linux-arm-gnueabihf": "17.1.0-beta.3",
|
|
93
|
+
"@nx/nx-win32-arm64-msvc": "17.1.0-beta.3",
|
|
94
|
+
"@nx/nx-freebsd-x64": "17.1.0-beta.3"
|
|
95
95
|
},
|
|
96
96
|
"nx-migrations": {
|
|
97
97
|
"migrations": "./migrations.json",
|
|
@@ -5,13 +5,14 @@ const shared_options_1 = require("../yargs-utils/shared-options");
|
|
|
5
5
|
exports.yargsExecCommand = {
|
|
6
6
|
command: 'exec',
|
|
7
7
|
describe: 'Executes any command as if it was a target on the project',
|
|
8
|
-
builder: (yargs) => (0, shared_options_1.
|
|
8
|
+
builder: (yargs) => (0, shared_options_1.withRunManyOptions)(yargs),
|
|
9
9
|
handler: async (args) => {
|
|
10
10
|
try {
|
|
11
11
|
await (await Promise.resolve().then(() => require('./exec'))).nxExecCommand((0, shared_options_1.withOverrides)(args));
|
|
12
12
|
process.exit(0);
|
|
13
13
|
}
|
|
14
14
|
catch (e) {
|
|
15
|
+
console.error(e);
|
|
15
16
|
process.exit(1);
|
|
16
17
|
}
|
|
17
18
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare function nxExecCommand(args: Record<string, string[]>): Promise<unknown>;
|
|
1
|
+
export declare function nxExecCommand(args: Record<string, string | string[] | boolean>): Promise<unknown>;
|
|
@@ -5,6 +5,8 @@ const child_process_1 = require("child_process");
|
|
|
5
5
|
const path_1 = require("path");
|
|
6
6
|
const process_1 = require("process");
|
|
7
7
|
const yargs = require("yargs-parser");
|
|
8
|
+
const fs_1 = require("fs");
|
|
9
|
+
const find_matching_projects_1 = require("../../utils/find-matching-projects");
|
|
8
10
|
const configuration_1 = require("../../config/configuration");
|
|
9
11
|
const project_graph_1 = require("../../project-graph/project-graph");
|
|
10
12
|
const command_line_utils_1 = require("../../utils/command-line-utils");
|
|
@@ -13,8 +15,15 @@ const output_1 = require("../../utils/output");
|
|
|
13
15
|
const package_manager_1 = require("../../utils/package-manager");
|
|
14
16
|
const workspace_root_1 = require("../../utils/workspace-root");
|
|
15
17
|
const calculate_default_project_name_1 = require("../../config/calculate-default-project-name");
|
|
18
|
+
const get_command_projects_1 = require("../../commands-runner/get-command-projects");
|
|
16
19
|
async function nxExecCommand(args) {
|
|
17
|
-
const
|
|
20
|
+
const nxJson = (0, configuration_1.readNxJson)();
|
|
21
|
+
const { nxArgs, overrides } = (0, command_line_utils_1.splitArgsIntoNxArgsAndOverrides)(args, 'run-many', { printWarnings: args.graph !== 'stdout' }, nxJson);
|
|
22
|
+
if (nxArgs.verbose) {
|
|
23
|
+
process.env.NX_VERBOSE_LOGGING = 'true';
|
|
24
|
+
}
|
|
25
|
+
const scriptArgV = readScriptArgV(overrides);
|
|
26
|
+
const projectGraph = await (0, project_graph_1.createProjectGraphAsync)({ exitOnError: true });
|
|
18
27
|
// NX is already running
|
|
19
28
|
if (process.env.NX_TASK_TARGET_PROJECT) {
|
|
20
29
|
const command = scriptArgV
|
|
@@ -22,32 +31,56 @@ async function nxExecCommand(args) {
|
|
|
22
31
|
.trim();
|
|
23
32
|
(0, child_process_1.execSync)(command, {
|
|
24
33
|
stdio: 'inherit',
|
|
25
|
-
env:
|
|
34
|
+
env: {
|
|
35
|
+
...process.env,
|
|
36
|
+
NX_PROJECT_NAME: process.env.NX_TASK_TARGET_PROJECT,
|
|
37
|
+
NX_PROJECT_ROOT_PATH: projectGraph.nodes?.[process.env.NX_TASK_TARGET_PROJECT]?.data?.root,
|
|
38
|
+
},
|
|
26
39
|
});
|
|
27
40
|
}
|
|
28
41
|
else {
|
|
29
42
|
// nx exec is being ran inside of Nx's context
|
|
30
|
-
return runScriptAsNxTarget(scriptArgV);
|
|
43
|
+
return runScriptAsNxTarget(projectGraph, scriptArgV, nxArgs);
|
|
31
44
|
}
|
|
32
45
|
}
|
|
33
46
|
exports.nxExecCommand = nxExecCommand;
|
|
34
|
-
async function runScriptAsNxTarget(argv) {
|
|
35
|
-
const projectGraph = await (0, project_graph_1.createProjectGraphAsync)();
|
|
36
|
-
const { projectName, project } = getProject(projectGraph);
|
|
47
|
+
async function runScriptAsNxTarget(projectGraph, argv, nxArgs) {
|
|
37
48
|
// NPM, Yarn, and PNPM set this to the name of the currently executing script. Lets use it if we can.
|
|
38
49
|
const targetName = process.env.npm_lifecycle_event;
|
|
39
|
-
|
|
50
|
+
if (targetName) {
|
|
51
|
+
const defaultPorject = getDefaultProject(projectGraph);
|
|
52
|
+
const scriptDefinition = getScriptDefinition(targetName, defaultPorject);
|
|
53
|
+
if (scriptDefinition) {
|
|
54
|
+
runTargetOnProject(scriptDefinition, targetName, defaultPorject, defaultPorject.name, argv);
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
const projects = getProjects(projectGraph, nxArgs);
|
|
59
|
+
const projectsToRun = (0, get_command_projects_1.getCommandProjects)(projectGraph, projects, nxArgs);
|
|
60
|
+
projectsToRun.forEach((projectName) => {
|
|
61
|
+
const command = argv.reduce((cmd, arg) => cmd + `"${arg}" `, '').trim();
|
|
62
|
+
(0, child_process_1.execSync)(command, {
|
|
63
|
+
stdio: 'inherit',
|
|
64
|
+
env: {
|
|
65
|
+
...process.env,
|
|
66
|
+
NX_PROJECT_NAME: projectGraph.nodes?.[projectName]?.name,
|
|
67
|
+
NX_PROJECT_ROOT_PATH: projectGraph.nodes?.[projectName]?.data?.root,
|
|
68
|
+
},
|
|
69
|
+
cwd: projectGraph.nodes?.[projectName]?.data?.root ?? workspace_root_1.workspaceRoot,
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
function runTargetOnProject(scriptDefinition, targetName, project, projectName, argv) {
|
|
40
74
|
ensureNxTarget(project, targetName);
|
|
41
75
|
// Get ArgV that is provided in npm script definition
|
|
42
76
|
const providedArgs = yargs(scriptDefinition)._.slice(2);
|
|
43
77
|
const extraArgs = providedArgs.length === argv.length ? [] : argv.slice(providedArgs.length);
|
|
44
78
|
const pm = (0, package_manager_1.getPackageManagerCommand)();
|
|
45
79
|
// `targetName` might be an npm script with `:` like: `start:dev`, `start:debug`.
|
|
46
|
-
|
|
47
|
-
|
|
80
|
+
const command = `${pm.exec} nx run ${projectName}:\\\"${targetName}\\\" ${extraArgs.join(' ')}`;
|
|
81
|
+
(0, child_process_1.execSync)(command, { stdio: 'inherit' });
|
|
48
82
|
}
|
|
49
|
-
function readScriptArgV(
|
|
50
|
-
const { overrides } = (0, command_line_utils_1.splitArgsIntoNxArgsAndOverrides)(args, 'run-one', { printWarnings: false }, (0, configuration_1.readNxJson)());
|
|
83
|
+
function readScriptArgV(overrides) {
|
|
51
84
|
const scriptSeparatorIdx = process.argv.findIndex((el) => el === '--');
|
|
52
85
|
if (scriptSeparatorIdx === -1) {
|
|
53
86
|
output_1.output.error({
|
|
@@ -57,18 +90,15 @@ function readScriptArgV(args) {
|
|
|
57
90
|
}
|
|
58
91
|
return overrides.__overrides_unparsed__;
|
|
59
92
|
}
|
|
60
|
-
function getScriptDefinition(
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
});
|
|
69
|
-
process.exit(1);
|
|
93
|
+
function getScriptDefinition(targetName, project) {
|
|
94
|
+
if (!project) {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
const packageJsonPath = (0, path_1.join)(workspace_root_1.workspaceRoot, project.data.root, 'package.json');
|
|
98
|
+
if ((0, fs_1.existsSync)(packageJsonPath)) {
|
|
99
|
+
const scriptDefinition = (0, fileutils_1.readJsonFile)(packageJsonPath).scripts?.[targetName];
|
|
100
|
+
return scriptDefinition;
|
|
70
101
|
}
|
|
71
|
-
return scriptDefinition;
|
|
72
102
|
}
|
|
73
103
|
function ensureNxTarget(project, targetName) {
|
|
74
104
|
if (!project.data.targets[targetName]) {
|
|
@@ -81,18 +111,28 @@ function ensureNxTarget(project, targetName) {
|
|
|
81
111
|
(0, process_1.exit)(1);
|
|
82
112
|
}
|
|
83
113
|
}
|
|
84
|
-
function
|
|
85
|
-
const
|
|
86
|
-
if (
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
114
|
+
function getDefaultProject(projectGraph) {
|
|
115
|
+
const defaultProjectName = (0, calculate_default_project_name_1.calculateDefaultProjectName)(process.cwd(), workspace_root_1.workspaceRoot, (0, project_graph_1.readProjectsConfigurationFromProjectGraph)(projectGraph), (0, configuration_1.readNxJson)());
|
|
116
|
+
if (defaultProjectName && projectGraph.nodes[defaultProjectName]) {
|
|
117
|
+
return projectGraph.nodes[defaultProjectName];
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
function getProjects(projectGraph, nxArgs) {
|
|
121
|
+
let selectedProjects = {};
|
|
122
|
+
// get projects matched
|
|
123
|
+
if (nxArgs.projects?.length) {
|
|
124
|
+
const matchingProjects = (0, find_matching_projects_1.findMatchingProjects)(nxArgs.projects, projectGraph.nodes);
|
|
125
|
+
for (const project of matchingProjects) {
|
|
126
|
+
selectedProjects[project] = projectGraph.nodes[project];
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
// if no project specified, return all projects
|
|
131
|
+
selectedProjects = { ...projectGraph.nodes };
|
|
132
|
+
}
|
|
133
|
+
const excludedProjects = (0, find_matching_projects_1.findMatchingProjects)(nxArgs.exclude, selectedProjects);
|
|
134
|
+
for (const excludedProject of excludedProjects) {
|
|
135
|
+
delete selectedProjects[excludedProject];
|
|
95
136
|
}
|
|
96
|
-
|
|
97
|
-
return { projectName, project };
|
|
137
|
+
return Object.values(selectedProjects);
|
|
98
138
|
}
|
|
@@ -12,9 +12,11 @@ const package_manager_1 = require("../../../../utils/package-manager");
|
|
|
12
12
|
const utils_1 = require("../utils");
|
|
13
13
|
// map of Angular major versions to Nx versions to use for legacy `nx init` migrations,
|
|
14
14
|
// key is major Angular version and value is Nx version to use
|
|
15
|
-
const nxAngularLegacyVersionMap = {
|
|
15
|
+
const nxAngularLegacyVersionMap = {
|
|
16
|
+
14: '~17.0.0',
|
|
17
|
+
};
|
|
16
18
|
// min major angular version supported in latest Nx
|
|
17
|
-
const minMajorAngularVersionSupported =
|
|
19
|
+
const minMajorAngularVersionSupported = 15;
|
|
18
20
|
// version when the Nx CLI changed from @nrwl/tao & @nrwl/cli to nx
|
|
19
21
|
const versionWithConsolidatedPackages = '13.9.0';
|
|
20
22
|
// version when packages were rescoped from @nrwl/* to @nx/*
|
|
@@ -98,7 +98,7 @@ function createNxJson(repoRoot, angularJson, cacheableOperations, { eslintProjec
|
|
|
98
98
|
inputs: ['default', '^production'],
|
|
99
99
|
};
|
|
100
100
|
}
|
|
101
|
-
// Angular
|
|
101
|
+
// Angular 15 workspaces still support defaultProject. Support was removed in Angular 16.
|
|
102
102
|
nxJson.defaultProject = angularJson.defaultProject;
|
|
103
103
|
(0, fileutils_1.writeJsonFile)((0, path_1.join)(repoRoot, 'nx.json'), nxJson);
|
|
104
104
|
}
|
|
@@ -22,6 +22,7 @@ const github_1 = require("./utils/github");
|
|
|
22
22
|
const launch_editor_1 = require("./utils/launch-editor");
|
|
23
23
|
const markdown_1 = require("./utils/markdown");
|
|
24
24
|
const print_changes_1 = require("./utils/print-changes");
|
|
25
|
+
const params_1 = require("../../utils/params");
|
|
25
26
|
class ReleaseVersion {
|
|
26
27
|
constructor({ version, // short form version string with no prefixes or patterns, e.g. 1.0.0
|
|
27
28
|
releaseTagPattern, // full pattern to interpolate, e.g. "v{version}" or "{projectName}@{version}"
|
|
@@ -36,80 +37,83 @@ class ReleaseVersion {
|
|
|
36
37
|
}
|
|
37
38
|
}
|
|
38
39
|
async function changelogHandler(args) {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
return (0, params_1.handleErrors)(args.verbose, async () => {
|
|
41
|
+
// Right now, the given version must be valid semver in order to proceed
|
|
42
|
+
if (!(0, semver_1.valid)(args.version)) {
|
|
43
|
+
output_1.output.error({
|
|
44
|
+
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`,
|
|
45
|
+
});
|
|
46
|
+
process.exit(1);
|
|
47
|
+
}
|
|
48
|
+
const projectGraph = await (0, project_graph_1.createProjectGraphAsync)({ exitOnError: true });
|
|
49
|
+
const nxJson = (0, nx_json_1.readNxJson)();
|
|
50
|
+
const commitHash = await (0, git_1.getCommitHash)(args.to);
|
|
51
|
+
if (args.verbose) {
|
|
52
|
+
process.env.NX_VERBOSE_LOGGING = 'true';
|
|
53
|
+
}
|
|
54
|
+
// Apply default configuration to any optional user configuration
|
|
55
|
+
const { error: configError, nxReleaseConfig } = await (0, config_1.createNxReleaseConfig)(projectGraph, nxJson.release);
|
|
56
|
+
if (configError) {
|
|
57
|
+
return await (0, config_1.handleNxReleaseConfigError)(configError);
|
|
58
|
+
}
|
|
59
|
+
const { error: filterError, releaseGroups, releaseGroupToFilteredProjects, } = (0, filter_release_groups_1.filterReleaseGroups)(projectGraph, nxReleaseConfig, args.projects, args.groups);
|
|
60
|
+
if (filterError) {
|
|
61
|
+
output_1.output.error(filterError);
|
|
62
|
+
process.exit(1);
|
|
63
|
+
}
|
|
64
|
+
const releaseVersion = new ReleaseVersion({
|
|
65
|
+
version: args.version,
|
|
66
|
+
releaseTagPattern: nxReleaseConfig.releaseTagPattern,
|
|
43
67
|
});
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
version: args.version,
|
|
63
|
-
releaseTagPattern: nxReleaseConfig.releaseTagPattern,
|
|
64
|
-
});
|
|
65
|
-
const from = args.from ||
|
|
66
|
-
(await (0, git_1.getLatestGitTagForPattern)(nxReleaseConfig.releaseTagPattern))?.tag;
|
|
67
|
-
if (!from) {
|
|
68
|
-
output_1.output.error({
|
|
69
|
-
title: `Unable to determine the previous git tag, please provide an explicit git reference using --from`,
|
|
68
|
+
const from = args.from ||
|
|
69
|
+
(await (0, git_1.getLatestGitTagForPattern)(nxReleaseConfig.releaseTagPattern))?.tag;
|
|
70
|
+
if (!from) {
|
|
71
|
+
output_1.output.error({
|
|
72
|
+
title: `Unable to determine the previous git tag, please provide an explicit git reference using --from`,
|
|
73
|
+
});
|
|
74
|
+
process.exit(1);
|
|
75
|
+
}
|
|
76
|
+
const rawCommits = await (0, git_1.getGitDiff)(from, args.to);
|
|
77
|
+
// Parse as conventional commits
|
|
78
|
+
const commits = (0, git_1.parseCommits)(rawCommits).filter((c) => {
|
|
79
|
+
const type = c.type;
|
|
80
|
+
// Always ignore non user-facing commits for now
|
|
81
|
+
// TODO: allow this filter to be configurable via config in a future release
|
|
82
|
+
if (type === 'feat' || type === 'fix' || type === 'perf') {
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
85
|
+
return false;
|
|
70
86
|
});
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
87
|
+
const tree = new tree_1.FsTree(workspace_root_1.workspaceRoot, args.verbose);
|
|
88
|
+
await generateChangelogForWorkspace(tree, releaseVersion, !!args.dryRun,
|
|
89
|
+
// Only trigger interactive mode for the workspace changelog if the user explicitly requested it via "all" or "workspace"
|
|
90
|
+
args.interactive === 'all' || args.interactive === 'workspace', commitHash, commits, nxReleaseConfig.changelog.workspaceChangelog, args.gitRemote);
|
|
91
|
+
if (args.projects?.length) {
|
|
92
|
+
/**
|
|
93
|
+
* Run changelog generation for all remaining release groups and filtered projects within them
|
|
94
|
+
*/
|
|
95
|
+
for (const releaseGroup of releaseGroups) {
|
|
96
|
+
const projectNodes = Array.from(releaseGroupToFilteredProjects.get(releaseGroup)).map((name) => projectGraph.nodes[name]);
|
|
97
|
+
await generateChangelogForProjects(tree, args.version, !!args.dryRun,
|
|
98
|
+
// Only trigger interactive mode for the workspace changelog if the user explicitly requested it via "all" or "projects"
|
|
99
|
+
args.interactive === 'all' || args.interactive === 'projects', commitHash, commits, releaseGroup.changelog, releaseGroup.releaseTagPattern, projectNodes, args.gitRemote);
|
|
100
|
+
}
|
|
101
|
+
return process.exit(0);
|
|
81
102
|
}
|
|
82
|
-
return false;
|
|
83
|
-
});
|
|
84
|
-
const tree = new tree_1.FsTree(workspace_root_1.workspaceRoot, args.verbose);
|
|
85
|
-
await generateChangelogForWorkspace(tree, releaseVersion, !!args.dryRun,
|
|
86
|
-
// Only trigger interactive mode for the workspace changelog if the user explicitly requested it via "all" or "workspace"
|
|
87
|
-
args.interactive === 'all' || args.interactive === 'workspace', commits, nxReleaseConfig.changelog.workspaceChangelog, args.gitRemote);
|
|
88
|
-
if (args.projects?.length) {
|
|
89
103
|
/**
|
|
90
|
-
* Run changelog generation for all remaining release groups
|
|
104
|
+
* Run changelog generation for all remaining release groups
|
|
91
105
|
*/
|
|
92
106
|
for (const releaseGroup of releaseGroups) {
|
|
93
|
-
const projectNodes =
|
|
107
|
+
const projectNodes = releaseGroup.projects.map((name) => projectGraph.nodes[name]);
|
|
94
108
|
await generateChangelogForProjects(tree, args.version, !!args.dryRun,
|
|
95
109
|
// Only trigger interactive mode for the workspace changelog if the user explicitly requested it via "all" or "projects"
|
|
96
|
-
args.interactive === 'all' || args.interactive === 'projects', commits, releaseGroup.changelog, releaseGroup.releaseTagPattern, projectNodes, args.gitRemote);
|
|
110
|
+
args.interactive === 'all' || args.interactive === 'projects', commitHash, commits, releaseGroup.changelog, releaseGroup.releaseTagPattern, projectNodes, args.gitRemote);
|
|
97
111
|
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
for (const releaseGroup of releaseGroups) {
|
|
104
|
-
const projectNodes = releaseGroup.projects.map((name) => projectGraph.nodes[name]);
|
|
105
|
-
await generateChangelogForProjects(tree, args.version, !!args.dryRun,
|
|
106
|
-
// Only trigger interactive mode for the workspace changelog if the user explicitly requested it via "all" or "projects"
|
|
107
|
-
args.interactive === 'all' || args.interactive === 'projects', commits, releaseGroup.changelog, releaseGroup.releaseTagPattern, projectNodes, args.gitRemote);
|
|
108
|
-
}
|
|
109
|
-
if (args.dryRun) {
|
|
110
|
-
logger_1.logger.warn(`\nNOTE: The "dryRun" flag means no changelogs were actually created.`);
|
|
111
|
-
}
|
|
112
|
-
process.exit(0);
|
|
112
|
+
if (args.dryRun) {
|
|
113
|
+
logger_1.logger.warn(`\nNOTE: The "dryRun" flag means no changelogs were actually created.`);
|
|
114
|
+
}
|
|
115
|
+
process.exit(0);
|
|
116
|
+
});
|
|
113
117
|
}
|
|
114
118
|
exports.changelogHandler = changelogHandler;
|
|
115
119
|
function isPrerelease(version) {
|
|
@@ -135,7 +139,7 @@ function resolveChangelogRenderer(changelogRendererPath) {
|
|
|
135
139
|
}
|
|
136
140
|
return changelogRenderer;
|
|
137
141
|
}
|
|
138
|
-
async function generateChangelogForWorkspace(tree, releaseVersion, dryRun, interactive, commits, config, gitRemote) {
|
|
142
|
+
async function generateChangelogForWorkspace(tree, releaseVersion, dryRun, interactive, commit, commits, config, gitRemote) {
|
|
139
143
|
// The entire feature is disabled at the workspace level, exit early
|
|
140
144
|
if (config === false) {
|
|
141
145
|
return;
|
|
@@ -276,12 +280,13 @@ async function generateChangelogForWorkspace(tree, releaseVersion, dryRun, inter
|
|
|
276
280
|
version: releaseVersion.gitTag,
|
|
277
281
|
prerelease: releaseVersion.isPrerelease,
|
|
278
282
|
body: contents,
|
|
283
|
+
commit,
|
|
279
284
|
}, existingGithubReleaseForVersion);
|
|
280
285
|
}
|
|
281
286
|
}
|
|
282
287
|
printSummary();
|
|
283
288
|
}
|
|
284
|
-
async function generateChangelogForProjects(tree, rawVersion, dryRun, interactive, commits, config, releaseTagPattern, projects, gitRemote) {
|
|
289
|
+
async function generateChangelogForProjects(tree, rawVersion, dryRun, interactive, commit, commits, config, releaseTagPattern, projects, gitRemote) {
|
|
285
290
|
// The entire feature is disabled at the project level, exit early
|
|
286
291
|
if (config === false) {
|
|
287
292
|
return;
|
|
@@ -436,6 +441,7 @@ async function generateChangelogForProjects(tree, rawVersion, dryRun, interactiv
|
|
|
436
441
|
version: releaseVersion.gitTag,
|
|
437
442
|
prerelease: releaseVersion.isPrerelease,
|
|
438
443
|
body: contents,
|
|
444
|
+
commit,
|
|
439
445
|
}, existingGithubReleaseForVersion);
|
|
440
446
|
}
|
|
441
447
|
}
|
|
@@ -28,3 +28,4 @@ export declare function getLatestGitTagForPattern(releaseTagPattern: string, add
|
|
|
28
28
|
export declare function getGitDiff(from: string | undefined, to?: string): Promise<RawGitCommit[]>;
|
|
29
29
|
export declare function parseCommits(commits: RawGitCommit[]): GitCommit[];
|
|
30
30
|
export declare function parseGitCommit(commit: RawGitCommit): GitCommit | null;
|
|
31
|
+
export declare function getCommitHash(ref: string): Promise<string>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.parseGitCommit = exports.parseCommits = exports.getGitDiff = exports.getLatestGitTagForPattern = void 0;
|
|
3
|
+
exports.getCommitHash = exports.parseGitCommit = exports.parseCommits = exports.getGitDiff = exports.getLatestGitTagForPattern = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* Special thanks to changelogen for the original inspiration for many of these utilities:
|
|
6
6
|
* https://github.com/unjs/changelogen
|
|
@@ -126,3 +126,12 @@ function parseGitCommit(commit) {
|
|
|
126
126
|
};
|
|
127
127
|
}
|
|
128
128
|
exports.parseGitCommit = parseGitCommit;
|
|
129
|
+
function getCommitHash(ref) {
|
|
130
|
+
try {
|
|
131
|
+
return (0, exec_command_1.execCommand)('git', ['rev-parse', ref]);
|
|
132
|
+
}
|
|
133
|
+
catch (e) {
|
|
134
|
+
throw new Error(`Unknown revision: ${ref}`);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
exports.getCommitHash = getCommitHash;
|
|
@@ -7,17 +7,21 @@ export interface GithubRequestConfig {
|
|
|
7
7
|
export interface GithubRelease {
|
|
8
8
|
id?: string;
|
|
9
9
|
tag_name: string;
|
|
10
|
+
target_commitish?: string;
|
|
10
11
|
name?: string;
|
|
11
12
|
body?: string;
|
|
12
13
|
draft?: boolean;
|
|
13
14
|
prerelease?: boolean;
|
|
14
15
|
}
|
|
15
16
|
export declare function getGitHubRepoSlug(remoteName?: string): RepoSlug;
|
|
16
|
-
|
|
17
|
+
interface GithubReleaseOptions {
|
|
17
18
|
version: string;
|
|
18
19
|
body: string;
|
|
19
20
|
prerelease: boolean;
|
|
20
|
-
|
|
21
|
+
commit: string;
|
|
22
|
+
}
|
|
23
|
+
export declare function createOrUpdateGithubRelease(githubRequestConfig: GithubRequestConfig, release: GithubReleaseOptions, existingGithubReleaseForVersion?: GithubRelease): Promise<void>;
|
|
21
24
|
export declare function resolveGithubToken(): Promise<string | null>;
|
|
22
25
|
export declare function getGithubReleaseByTag(config: GithubRequestConfig, tag: string): Promise<GithubRelease>;
|
|
23
26
|
export declare function formatReferences(references: Reference[], repoSlug: RepoSlug): string;
|
|
27
|
+
export {};
|
|
@@ -5,7 +5,7 @@ const chalk = require("chalk");
|
|
|
5
5
|
const node_child_process_1 = require("node:child_process");
|
|
6
6
|
const node_fs_1 = require("node:fs");
|
|
7
7
|
const node_os_1 = require("node:os");
|
|
8
|
-
const
|
|
8
|
+
const path_1 = require("../../../utils/path");
|
|
9
9
|
// axios types and values don't seem to match
|
|
10
10
|
const _axios = require("axios");
|
|
11
11
|
const axios = _axios;
|
|
@@ -16,7 +16,7 @@ function getGitHubRepoSlug(remoteName = 'origin') {
|
|
|
16
16
|
stdio: 'pipe',
|
|
17
17
|
}).trim();
|
|
18
18
|
// Extract the 'user/repo' part from the URL
|
|
19
|
-
const regex = /github\.com[/:]([\w-]+\/[\w-]+)
|
|
19
|
+
const regex = /github\.com[/:]([\w-]+\/[\w-]+)/;
|
|
20
20
|
const match = remoteUrl.match(regex);
|
|
21
21
|
if (match && match[1]) {
|
|
22
22
|
return match[1];
|
|
@@ -64,7 +64,10 @@ async function syncGithubRelease(githubRequestConfig, release, existingGithubRel
|
|
|
64
64
|
try {
|
|
65
65
|
const newGhRelease = await (existingGithubReleaseForVersion
|
|
66
66
|
? updateGithubRelease(githubRequestConfig, existingGithubReleaseForVersion.id, ghRelease)
|
|
67
|
-
: createGithubRelease(githubRequestConfig,
|
|
67
|
+
: createGithubRelease(githubRequestConfig, {
|
|
68
|
+
...ghRelease,
|
|
69
|
+
target_commitish: release.commit,
|
|
70
|
+
}));
|
|
68
71
|
return {
|
|
69
72
|
status: existingGithubReleaseForVersion ? 'updated' : 'created',
|
|
70
73
|
id: newGhRelease.id,
|
|
@@ -86,7 +89,7 @@ async function resolveGithubToken() {
|
|
|
86
89
|
return tokenFromEnv;
|
|
87
90
|
}
|
|
88
91
|
// Try and resolve from gh CLI installation
|
|
89
|
-
const ghCLIPath = (0,
|
|
92
|
+
const ghCLIPath = (0, path_1.joinPathFragments)(process.env.XDG_CONFIG_HOME || (0, path_1.joinPathFragments)((0, node_os_1.homedir)(), '.config'), 'gh', 'hosts.yml');
|
|
90
93
|
if ((0, node_fs_1.existsSync)(ghCLIPath)) {
|
|
91
94
|
const yamlContents = await node_fs_1.promises.readFile(ghCLIPath, 'utf8');
|
|
92
95
|
const { load } = require('@zkochan/js-yaml');
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Graph of Tasks to be executed
|
|
3
|
+
*/
|
|
4
|
+
export interface CommandGraph {
|
|
5
|
+
/**
|
|
6
|
+
* Projects that do not have any dependencies and are thus ready to execute immediately
|
|
7
|
+
*/
|
|
8
|
+
roots: string[];
|
|
9
|
+
/**
|
|
10
|
+
* Map of projects to projects which the task depends on
|
|
11
|
+
*/
|
|
12
|
+
dependencies: Record<string, string[]>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { ProjectGraph } from '../config/project-graph';
|
|
2
|
+
import { NxArgs } from '../utils/command-line-utils';
|
|
3
|
+
import { CommandGraph } from './command-graph';
|
|
4
|
+
export declare function createCommandGraph(projectGraph: ProjectGraph, projectNames: string[], nxArgs: NxArgs): CommandGraph;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createCommandGraph = void 0;
|
|
4
|
+
const task_graph_utils_1 = require("../tasks-runner/task-graph-utils");
|
|
5
|
+
const output_1 = require("../utils/output");
|
|
6
|
+
function createCommandGraph(projectGraph, projectNames, nxArgs) {
|
|
7
|
+
const dependencies = {};
|
|
8
|
+
for (const projectName of projectNames) {
|
|
9
|
+
if (projectGraph.dependencies[projectName].length >= 1) {
|
|
10
|
+
dependencies[projectName] = [
|
|
11
|
+
...new Set(projectGraph.dependencies[projectName]
|
|
12
|
+
.map((projectDep) => projectDep.target)
|
|
13
|
+
.filter((projectDep) => projectGraph.nodes[projectDep])).values(),
|
|
14
|
+
];
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
dependencies[projectName] = [];
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
const roots = Object.keys(dependencies).filter((d) => dependencies[d].length === 0);
|
|
21
|
+
const commandGraph = {
|
|
22
|
+
dependencies,
|
|
23
|
+
roots,
|
|
24
|
+
};
|
|
25
|
+
const cycle = (0, task_graph_utils_1.findCycle)(commandGraph);
|
|
26
|
+
if (cycle) {
|
|
27
|
+
if (process.env.NX_IGNORE_CYCLES === 'true' || nxArgs.nxIgnoreCycles) {
|
|
28
|
+
output_1.output.warn({
|
|
29
|
+
title: `The command graph has a circular dependency`,
|
|
30
|
+
bodyLines: [`${cycle.join(' --> ')}`],
|
|
31
|
+
});
|
|
32
|
+
(0, task_graph_utils_1.makeAcyclic)(commandGraph);
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
output_1.output.error({
|
|
36
|
+
title: `Could not execute command because the project graph has a circular dependency`,
|
|
37
|
+
bodyLines: [`${cycle.join(' --> ')}`],
|
|
38
|
+
});
|
|
39
|
+
process.exit(1);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return commandGraph;
|
|
43
|
+
}
|
|
44
|
+
exports.createCommandGraph = createCommandGraph;
|