nx 19.6.0-canary.20240803-bd7a2c9 → 19.6.0-canary.20240808-333ab77
Sign up to get free protection for your applications and to get access to all the features.
- package/package.json +12 -12
- package/release/changelog-renderer/index.js +16 -1
- package/release/index.d.ts +1 -1
- package/release/index.js +2 -1
- package/schemas/nx-schema.json +3 -0
- package/src/adapter/compat.d.ts +1 -1
- package/src/adapter/compat.js +1 -0
- package/src/command-line/connect/connect-to-nx-cloud.js +7 -3
- package/src/command-line/release/changelog.d.ts +2 -7
- package/src/command-line/release/changelog.js +415 -363
- package/src/command-line/release/command-object.d.ts +1 -0
- package/src/command-line/release/command-object.js +14 -0
- package/src/command-line/release/config/deep-merge-json.d.ts +1 -0
- package/src/command-line/release/config/deep-merge-json.js +28 -0
- package/src/command-line/release/config/version-plans.d.ts +5 -0
- package/src/command-line/release/config/version-plans.js +9 -5
- package/src/command-line/release/index.d.ts +16 -4
- package/src/command-line/release/index.js +23 -9
- package/src/command-line/release/plan.d.ts +2 -1
- package/src/command-line/release/plan.js +93 -100
- package/src/command-line/release/publish.d.ts +2 -6
- package/src/command-line/release/publish.js +67 -54
- package/src/command-line/release/release.d.ts +2 -1
- package/src/command-line/release/release.js +181 -165
- package/src/command-line/release/utils/generate-version-plan-content.js +2 -3
- package/src/command-line/release/utils/print-config.d.ts +7 -0
- package/src/command-line/release/utils/print-config.js +36 -0
- package/src/command-line/release/version.d.ts +7 -6
- package/src/command-line/release/version.js +179 -165
- package/src/config/nx-json.d.ts +6 -1
- package/src/devkit-internals.d.ts +2 -2
- package/src/devkit-internals.js +2 -2
- package/src/native/nx.wasm32-wasi.wasm +0 -0
- package/src/nx-cloud/generators/connect-to-nx-cloud/connect-to-nx-cloud.d.ts +2 -1
- package/src/nx-cloud/generators/connect-to-nx-cloud/connect-to-nx-cloud.js +49 -10
- package/src/nx-cloud/nx-cloud-tasks-runner-shell.d.ts +1 -0
- package/src/nx-cloud/utilities/axios.js +9 -2
- package/src/plugins/js/project-graph/build-dependencies/target-project-locator.js +7 -2
- package/src/plugins/package-json/create-nodes.js +9 -1
- package/src/project-graph/plugins/isolation/plugin-pool.js +32 -10
- package/src/tasks-runner/run-command.js +6 -1
- package/src/tasks-runner/utils.js +14 -10
- package/src/utils/nx-cloud-utils.js +3 -1
- package/src/utils/package-manager.js +12 -3
@@ -1,7 +1,7 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
3
|
exports.releaseVersionCLIHandler = exports.validReleaseVersionPrefixes = exports.deriveNewSemverVersion = void 0;
|
4
|
-
exports.
|
4
|
+
exports.createAPI = createAPI;
|
5
5
|
const chalk = require("chalk");
|
6
6
|
const node_child_process_1 = require("node:child_process");
|
7
7
|
const node_fs_1 = require("node:fs");
|
@@ -17,11 +17,13 @@ const workspace_root_1 = require("../../utils/workspace-root");
|
|
17
17
|
const generate_1 = require("../generate/generate");
|
18
18
|
const generator_utils_1 = require("../generate/generator-utils");
|
19
19
|
const config_1 = require("./config/config");
|
20
|
+
const deep_merge_json_1 = require("./config/deep-merge-json");
|
20
21
|
const filter_release_groups_1 = require("./config/filter-release-groups");
|
21
22
|
const version_plans_1 = require("./config/version-plans");
|
22
23
|
const batch_projects_by_generator_config_1 = require("./utils/batch-projects-by-generator-config");
|
23
24
|
const git_1 = require("./utils/git");
|
24
25
|
const print_changes_1 = require("./utils/print-changes");
|
26
|
+
const print_config_1 = require("./utils/print-config");
|
25
27
|
const resolve_nx_json_error_message_1 = require("./utils/resolve-nx-json-error-message");
|
26
28
|
const shared_1 = require("./utils/shared");
|
27
29
|
const LARGE_BUFFER = 1024 * 1000000;
|
@@ -29,78 +31,180 @@ const LARGE_BUFFER = 1024 * 1000000;
|
|
29
31
|
var semver_1 = require("./utils/semver");
|
30
32
|
Object.defineProperty(exports, "deriveNewSemverVersion", { enumerable: true, get: function () { return semver_1.deriveNewSemverVersion; } });
|
31
33
|
exports.validReleaseVersionPrefixes = ['auto', '', '~', '^', '='];
|
32
|
-
const releaseVersionCLIHandler = (args) => (0, params_1.handleErrors)(args.verbose, () =>
|
34
|
+
const releaseVersionCLIHandler = (args) => (0, params_1.handleErrors)(args.verbose, () => createAPI({})(args));
|
33
35
|
exports.releaseVersionCLIHandler = releaseVersionCLIHandler;
|
34
|
-
|
35
|
-
* NOTE: This function is also exported for programmatic usage and forms part of the public API
|
36
|
-
* of Nx. We intentionally do not wrap the implementation with handleErrors because users need
|
37
|
-
* to have control over their own error handling when using the API.
|
38
|
-
*/
|
39
|
-
async function releaseVersion(args) {
|
40
|
-
const projectGraph = await (0, project_graph_1.createProjectGraphAsync)({ exitOnError: true });
|
41
|
-
const { projects } = (0, project_graph_1.readProjectsConfigurationFromProjectGraph)(projectGraph);
|
42
|
-
const nxJson = (0, nx_json_1.readNxJson)();
|
43
|
-
if (args.verbose) {
|
44
|
-
process.env.NX_VERBOSE_LOGGING = 'true';
|
45
|
-
}
|
46
|
-
// Apply default configuration to any optional user configuration
|
47
|
-
const { error: configError, nxReleaseConfig } = await (0, config_1.createNxReleaseConfig)(projectGraph, await (0, file_map_utils_1.createProjectFileMapUsingProjectGraph)(projectGraph), nxJson.release);
|
48
|
-
if (configError) {
|
49
|
-
return await (0, config_1.handleNxReleaseConfigError)(configError);
|
50
|
-
}
|
51
|
-
// The nx release top level command will always override these three git args. This is how we can tell
|
52
|
-
// if the top level release command was used or if the user is using the changelog subcommand.
|
53
|
-
// If the user explicitly overrides these args, then it doesn't matter if the top level config is set,
|
54
|
-
// as all of the git options would be overridden anyway.
|
55
|
-
if ((args.gitCommit === undefined ||
|
56
|
-
args.gitTag === undefined ||
|
57
|
-
args.stageChanges === undefined) &&
|
58
|
-
nxJson.release?.git) {
|
59
|
-
const nxJsonMessage = await (0, resolve_nx_json_error_message_1.resolveNxJsonConfigErrorMessage)([
|
60
|
-
'release',
|
61
|
-
'git',
|
62
|
-
]);
|
63
|
-
output_1.output.error({
|
64
|
-
title: `The "release.git" property in nx.json may not be used with the "nx release version" subcommand or programmatic API. Instead, configure git options for subcommands directly with "release.version.git" and "release.changelog.git".`,
|
65
|
-
bodyLines: [nxJsonMessage],
|
66
|
-
});
|
67
|
-
process.exit(1);
|
68
|
-
}
|
69
|
-
const { error: filterError, releaseGroups, releaseGroupToFilteredProjects, } = (0, filter_release_groups_1.filterReleaseGroups)(projectGraph, nxReleaseConfig, args.projects, args.groups);
|
70
|
-
if (filterError) {
|
71
|
-
output_1.output.error(filterError);
|
72
|
-
process.exit(1);
|
73
|
-
}
|
74
|
-
const rawVersionPlans = await (0, version_plans_1.readRawVersionPlans)();
|
75
|
-
(0, version_plans_1.setVersionPlansOnGroups)(rawVersionPlans, releaseGroups, Object.keys(projectGraph.nodes));
|
76
|
-
if (args.deleteVersionPlans === undefined) {
|
77
|
-
// default to not delete version plans after versioning as they may be needed for changelog generation
|
78
|
-
args.deleteVersionPlans = false;
|
79
|
-
}
|
80
|
-
runPreVersionCommand(nxReleaseConfig.version.preVersionCommand, {
|
81
|
-
dryRun: args.dryRun,
|
82
|
-
verbose: args.verbose,
|
83
|
-
});
|
84
|
-
const tree = new tree_1.FsTree(workspace_root_1.workspaceRoot, args.verbose);
|
85
|
-
const versionData = {};
|
86
|
-
const commitMessage = args.gitCommitMessage || nxReleaseConfig.version.git.commitMessage;
|
87
|
-
const generatorCallbacks = [];
|
36
|
+
function createAPI(overrideReleaseConfig) {
|
88
37
|
/**
|
89
|
-
*
|
90
|
-
*
|
38
|
+
* NOTE: This function is also exported for programmatic usage and forms part of the public API
|
39
|
+
* of Nx. We intentionally do not wrap the implementation with handleErrors because users need
|
40
|
+
* to have control over their own error handling when using the API.
|
91
41
|
*/
|
92
|
-
|
93
|
-
|
94
|
-
|
42
|
+
return async function releaseVersion(args) {
|
43
|
+
const projectGraph = await (0, project_graph_1.createProjectGraphAsync)({ exitOnError: true });
|
44
|
+
const { projects } = (0, project_graph_1.readProjectsConfigurationFromProjectGraph)(projectGraph);
|
45
|
+
const nxJson = (0, nx_json_1.readNxJson)();
|
46
|
+
const userProvidedReleaseConfig = (0, deep_merge_json_1.deepMergeJson)(nxJson.release ?? {}, overrideReleaseConfig ?? {});
|
47
|
+
if (args.verbose) {
|
48
|
+
process.env.NX_VERBOSE_LOGGING = 'true';
|
49
|
+
}
|
50
|
+
// Apply default configuration to any optional user configuration
|
51
|
+
const { error: configError, nxReleaseConfig } = await (0, config_1.createNxReleaseConfig)(projectGraph, await (0, file_map_utils_1.createProjectFileMapUsingProjectGraph)(projectGraph), userProvidedReleaseConfig);
|
52
|
+
if (configError) {
|
53
|
+
return await (0, config_1.handleNxReleaseConfigError)(configError);
|
54
|
+
}
|
55
|
+
// --print-config exits directly as it is not designed to be combined with any other programmatic operations
|
56
|
+
if (args.printConfig) {
|
57
|
+
return (0, print_config_1.printConfigAndExit)({
|
58
|
+
userProvidedReleaseConfig,
|
59
|
+
nxReleaseConfig,
|
60
|
+
isDebug: args.printConfig === 'debug',
|
61
|
+
});
|
62
|
+
}
|
63
|
+
// The nx release top level command will always override these three git args. This is how we can tell
|
64
|
+
// if the top level release command was used or if the user is using the changelog subcommand.
|
65
|
+
// If the user explicitly overrides these args, then it doesn't matter if the top level config is set,
|
66
|
+
// as all of the git options would be overridden anyway.
|
67
|
+
if ((args.gitCommit === undefined ||
|
68
|
+
args.gitTag === undefined ||
|
69
|
+
args.stageChanges === undefined) &&
|
70
|
+
userProvidedReleaseConfig.git) {
|
71
|
+
const nxJsonMessage = await (0, resolve_nx_json_error_message_1.resolveNxJsonConfigErrorMessage)([
|
72
|
+
'release',
|
73
|
+
'git',
|
74
|
+
]);
|
75
|
+
output_1.output.error({
|
76
|
+
title: `The "release.git" property in nx.json may not be used with the "nx release version" subcommand or programmatic API. Instead, configure git options for subcommands directly with "release.version.git" and "release.changelog.git".`,
|
77
|
+
bodyLines: [nxJsonMessage],
|
78
|
+
});
|
79
|
+
process.exit(1);
|
80
|
+
}
|
81
|
+
const { error: filterError, releaseGroups, releaseGroupToFilteredProjects, } = (0, filter_release_groups_1.filterReleaseGroups)(projectGraph, nxReleaseConfig, args.projects, args.groups);
|
82
|
+
if (filterError) {
|
83
|
+
output_1.output.error(filterError);
|
84
|
+
process.exit(1);
|
85
|
+
}
|
86
|
+
const rawVersionPlans = await (0, version_plans_1.readRawVersionPlans)();
|
87
|
+
(0, version_plans_1.setVersionPlansOnGroups)(rawVersionPlans, releaseGroups, Object.keys(projectGraph.nodes));
|
88
|
+
if (args.deleteVersionPlans === undefined) {
|
89
|
+
// default to not delete version plans after versioning as they may be needed for changelog generation
|
90
|
+
args.deleteVersionPlans = false;
|
91
|
+
}
|
92
|
+
runPreVersionCommand(nxReleaseConfig.version.preVersionCommand, {
|
93
|
+
dryRun: args.dryRun,
|
94
|
+
verbose: args.verbose,
|
95
|
+
});
|
96
|
+
const tree = new tree_1.FsTree(workspace_root_1.workspaceRoot, args.verbose);
|
97
|
+
const versionData = {};
|
98
|
+
const commitMessage = args.gitCommitMessage || nxReleaseConfig.version.git.commitMessage;
|
99
|
+
const generatorCallbacks = [];
|
100
|
+
/**
|
101
|
+
* additionalChangedFiles are files which need to be updated as a side-effect of versioning (such as package manager lock files),
|
102
|
+
* and need to get staged and committed as part of the existing commit, if applicable.
|
103
|
+
*/
|
104
|
+
const additionalChangedFiles = new Set();
|
105
|
+
const additionalDeletedFiles = new Set();
|
106
|
+
if (args.projects?.length) {
|
107
|
+
/**
|
108
|
+
* Run versioning for all remaining release groups and filtered projects within them
|
109
|
+
*/
|
110
|
+
for (const releaseGroup of releaseGroups) {
|
111
|
+
const releaseGroupName = releaseGroup.name;
|
112
|
+
const releaseGroupProjectNames = Array.from(releaseGroupToFilteredProjects.get(releaseGroup));
|
113
|
+
const projectBatches = (0, batch_projects_by_generator_config_1.batchProjectsByGeneratorConfig)(projectGraph, releaseGroup,
|
114
|
+
// Only batch based on the filtered projects within the release group
|
115
|
+
releaseGroupProjectNames);
|
116
|
+
for (const [generatorConfigString, projectNames,] of projectBatches.entries()) {
|
117
|
+
const [generatorName, generatorOptions] = JSON.parse(generatorConfigString);
|
118
|
+
// Resolve the generator for the batch and run versioning on the projects within the batch
|
119
|
+
const generatorData = resolveGeneratorData({
|
120
|
+
...extractGeneratorCollectionAndName(`batch "${JSON.stringify(projectNames)}" for release-group "${releaseGroupName}"`, generatorName),
|
121
|
+
configGeneratorOptions: generatorOptions,
|
122
|
+
// all project data from the project graph (not to be confused with projectNamesToRunVersionOn)
|
123
|
+
projects,
|
124
|
+
});
|
125
|
+
const generatorCallback = await runVersionOnProjects(projectGraph, nxJson, args, tree, generatorData, args.generatorOptionsOverrides, projectNames, releaseGroup, versionData, nxReleaseConfig.conventionalCommits);
|
126
|
+
// Capture the callback so that we can run it after flushing the changes to disk
|
127
|
+
generatorCallbacks.push(async () => {
|
128
|
+
const result = await generatorCallback(tree, {
|
129
|
+
dryRun: !!args.dryRun,
|
130
|
+
verbose: !!args.verbose,
|
131
|
+
generatorOptions: {
|
132
|
+
...generatorOptions,
|
133
|
+
...args.generatorOptionsOverrides,
|
134
|
+
},
|
135
|
+
});
|
136
|
+
const { changedFiles, deletedFiles } = parseGeneratorCallbackResult(result);
|
137
|
+
changedFiles.forEach((f) => additionalChangedFiles.add(f));
|
138
|
+
deletedFiles.forEach((f) => additionalDeletedFiles.add(f));
|
139
|
+
});
|
140
|
+
}
|
141
|
+
}
|
142
|
+
// 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
|
143
|
+
const gitTagValues = args.gitTag ?? nxReleaseConfig.version.git.tag
|
144
|
+
? (0, shared_1.createGitTagValues)(releaseGroups, releaseGroupToFilteredProjects, versionData)
|
145
|
+
: [];
|
146
|
+
(0, shared_1.handleDuplicateGitTags)(gitTagValues);
|
147
|
+
printAndFlushChanges(tree, !!args.dryRun);
|
148
|
+
for (const generatorCallback of generatorCallbacks) {
|
149
|
+
await generatorCallback();
|
150
|
+
}
|
151
|
+
const changedFiles = [
|
152
|
+
...tree.listChanges().map((f) => f.path),
|
153
|
+
...additionalChangedFiles,
|
154
|
+
];
|
155
|
+
// No further actions are necessary in this scenario (e.g. if conventional commits detected no changes)
|
156
|
+
if (!changedFiles.length) {
|
157
|
+
return {
|
158
|
+
// An overall workspace version cannot be relevant when filtering to independent projects
|
159
|
+
workspaceVersion: undefined,
|
160
|
+
projectsVersionData: versionData,
|
161
|
+
};
|
162
|
+
}
|
163
|
+
if (args.gitCommit ?? nxReleaseConfig.version.git.commit) {
|
164
|
+
await (0, shared_1.commitChanges)({
|
165
|
+
changedFiles,
|
166
|
+
deletedFiles: Array.from(additionalDeletedFiles),
|
167
|
+
isDryRun: !!args.dryRun,
|
168
|
+
isVerbose: !!args.verbose,
|
169
|
+
gitCommitMessages: (0, shared_1.createCommitMessageValues)(releaseGroups, releaseGroupToFilteredProjects, versionData, commitMessage),
|
170
|
+
gitCommitArgs: args.gitCommitArgs || nxReleaseConfig.version.git.commitArgs,
|
171
|
+
});
|
172
|
+
}
|
173
|
+
else if (args.stageChanges ??
|
174
|
+
nxReleaseConfig.version.git.stageChanges) {
|
175
|
+
output_1.output.logSingleLine(`Staging changed files with git`);
|
176
|
+
await (0, git_1.gitAdd)({
|
177
|
+
changedFiles,
|
178
|
+
dryRun: args.dryRun,
|
179
|
+
verbose: args.verbose,
|
180
|
+
});
|
181
|
+
}
|
182
|
+
if (args.gitTag ?? nxReleaseConfig.version.git.tag) {
|
183
|
+
output_1.output.logSingleLine(`Tagging commit with git`);
|
184
|
+
for (const tag of gitTagValues) {
|
185
|
+
await (0, git_1.gitTag)({
|
186
|
+
tag,
|
187
|
+
message: args.gitTagMessage || nxReleaseConfig.version.git.tagMessage,
|
188
|
+
additionalArgs: args.gitTagArgs || nxReleaseConfig.version.git.tagArgs,
|
189
|
+
dryRun: args.dryRun,
|
190
|
+
verbose: args.verbose,
|
191
|
+
});
|
192
|
+
}
|
193
|
+
}
|
194
|
+
return {
|
195
|
+
// An overall workspace version cannot be relevant when filtering to independent projects
|
196
|
+
workspaceVersion: undefined,
|
197
|
+
projectsVersionData: versionData,
|
198
|
+
};
|
199
|
+
}
|
95
200
|
/**
|
96
|
-
* Run versioning for all remaining release groups
|
201
|
+
* Run versioning for all remaining release groups
|
97
202
|
*/
|
98
203
|
for (const releaseGroup of releaseGroups) {
|
99
204
|
const releaseGroupName = releaseGroup.name;
|
100
|
-
const releaseGroupProjectNames = Array.from(releaseGroupToFilteredProjects.get(releaseGroup));
|
101
205
|
const projectBatches = (0, batch_projects_by_generator_config_1.batchProjectsByGeneratorConfig)(projectGraph, releaseGroup,
|
102
|
-
//
|
103
|
-
|
206
|
+
// Batch based on all projects within the release group
|
207
|
+
releaseGroup.projects);
|
104
208
|
for (const [generatorConfigString, projectNames,] of projectBatches.entries()) {
|
105
209
|
const [generatorName, generatorOptions] = JSON.parse(generatorConfigString);
|
106
210
|
// Resolve the generator for the batch and run versioning on the projects within the batch
|
@@ -136,6 +240,15 @@ async function releaseVersion(args) {
|
|
136
240
|
for (const generatorCallback of generatorCallbacks) {
|
137
241
|
await generatorCallback();
|
138
242
|
}
|
243
|
+
// Only applicable when there is a single release group with a fixed relationship
|
244
|
+
let workspaceVersion = undefined;
|
245
|
+
if (releaseGroups.length === 1) {
|
246
|
+
const releaseGroup = releaseGroups[0];
|
247
|
+
if (releaseGroup.projectsRelationship === 'fixed') {
|
248
|
+
const releaseGroupProjectNames = Array.from(releaseGroupToFilteredProjects.get(releaseGroup));
|
249
|
+
workspaceVersion = versionData[releaseGroupProjectNames[0]].newVersion; // all projects have the same version so we can just grab the first
|
250
|
+
}
|
251
|
+
}
|
139
252
|
const changedFiles = [
|
140
253
|
...tree.listChanges().map((f) => f.path),
|
141
254
|
...additionalChangedFiles,
|
@@ -144,8 +257,7 @@ async function releaseVersion(args) {
|
|
144
257
|
// No further actions are necessary in this scenario (e.g. if conventional commits detected no changes)
|
145
258
|
if (!changedFiles.length && !deletedFiles.length) {
|
146
259
|
return {
|
147
|
-
|
148
|
-
workspaceVersion: undefined,
|
260
|
+
workspaceVersion,
|
149
261
|
projectsVersionData: versionData,
|
150
262
|
};
|
151
263
|
}
|
@@ -180,108 +292,10 @@ async function releaseVersion(args) {
|
|
180
292
|
});
|
181
293
|
}
|
182
294
|
}
|
183
|
-
return {
|
184
|
-
// An overall workspace version cannot be relevant when filtering to independent projects
|
185
|
-
workspaceVersion: undefined,
|
186
|
-
projectsVersionData: versionData,
|
187
|
-
};
|
188
|
-
}
|
189
|
-
/**
|
190
|
-
* Run versioning for all remaining release groups
|
191
|
-
*/
|
192
|
-
for (const releaseGroup of releaseGroups) {
|
193
|
-
const releaseGroupName = releaseGroup.name;
|
194
|
-
const projectBatches = (0, batch_projects_by_generator_config_1.batchProjectsByGeneratorConfig)(projectGraph, releaseGroup,
|
195
|
-
// Batch based on all projects within the release group
|
196
|
-
releaseGroup.projects);
|
197
|
-
for (const [generatorConfigString, projectNames,] of projectBatches.entries()) {
|
198
|
-
const [generatorName, generatorOptions] = JSON.parse(generatorConfigString);
|
199
|
-
// Resolve the generator for the batch and run versioning on the projects within the batch
|
200
|
-
const generatorData = resolveGeneratorData({
|
201
|
-
...extractGeneratorCollectionAndName(`batch "${JSON.stringify(projectNames)}" for release-group "${releaseGroupName}"`, generatorName),
|
202
|
-
configGeneratorOptions: generatorOptions,
|
203
|
-
// all project data from the project graph (not to be confused with projectNamesToRunVersionOn)
|
204
|
-
projects,
|
205
|
-
});
|
206
|
-
const generatorCallback = await runVersionOnProjects(projectGraph, nxJson, args, tree, generatorData, args.generatorOptionsOverrides, projectNames, releaseGroup, versionData, nxReleaseConfig.conventionalCommits);
|
207
|
-
// Capture the callback so that we can run it after flushing the changes to disk
|
208
|
-
generatorCallbacks.push(async () => {
|
209
|
-
const result = await generatorCallback(tree, {
|
210
|
-
dryRun: !!args.dryRun,
|
211
|
-
verbose: !!args.verbose,
|
212
|
-
generatorOptions: {
|
213
|
-
...generatorOptions,
|
214
|
-
...args.generatorOptionsOverrides,
|
215
|
-
},
|
216
|
-
});
|
217
|
-
const { changedFiles, deletedFiles } = parseGeneratorCallbackResult(result);
|
218
|
-
changedFiles.forEach((f) => additionalChangedFiles.add(f));
|
219
|
-
deletedFiles.forEach((f) => additionalDeletedFiles.add(f));
|
220
|
-
});
|
221
|
-
}
|
222
|
-
}
|
223
|
-
// 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
|
224
|
-
const gitTagValues = args.gitTag ?? nxReleaseConfig.version.git.tag
|
225
|
-
? (0, shared_1.createGitTagValues)(releaseGroups, releaseGroupToFilteredProjects, versionData)
|
226
|
-
: [];
|
227
|
-
(0, shared_1.handleDuplicateGitTags)(gitTagValues);
|
228
|
-
printAndFlushChanges(tree, !!args.dryRun);
|
229
|
-
for (const generatorCallback of generatorCallbacks) {
|
230
|
-
await generatorCallback();
|
231
|
-
}
|
232
|
-
// Only applicable when there is a single release group with a fixed relationship
|
233
|
-
let workspaceVersion = undefined;
|
234
|
-
if (releaseGroups.length === 1) {
|
235
|
-
const releaseGroup = releaseGroups[0];
|
236
|
-
if (releaseGroup.projectsRelationship === 'fixed') {
|
237
|
-
const releaseGroupProjectNames = Array.from(releaseGroupToFilteredProjects.get(releaseGroup));
|
238
|
-
workspaceVersion = versionData[releaseGroupProjectNames[0]].newVersion; // all projects have the same version so we can just grab the first
|
239
|
-
}
|
240
|
-
}
|
241
|
-
const changedFiles = [
|
242
|
-
...tree.listChanges().map((f) => f.path),
|
243
|
-
...additionalChangedFiles,
|
244
|
-
];
|
245
|
-
// No further actions are necessary in this scenario (e.g. if conventional commits detected no changes)
|
246
|
-
if (!changedFiles.length) {
|
247
295
|
return {
|
248
296
|
workspaceVersion,
|
249
297
|
projectsVersionData: versionData,
|
250
298
|
};
|
251
|
-
}
|
252
|
-
if (args.gitCommit ?? nxReleaseConfig.version.git.commit) {
|
253
|
-
await (0, shared_1.commitChanges)({
|
254
|
-
changedFiles,
|
255
|
-
deletedFiles: Array.from(additionalDeletedFiles),
|
256
|
-
isDryRun: !!args.dryRun,
|
257
|
-
isVerbose: !!args.verbose,
|
258
|
-
gitCommitMessages: (0, shared_1.createCommitMessageValues)(releaseGroups, releaseGroupToFilteredProjects, versionData, commitMessage),
|
259
|
-
gitCommitArgs: args.gitCommitArgs || nxReleaseConfig.version.git.commitArgs,
|
260
|
-
});
|
261
|
-
}
|
262
|
-
else if (args.stageChanges ?? nxReleaseConfig.version.git.stageChanges) {
|
263
|
-
output_1.output.logSingleLine(`Staging changed files with git`);
|
264
|
-
await (0, git_1.gitAdd)({
|
265
|
-
changedFiles,
|
266
|
-
dryRun: args.dryRun,
|
267
|
-
verbose: args.verbose,
|
268
|
-
});
|
269
|
-
}
|
270
|
-
if (args.gitTag ?? nxReleaseConfig.version.git.tag) {
|
271
|
-
output_1.output.logSingleLine(`Tagging commit with git`);
|
272
|
-
for (const tag of gitTagValues) {
|
273
|
-
await (0, git_1.gitTag)({
|
274
|
-
tag,
|
275
|
-
message: args.gitTagMessage || nxReleaseConfig.version.git.tagMessage,
|
276
|
-
additionalArgs: args.gitTagArgs || nxReleaseConfig.version.git.tagArgs,
|
277
|
-
dryRun: args.dryRun,
|
278
|
-
verbose: args.verbose,
|
279
|
-
});
|
280
|
-
}
|
281
|
-
}
|
282
|
-
return {
|
283
|
-
workspaceVersion,
|
284
|
-
projectsVersionData: versionData,
|
285
299
|
};
|
286
300
|
}
|
287
301
|
function appendVersionData(existingVersionData, newVersionData) {
|
package/src/config/nx-json.d.ts
CHANGED
@@ -145,7 +145,7 @@ export interface NxReleaseConventionalCommitsConfiguration {
|
|
145
145
|
} | boolean;
|
146
146
|
} | boolean>;
|
147
147
|
}
|
148
|
-
interface NxReleaseConfiguration {
|
148
|
+
export interface NxReleaseConfiguration {
|
149
149
|
/**
|
150
150
|
* Shorthand for amending the projects which will be included in the implicit default release group (all projects by default).
|
151
151
|
* @note Only one of `projects` or `groups` can be specified, the cannot be used together.
|
@@ -379,6 +379,11 @@ export interface NxJsonConfiguration<T = '*' | string[]> {
|
|
379
379
|
* To use a different runner that accepts an access token, define it in {@link tasksRunnerOptions}
|
380
380
|
*/
|
381
381
|
nxCloudAccessToken?: string;
|
382
|
+
/**
|
383
|
+
* If specified Nx will use nx-cloud by default with the given cloud id.
|
384
|
+
* To use a different runner that accepts a cloud id, define it in {@link tasksRunnerOptions}
|
385
|
+
*/
|
386
|
+
nxCloudId?: string;
|
382
387
|
/**
|
383
388
|
* Specifies the url pointing to an instance of nx cloud. Used for remote
|
384
389
|
* caching and displaying run links.
|
@@ -8,8 +8,8 @@ export { getExecutorInformation } from './command-line/run/executor-utils';
|
|
8
8
|
export { readNxJson as readNxJsonFromDisk } from './config/nx-json';
|
9
9
|
export { calculateDefaultProjectName } from './config/calculate-default-project-name';
|
10
10
|
export { retrieveProjectConfigurationsWithAngularProjects } from './project-graph/utils/retrieve-workspace-files';
|
11
|
-
export { mergeTargetConfigurations
|
12
|
-
export { readProjectConfigurationsFromRootMap } from './project-graph/utils/project-configuration-utils';
|
11
|
+
export { mergeTargetConfigurations } from './project-graph/utils/project-configuration-utils';
|
12
|
+
export { readProjectConfigurationsFromRootMap, findMatchingConfigFiles, } from './project-graph/utils/project-configuration-utils';
|
13
13
|
export { splitTarget } from './utils/split-target';
|
14
14
|
export { combineOptionsForExecutor } from './utils/params';
|
15
15
|
export { sortObjectByKeys } from './utils/object-sort';
|
package/src/devkit-internals.js
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.interpolate = exports.registerTsProject = exports.LoadedNxPlugin = exports.retrieveProjectConfigurations = exports.findProjectForPath = exports.createProjectRootMappingsFromProjectConfigurations = exports.hashWithWorkspaceContext = exports.hashObject = exports.splitByColons = exports.readModulePackageJson = exports.stripIndent = exports.sortObjectByKeys = exports.combineOptionsForExecutor = exports.splitTarget = exports.
|
3
|
+
exports.interpolate = exports.registerTsProject = exports.LoadedNxPlugin = exports.retrieveProjectConfigurations = exports.findProjectForPath = exports.createProjectRootMappingsFromProjectConfigurations = exports.hashWithWorkspaceContext = exports.hashObject = exports.splitByColons = exports.readModulePackageJson = exports.stripIndent = exports.sortObjectByKeys = exports.combineOptionsForExecutor = exports.splitTarget = exports.findMatchingConfigFiles = exports.readProjectConfigurationsFromRootMap = exports.mergeTargetConfigurations = exports.retrieveProjectConfigurationsWithAngularProjects = exports.calculateDefaultProjectName = exports.readNxJsonFromDisk = exports.getExecutorInformation = exports.createTempNpmDirectory = void 0;
|
4
4
|
const tslib_1 = require("tslib");
|
5
5
|
/**
|
6
6
|
* Note to developers: STOP! These exports are available via requireNx in @nx/devkit.
|
@@ -19,9 +19,9 @@ var retrieve_workspace_files_1 = require("./project-graph/utils/retrieve-workspa
|
|
19
19
|
Object.defineProperty(exports, "retrieveProjectConfigurationsWithAngularProjects", { enumerable: true, get: function () { return retrieve_workspace_files_1.retrieveProjectConfigurationsWithAngularProjects; } });
|
20
20
|
var project_configuration_utils_1 = require("./project-graph/utils/project-configuration-utils");
|
21
21
|
Object.defineProperty(exports, "mergeTargetConfigurations", { enumerable: true, get: function () { return project_configuration_utils_1.mergeTargetConfigurations; } });
|
22
|
-
Object.defineProperty(exports, "findMatchingConfigFiles", { enumerable: true, get: function () { return project_configuration_utils_1.findMatchingConfigFiles; } });
|
23
22
|
var project_configuration_utils_2 = require("./project-graph/utils/project-configuration-utils");
|
24
23
|
Object.defineProperty(exports, "readProjectConfigurationsFromRootMap", { enumerable: true, get: function () { return project_configuration_utils_2.readProjectConfigurationsFromRootMap; } });
|
24
|
+
Object.defineProperty(exports, "findMatchingConfigFiles", { enumerable: true, get: function () { return project_configuration_utils_2.findMatchingConfigFiles; } });
|
25
25
|
var split_target_1 = require("./utils/split-target");
|
26
26
|
Object.defineProperty(exports, "splitTarget", { enumerable: true, get: function () { return split_target_1.splitTarget; } });
|
27
27
|
var params_1 = require("./utils/params");
|
Binary file
|
@@ -9,4 +9,5 @@ export interface ConnectToNxCloudOptions {
|
|
9
9
|
directory?: string;
|
10
10
|
}
|
11
11
|
export declare function connectToNxCloud(tree: Tree, schema: ConnectToNxCloudOptions, nxJson?: NxJsonConfiguration<string[] | "*">): Promise<string>;
|
12
|
-
|
12
|
+
declare function connectToNxCloudGenerator(tree: Tree, options: ConnectToNxCloudOptions): Promise<void>;
|
13
|
+
export default connectToNxCloudGenerator;
|
@@ -42,7 +42,7 @@ function getNxInitDate() {
|
|
42
42
|
return null;
|
43
43
|
}
|
44
44
|
}
|
45
|
-
async function
|
45
|
+
async function createNxCloudWorkspaceV1(workspaceName, installationSource, nxInitDate) {
|
46
46
|
const apiUrl = (0, get_cloud_options_1.getCloudUrl)();
|
47
47
|
const response = await require('axios').post(`${apiUrl}/nx-cloud/create-org-and-workspace`, {
|
48
48
|
workspaceName,
|
@@ -54,6 +54,18 @@ async function createNxCloudWorkspace(workspaceName, installationSource, nxInitD
|
|
54
54
|
}
|
55
55
|
return response.data;
|
56
56
|
}
|
57
|
+
async function createNxCloudWorkspaceV2(workspaceName, installationSource, nxInitDate) {
|
58
|
+
const apiUrl = (0, get_cloud_options_1.getCloudUrl)();
|
59
|
+
const response = await require('axios').post(`${apiUrl}/nx-cloud/v2/create-org-and-workspace`, {
|
60
|
+
workspaceName,
|
61
|
+
installationSource,
|
62
|
+
nxInitDate,
|
63
|
+
});
|
64
|
+
if (response.data.message) {
|
65
|
+
throw new Error(response.data.message);
|
66
|
+
}
|
67
|
+
return response.data;
|
68
|
+
}
|
57
69
|
async function printSuccessMessage(token, installationSource, usesGithub) {
|
58
70
|
const connectCloudUrl = await (0, url_shorten_1.createNxCloudOnboardingURL)(installationSource, token, usesGithub);
|
59
71
|
output_1.output.note({
|
@@ -69,7 +81,7 @@ async function printSuccessMessage(token, installationSource, usesGithub) {
|
|
69
81
|
});
|
70
82
|
return connectCloudUrl;
|
71
83
|
}
|
72
|
-
function addNxCloudOptionsToNxJson(tree, token, directory =
|
84
|
+
function addNxCloudOptionsToNxJson(tree, token, directory = '') {
|
73
85
|
const nxJsonPath = (0, path_1.join)(directory, 'nx.json');
|
74
86
|
if (tree.exists(nxJsonPath)) {
|
75
87
|
(0, json_1.updateJson)(tree, (0, path_1.join)(directory, 'nx.json'), (nxJson) => {
|
@@ -82,6 +94,19 @@ function addNxCloudOptionsToNxJson(tree, token, directory = tree.root) {
|
|
82
94
|
});
|
83
95
|
}
|
84
96
|
}
|
97
|
+
function addNxCloudIdToNxJson(tree, nxCloudId, directory = tree.root) {
|
98
|
+
const nxJsonPath = (0, path_1.join)(directory, 'nx.json');
|
99
|
+
if (tree.exists(nxJsonPath)) {
|
100
|
+
(0, json_1.updateJson)(tree, (0, path_1.join)(directory, 'nx.json'), (nxJson) => {
|
101
|
+
const overrideUrl = process.env.NX_CLOUD_API || process.env.NRWL_API;
|
102
|
+
if (overrideUrl) {
|
103
|
+
nxJson.nxCloudUrl = overrideUrl;
|
104
|
+
}
|
105
|
+
nxJson.nxCloudId = nxCloudId;
|
106
|
+
return nxJson;
|
107
|
+
});
|
108
|
+
}
|
109
|
+
}
|
85
110
|
async function connectToNxCloud(tree, schema, nxJson = (0, nx_json_1.readNxJson)(tree)) {
|
86
111
|
schema.installationSource ??= 'user';
|
87
112
|
if (nxJson?.neverConnectToCloud) {
|
@@ -90,17 +115,31 @@ async function connectToNxCloud(tree, schema, nxJson = (0, nx_json_1.readNxJson)
|
|
90
115
|
}
|
91
116
|
else {
|
92
117
|
const usesGithub = schema.github ?? (await (0, url_shorten_1.repoUsesGithub)(schema.github));
|
93
|
-
let
|
118
|
+
let responseFromCreateNxCloudWorkspaceV1;
|
119
|
+
let responseFromCreateNxCloudWorkspaceV2;
|
94
120
|
// do NOT create Nx Cloud token (createNxCloudWorkspace)
|
95
121
|
// if user is using github and is running nx-connect
|
96
122
|
if (!(usesGithub && schema.installationSource === 'nx-connect')) {
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
123
|
+
if (process.env.NX_ENABLE_LOGIN === 'true') {
|
124
|
+
responseFromCreateNxCloudWorkspaceV2 = await createNxCloudWorkspaceV2(getRootPackageName(tree), schema.installationSource, getNxInitDate());
|
125
|
+
addNxCloudIdToNxJson(tree, responseFromCreateNxCloudWorkspaceV2?.nxCloudId, schema.directory);
|
126
|
+
await (0, format_changed_files_with_prettier_if_available_1.formatChangedFilesWithPrettierIfAvailable)(tree, {
|
127
|
+
silent: schema.hideFormatLogs,
|
128
|
+
});
|
129
|
+
return responseFromCreateNxCloudWorkspaceV2.nxCloudId;
|
130
|
+
}
|
131
|
+
else {
|
132
|
+
responseFromCreateNxCloudWorkspaceV1 = await createNxCloudWorkspaceV1(getRootPackageName(tree), schema.installationSource, getNxInitDate());
|
133
|
+
addNxCloudOptionsToNxJson(tree, responseFromCreateNxCloudWorkspaceV1?.token, schema.directory);
|
134
|
+
await (0, format_changed_files_with_prettier_if_available_1.formatChangedFilesWithPrettierIfAvailable)(tree, {
|
135
|
+
silent: schema.hideFormatLogs,
|
136
|
+
});
|
137
|
+
return responseFromCreateNxCloudWorkspaceV1.token;
|
138
|
+
}
|
103
139
|
}
|
104
140
|
}
|
105
141
|
}
|
106
|
-
|
142
|
+
async function connectToNxCloudGenerator(tree, options) {
|
143
|
+
await connectToNxCloud(tree, options);
|
144
|
+
}
|
145
|
+
exports.default = connectToNxCloudGenerator;
|
@@ -8,8 +8,15 @@ function createApiAxiosInstance(options) {
|
|
8
8
|
let axiosConfigBuilder = (axiosConfig) => axiosConfig;
|
9
9
|
const baseUrl = process.env.NX_CLOUD_API || options.url || 'https://cloud.nx.app';
|
10
10
|
const accessToken = environment_1.ACCESS_TOKEN ? environment_1.ACCESS_TOKEN : options.accessToken;
|
11
|
-
|
12
|
-
|
11
|
+
const nxCloudId = options.nxCloudId;
|
12
|
+
// TODO(lourw): Update message with NxCloudId once it is supported
|
13
|
+
if (!accessToken && !nxCloudId) {
|
14
|
+
if (process.env.NX_ENABLE_LOGIN === 'true' && !nxCloudId) {
|
15
|
+
throw new Error(`Unable to authenticate. Please connect your workspace to Nx Cloud to define a valid Nx Cloud Id. If you are in a CI context, please set the NX_CLOUD_ACCESS_TOKEN environment variable or define an access token in your nx.json.`);
|
16
|
+
}
|
17
|
+
else {
|
18
|
+
throw new Error(`Unable to authenticate. Either define accessToken in nx.json or set the NX_CLOUD_ACCESS_TOKEN env variable. If you do not want to use Nx Cloud for this command, either set NX_NO_CLOUD=true, or pass the --no-cloud flag.`);
|
19
|
+
}
|
13
20
|
}
|
14
21
|
if (options.customProxyConfigPath) {
|
15
22
|
const { nxCloudProxyConfig } = require((0, path_1.join)(process.cwd(), options.customProxyConfigPath));
|
@@ -141,9 +141,14 @@ class TargetProjectLocator {
|
|
141
141
|
}
|
142
142
|
const version = (0, semver_1.clean)(externalPackageJson.version);
|
143
143
|
const npmProjectKey = `npm:${externalPackageJson.name}@${version}`;
|
144
|
-
|
144
|
+
let matchingExternalNode = this.npmProjects[npmProjectKey];
|
145
145
|
if (!matchingExternalNode) {
|
146
|
-
|
146
|
+
// check if it's a package alias, where the resolved package key is used as the version
|
147
|
+
const aliasNpmProjectKey = `npm:${packageName}@${npmProjectKey}`;
|
148
|
+
matchingExternalNode = this.npmProjects[aliasNpmProjectKey];
|
149
|
+
if (!matchingExternalNode) {
|
150
|
+
return null;
|
151
|
+
}
|
147
152
|
}
|
148
153
|
this.npmResolutionCache.set(npmImportForProject, matchingExternalNode.name);
|
149
154
|
return matchingExternalNode.name;
|
@@ -90,7 +90,15 @@ function buildProjectConfigurationFromPackageJson(packageJson, workspaceRoot, pa
|
|
90
90
|
const siblingProjectJson = tryReadJson((0, node_path_1.join)(workspaceRoot, projectRoot, 'project.json'));
|
91
91
|
if (siblingProjectJson) {
|
92
92
|
for (const target of Object.keys(siblingProjectJson?.targets ?? {})) {
|
93
|
-
|
93
|
+
const { executor, command, options } = siblingProjectJson.targets[target];
|
94
|
+
if (
|
95
|
+
// will use run-commands, different target
|
96
|
+
command ||
|
97
|
+
// Either uses a different executor or runs a different script
|
98
|
+
(executor &&
|
99
|
+
(executor !== 'nx:run-script' || options?.script !== target))) {
|
100
|
+
delete packageJson.scripts?.[target];
|
101
|
+
}
|
94
102
|
}
|
95
103
|
}
|
96
104
|
if (!packageJson.name && projectRoot === '.') {
|