nx 18.0.3 → 18.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/package.json +14 -13
- package/src/command-line/add/add.js +3 -1
- package/src/command-line/graph/graph.js +1 -1
- package/src/command-line/init/init-v2.js +16 -11
- package/src/command-line/migrate/command-object.js +17 -2
- package/src/command-line/migrate/migrate.js +13 -1
- package/src/command-line/release/changelog.d.ts +16 -1
- package/src/command-line/release/changelog.js +104 -198
- package/src/command-line/release/command-object.d.ts +1 -0
- package/src/command-line/release/command-object.js +31 -12
- package/src/command-line/release/publish.js +8 -11
- package/src/command-line/release/release.js +57 -6
- package/src/command-line/release/utils/git.d.ts +5 -1
- package/src/command-line/release/utils/git.js +26 -11
- package/src/command-line/release/utils/github.d.ts +4 -8
- package/src/command-line/release/utils/github.js +102 -34
- package/src/command-line/release/utils/shared.d.ts +1 -0
- package/src/command-line/release/utils/shared.js +3 -1
- package/src/command-line/release/version.js +0 -6
- package/src/core/graph/3rdpartylicenses.txt +0 -51
- package/src/core/graph/main.js +1 -1
- package/src/core/graph/polyfills.js +1 -1
- package/src/core/graph/runtime.js +1 -1
- package/src/core/graph/styles.js +1 -1
- package/src/executors/run-commands/run-commands.impl.js +3 -3
- package/src/migrations/update-17-0-0/rm-default-collection-npm-scope.js +3 -3
- package/src/plugins/js/utils/register.d.ts +4 -8
- package/src/plugins/js/utils/register.js +8 -22
- package/src/plugins/target-defaults/target-defaults-plugin.d.ts +2 -3
- package/src/plugins/target-defaults/target-defaults-plugin.js +24 -32
- package/src/project-graph/utils/project-configuration-utils.js +13 -6
- package/src/tasks-runner/life-cycles/dynamic-run-many-terminal-output-life-cycle.js +20 -23
- package/src/tasks-runner/life-cycles/dynamic-run-one-terminal-output-life-cycle.js +16 -16
- package/src/tasks-runner/life-cycles/static-run-many-terminal-output-life-cycle.js +1 -1
- 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 +10 -2
- package/src/tasks-runner/life-cycles/view-logs-utils.js +1 -1
- package/src/tasks-runner/task-orchestrator.js +23 -1
- package/src/utils/json.js +3 -1
- package/src/utils/logger.js +1 -1
- package/src/utils/output.d.ts +0 -1
- package/src/utils/output.js +6 -7
- package/src/utils/package-json.d.ts +1 -1
- package/src/utils/package-json.js +12 -11
- package/src/utils/plugins/core-plugins.js +4 -0
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.yargsReleaseCommand = void 0;
|
|
4
4
|
const yargs_1 = require("yargs");
|
|
5
5
|
const file_utils_1 = require("../../project-graph/file-utils");
|
|
6
|
+
const logger_1 = require("../../utils/logger");
|
|
6
7
|
const shared_options_1 = require("../yargs-utils/shared-options");
|
|
7
8
|
exports.yargsReleaseCommand = {
|
|
8
9
|
command: 'release',
|
|
@@ -83,13 +84,17 @@ const releaseCommand = {
|
|
|
83
84
|
}
|
|
84
85
|
return true;
|
|
85
86
|
}),
|
|
86
|
-
handler: (args) =>
|
|
87
|
-
.then((
|
|
88
|
-
|
|
89
|
-
|
|
87
|
+
handler: async (args) => {
|
|
88
|
+
const release = await Promise.resolve().then(() => require('./release'));
|
|
89
|
+
const result = await release.releaseCLIHandler(args);
|
|
90
|
+
if (args.dryRun) {
|
|
91
|
+
logger_1.logger.warn(`\nNOTE: The "dryRun" flag means no changes were made.`);
|
|
92
|
+
}
|
|
93
|
+
if (typeof result === 'number') {
|
|
94
|
+
process.exit(result);
|
|
90
95
|
}
|
|
91
96
|
process.exit(0);
|
|
92
|
-
}
|
|
97
|
+
},
|
|
93
98
|
};
|
|
94
99
|
const versionCommand = {
|
|
95
100
|
command: 'version [specifier]',
|
|
@@ -109,13 +114,17 @@ const versionCommand = {
|
|
|
109
114
|
type: 'boolean',
|
|
110
115
|
describe: 'Whether or not to stage the changes made by this command. Useful when combining this command with changelog generation.',
|
|
111
116
|
})),
|
|
112
|
-
handler: (args) =>
|
|
113
|
-
.then((
|
|
114
|
-
|
|
115
|
-
|
|
117
|
+
handler: async (args) => {
|
|
118
|
+
const release = await Promise.resolve().then(() => require('./version'));
|
|
119
|
+
const result = await release.releaseVersionCLIHandler(args);
|
|
120
|
+
if (args.dryRun) {
|
|
121
|
+
logger_1.logger.warn(`\nNOTE: The "dryRun" flag means no changes were made.`);
|
|
122
|
+
}
|
|
123
|
+
if (typeof result === 'number') {
|
|
124
|
+
process.exit(result);
|
|
116
125
|
}
|
|
117
126
|
process.exit(0);
|
|
118
|
-
}
|
|
127
|
+
},
|
|
119
128
|
};
|
|
120
129
|
const changelogCommand = {
|
|
121
130
|
command: 'changelog [version]',
|
|
@@ -155,8 +164,15 @@ const changelogCommand = {
|
|
|
155
164
|
return true;
|
|
156
165
|
})),
|
|
157
166
|
handler: async (args) => {
|
|
158
|
-
const
|
|
159
|
-
|
|
167
|
+
const release = await Promise.resolve().then(() => require('./changelog'));
|
|
168
|
+
const result = await release.releaseChangelogCLIHandler(args);
|
|
169
|
+
if (args.dryRun) {
|
|
170
|
+
logger_1.logger.warn(`\nNOTE: The "dryRun" flag means no changes were made.`);
|
|
171
|
+
}
|
|
172
|
+
if (typeof result === 'number') {
|
|
173
|
+
process.exit(result);
|
|
174
|
+
}
|
|
175
|
+
process.exit(0);
|
|
160
176
|
},
|
|
161
177
|
};
|
|
162
178
|
const publishCommand = {
|
|
@@ -178,6 +194,9 @@ const publishCommand = {
|
|
|
178
194
|
}),
|
|
179
195
|
handler: async (args) => {
|
|
180
196
|
const status = await (await Promise.resolve().then(() => require('./publish'))).releasePublishCLIHandler(coerceParallelOption((0, shared_options_1.withOverrides)(args, 2)));
|
|
197
|
+
if (args.dryRun) {
|
|
198
|
+
logger_1.logger.warn(`\nNOTE: The "dryRun" flag means no changes were made.`);
|
|
199
|
+
}
|
|
181
200
|
process.exit(status);
|
|
182
201
|
},
|
|
183
202
|
};
|
|
@@ -6,7 +6,6 @@ const devkit_exports_1 = require("../../devkit-exports");
|
|
|
6
6
|
const project_graph_1 = require("../../project-graph/project-graph");
|
|
7
7
|
const run_command_1 = require("../../tasks-runner/run-command");
|
|
8
8
|
const command_line_utils_1 = require("../../utils/command-line-utils");
|
|
9
|
-
const logger_1 = require("../../utils/logger");
|
|
10
9
|
const params_1 = require("../../utils/params");
|
|
11
10
|
const project_graph_utils_1 = require("../../utils/project-graph-utils");
|
|
12
11
|
const graph_1 = require("../graph/graph");
|
|
@@ -70,9 +69,6 @@ async function releasePublish(args, isCLI = false) {
|
|
|
70
69
|
overallExitStatus = status || 1;
|
|
71
70
|
}
|
|
72
71
|
}
|
|
73
|
-
if (_args.dryRun) {
|
|
74
|
-
logger_1.logger.warn(`\nNOTE: The "dryRun" flag means no projects were actually published.`);
|
|
75
|
-
}
|
|
76
72
|
return overallExitStatus;
|
|
77
73
|
}
|
|
78
74
|
exports.releasePublish = releasePublish;
|
|
@@ -102,22 +98,23 @@ async function runPublishOnProjects(args, projectGraph, nxJson, projectNames, sh
|
|
|
102
98
|
if (args.firstRelease) {
|
|
103
99
|
overrides.firstRelease = args.firstRelease;
|
|
104
100
|
}
|
|
105
|
-
const
|
|
101
|
+
const requiredTargetName = 'nx-release-publish';
|
|
106
102
|
if (args.graph) {
|
|
107
103
|
const file = (0, command_line_utils_1.readGraphFileFromGraphArg)(args);
|
|
108
|
-
const
|
|
104
|
+
const projectNamesWithTarget = projectsToRun
|
|
105
|
+
.map((t) => t.name)
|
|
106
|
+
.filter((projectName) => (0, project_graph_utils_1.projectHasTarget)(projectGraph.nodes[projectName], requiredTargetName));
|
|
109
107
|
await (0, graph_1.generateGraph)({
|
|
110
108
|
watch: false,
|
|
111
109
|
all: false,
|
|
112
110
|
open: true,
|
|
113
111
|
view: 'tasks',
|
|
114
|
-
targets,
|
|
115
|
-
projects:
|
|
112
|
+
targets: [requiredTargetName],
|
|
113
|
+
projects: projectNamesWithTarget,
|
|
116
114
|
file,
|
|
117
|
-
},
|
|
115
|
+
}, projectNamesWithTarget);
|
|
118
116
|
return 0;
|
|
119
117
|
}
|
|
120
|
-
const requiredTargetName = 'nx-release-publish';
|
|
121
118
|
const projectsWithTarget = projectsToRun.filter((project) => (0, project_graph_utils_1.projectHasTarget)(project, requiredTargetName));
|
|
122
119
|
if (projectsWithTarget.length === 0) {
|
|
123
120
|
throw new Error(`Based on your config, the following projects were matched for publishing but do not have the "${requiredTargetName}" target specified:\n${[
|
|
@@ -130,7 +127,7 @@ async function runPublishOnProjects(args, projectGraph, nxJson, projectNames, sh
|
|
|
130
127
|
* Run the relevant nx-release-publish executor on each of the selected projects.
|
|
131
128
|
*/
|
|
132
129
|
const status = await (0, run_command_1.runCommand)(projectsWithTarget, projectGraph, { nxJson }, {
|
|
133
|
-
targets,
|
|
130
|
+
targets: [requiredTargetName],
|
|
134
131
|
outputStyle: 'static',
|
|
135
132
|
...args,
|
|
136
133
|
}, overrides, null, {}, {
|
|
@@ -11,6 +11,7 @@ const config_1 = require("./config/config");
|
|
|
11
11
|
const filter_release_groups_1 = require("./config/filter-release-groups");
|
|
12
12
|
const publish_1 = require("./publish");
|
|
13
13
|
const git_1 = require("./utils/git");
|
|
14
|
+
const github_1 = require("./utils/github");
|
|
14
15
|
const resolve_nx_json_error_message_1 = require("./utils/resolve-nx-json-error-message");
|
|
15
16
|
const shared_1 = require("./utils/shared");
|
|
16
17
|
const version_1 = require("./version");
|
|
@@ -51,13 +52,14 @@ async function release(args) {
|
|
|
51
52
|
gitCommit: false,
|
|
52
53
|
gitTag: false,
|
|
53
54
|
});
|
|
54
|
-
await (0, changelog_1.releaseChangelog)({
|
|
55
|
+
const changelogResult = await (0, changelog_1.releaseChangelog)({
|
|
55
56
|
...args,
|
|
56
57
|
versionData: versionResult.projectsVersionData,
|
|
57
58
|
version: versionResult.workspaceVersion,
|
|
58
59
|
stageChanges: shouldStage,
|
|
59
60
|
gitCommit: false,
|
|
60
61
|
gitTag: false,
|
|
62
|
+
createRelease: false,
|
|
61
63
|
});
|
|
62
64
|
const { error: filterError, releaseGroups, releaseGroupToFilteredProjects, } = (0, filter_release_groups_1.filterReleaseGroups)(projectGraph, nxReleaseConfig, args.projects, args.groups);
|
|
63
65
|
if (filterError) {
|
|
@@ -90,8 +92,59 @@ async function release(args) {
|
|
|
90
92
|
});
|
|
91
93
|
}
|
|
92
94
|
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
+
const shouldCreateWorkspaceRelease = (0, changelog_1.shouldCreateGitHubRelease)(nxReleaseConfig.changelog.workspaceChangelog);
|
|
96
|
+
let hasPushedChanges = false;
|
|
97
|
+
let latestCommit;
|
|
98
|
+
if (shouldCreateWorkspaceRelease && changelogResult.workspaceChangelog) {
|
|
99
|
+
devkit_exports_1.output.logSingleLine(`Pushing to git remote`);
|
|
100
|
+
// Before we can create/update the release we need to ensure the commit exists on the remote
|
|
101
|
+
await (0, git_1.gitPush)({
|
|
102
|
+
dryRun: args.dryRun,
|
|
103
|
+
verbose: args.verbose,
|
|
104
|
+
});
|
|
105
|
+
hasPushedChanges = true;
|
|
106
|
+
devkit_exports_1.output.logSingleLine(`Creating GitHub Release`);
|
|
107
|
+
latestCommit = await (0, git_1.getCommitHash)('HEAD');
|
|
108
|
+
await (0, github_1.createOrUpdateGithubRelease)(changelogResult.workspaceChangelog.releaseVersion, changelogResult.workspaceChangelog.contents, latestCommit, { dryRun: args.dryRun });
|
|
109
|
+
}
|
|
110
|
+
for (const releaseGroup of releaseGroups) {
|
|
111
|
+
const shouldCreateProjectReleases = (0, changelog_1.shouldCreateGitHubRelease)(releaseGroup.changelog);
|
|
112
|
+
if (shouldCreateProjectReleases && changelogResult.projectChangelogs) {
|
|
113
|
+
const projects = args.projects?.length
|
|
114
|
+
? // If the user has passed a list of projects, we need to use the filtered list of projects within the release group
|
|
115
|
+
Array.from(releaseGroupToFilteredProjects.get(releaseGroup))
|
|
116
|
+
: // Otherwise, we use the full list of projects within the release group
|
|
117
|
+
releaseGroup.projects;
|
|
118
|
+
const projectNodes = projects.map((name) => projectGraph.nodes[name]);
|
|
119
|
+
for (const project of projectNodes) {
|
|
120
|
+
const changelog = changelogResult.projectChangelogs[project.name];
|
|
121
|
+
if (!changelog) {
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
if (!hasPushedChanges) {
|
|
125
|
+
devkit_exports_1.output.logSingleLine(`Pushing to git remote`);
|
|
126
|
+
// Before we can create/update the release we need to ensure the commit exists on the remote
|
|
127
|
+
await (0, git_1.gitPush)({
|
|
128
|
+
dryRun: args.dryRun,
|
|
129
|
+
verbose: args.verbose,
|
|
130
|
+
});
|
|
131
|
+
hasPushedChanges = true;
|
|
132
|
+
}
|
|
133
|
+
devkit_exports_1.output.logSingleLine(`Creating GitHub Release`);
|
|
134
|
+
if (!latestCommit) {
|
|
135
|
+
latestCommit = await (0, git_1.getCommitHash)('HEAD');
|
|
136
|
+
}
|
|
137
|
+
await (0, github_1.createOrUpdateGithubRelease)(changelog.releaseVersion, changelog.contents, latestCommit, { dryRun: args.dryRun });
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
let hasNewVersion = false;
|
|
142
|
+
// null means that all projects are versioned together but there were no changes
|
|
143
|
+
if (versionResult.workspaceVersion !== null) {
|
|
144
|
+
hasNewVersion = Object.values(versionResult.projectsVersionData).some((version) => version.newVersion !== null);
|
|
145
|
+
}
|
|
146
|
+
let shouldPublish = !!args.yes && !args.skipPublish && hasNewVersion;
|
|
147
|
+
const shouldPromptPublishing = !args.yes && !args.skipPublish && !args.dryRun && hasNewVersion;
|
|
95
148
|
if (shouldPromptPublishing) {
|
|
96
149
|
shouldPublish = await promptForPublish();
|
|
97
150
|
}
|
|
@@ -99,13 +152,12 @@ async function release(args) {
|
|
|
99
152
|
await (0, publish_1.releasePublish)(args);
|
|
100
153
|
}
|
|
101
154
|
else {
|
|
102
|
-
|
|
155
|
+
devkit_exports_1.output.logSingleLine('Skipped publishing packages.');
|
|
103
156
|
}
|
|
104
157
|
return versionResult;
|
|
105
158
|
}
|
|
106
159
|
exports.release = release;
|
|
107
160
|
async function promptForPublish() {
|
|
108
|
-
console.log('\n');
|
|
109
161
|
try {
|
|
110
162
|
const reply = await (0, enquirer_1.prompt)([
|
|
111
163
|
{
|
|
@@ -117,7 +169,6 @@ async function promptForPublish() {
|
|
|
117
169
|
return reply.confirmation;
|
|
118
170
|
}
|
|
119
171
|
catch (e) {
|
|
120
|
-
console.log('\n');
|
|
121
172
|
// Handle the case where the user exits the prompt with ctrl+c
|
|
122
173
|
return false;
|
|
123
174
|
}
|
|
@@ -48,7 +48,11 @@ export declare function gitTag({ tag, message, additionalArgs, dryRun, verbose,
|
|
|
48
48
|
verbose?: boolean;
|
|
49
49
|
logFn?: (message: string) => void;
|
|
50
50
|
}): Promise<string>;
|
|
51
|
-
export declare function gitPush(gitRemote
|
|
51
|
+
export declare function gitPush({ gitRemote, dryRun, verbose, }: {
|
|
52
|
+
gitRemote?: string;
|
|
53
|
+
dryRun?: boolean;
|
|
54
|
+
verbose?: boolean;
|
|
55
|
+
}): Promise<void>;
|
|
52
56
|
export declare function parseCommits(commits: RawGitCommit[]): GitCommit[];
|
|
53
57
|
export declare function parseGitCommit(commit: RawGitCommit): GitCommit | null;
|
|
54
58
|
export declare function getCommitHash(ref: string): Promise<string>;
|
|
@@ -155,17 +155,27 @@ async function gitTag({ tag, message, additionalArgs, dryRun, verbose, logFn, })
|
|
|
155
155
|
}
|
|
156
156
|
}
|
|
157
157
|
exports.gitTag = gitTag;
|
|
158
|
-
async function gitPush(gitRemote) {
|
|
158
|
+
async function gitPush({ gitRemote, dryRun, verbose, }) {
|
|
159
|
+
const commandArgs = [
|
|
160
|
+
'push',
|
|
161
|
+
// NOTE: It's important we use --follow-tags, and not --tags, so that we are precise about what we are pushing
|
|
162
|
+
'--follow-tags',
|
|
163
|
+
'--no-verify',
|
|
164
|
+
'--atomic',
|
|
165
|
+
// Set custom git remote if provided
|
|
166
|
+
...(gitRemote ? [gitRemote] : []),
|
|
167
|
+
];
|
|
168
|
+
if (verbose) {
|
|
169
|
+
console.log(dryRun
|
|
170
|
+
? `Would push the current branch to the remote with the following command, but --dry-run was set:`
|
|
171
|
+
: `Pushing the current branch to the remote with the following command:`);
|
|
172
|
+
console.log(`git ${commandArgs.join(' ')}`);
|
|
173
|
+
}
|
|
174
|
+
if (dryRun) {
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
159
177
|
try {
|
|
160
|
-
await (0, exec_command_1.execCommand)('git',
|
|
161
|
-
'push',
|
|
162
|
-
// NOTE: It's important we use --follow-tags, and not --tags, so that we are precise about what we are pushing
|
|
163
|
-
'--follow-tags',
|
|
164
|
-
'--no-verify',
|
|
165
|
-
'--atomic',
|
|
166
|
-
// Set custom git remote if provided
|
|
167
|
-
...(gitRemote ? [gitRemote] : []),
|
|
168
|
-
]);
|
|
178
|
+
await (0, exec_command_1.execCommand)('git', commandArgs);
|
|
169
179
|
}
|
|
170
180
|
catch (err) {
|
|
171
181
|
throw new Error(`Unexpected git push error: ${err}`);
|
|
@@ -252,7 +262,12 @@ async function getCommitHash(ref) {
|
|
|
252
262
|
exports.getCommitHash = getCommitHash;
|
|
253
263
|
async function getFirstGitCommit() {
|
|
254
264
|
try {
|
|
255
|
-
return (await (0, exec_command_1.execCommand)('git', [
|
|
265
|
+
return (await (0, exec_command_1.execCommand)('git', [
|
|
266
|
+
'rev-list',
|
|
267
|
+
'--max-parents=0',
|
|
268
|
+
'HEAD',
|
|
269
|
+
'--first-parent',
|
|
270
|
+
])).trim();
|
|
256
271
|
}
|
|
257
272
|
catch (e) {
|
|
258
273
|
throw new Error(`Unable to find first commit in git history`);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Reference } from './git';
|
|
2
|
+
import { ReleaseVersion } from './shared';
|
|
2
3
|
export type RepoSlug = `${string}/${string}`;
|
|
3
4
|
export interface GithubRequestConfig {
|
|
4
5
|
repo: string;
|
|
@@ -14,14 +15,9 @@ export interface GithubRelease {
|
|
|
14
15
|
prerelease?: boolean;
|
|
15
16
|
}
|
|
16
17
|
export declare function getGitHubRepoSlug(remoteName?: string): RepoSlug;
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
prerelease: boolean;
|
|
21
|
-
commit: string;
|
|
22
|
-
}
|
|
23
|
-
export declare function createOrUpdateGithubRelease(githubRequestConfig: GithubRequestConfig, release: GithubReleaseOptions, existingGithubReleaseForVersion?: GithubRelease): Promise<void>;
|
|
18
|
+
export declare function createOrUpdateGithubRelease(releaseVersion: ReleaseVersion, changelogContents: string, latestCommit: string, { dryRun }: {
|
|
19
|
+
dryRun: boolean;
|
|
20
|
+
}): Promise<void>;
|
|
24
21
|
export declare function resolveGithubToken(): Promise<string | null>;
|
|
25
22
|
export declare function getGithubReleaseByTag(config: GithubRequestConfig, tag: string): Promise<GithubRelease>;
|
|
26
23
|
export declare function formatReferences(references: Reference[], repoSlug: RepoSlug): string;
|
|
27
|
-
export {};
|
|
@@ -8,6 +8,8 @@ const node_fs_1 = require("node:fs");
|
|
|
8
8
|
const node_os_1 = require("node:os");
|
|
9
9
|
const output_1 = require("../../../utils/output");
|
|
10
10
|
const path_1 = require("../../../utils/path");
|
|
11
|
+
const print_changes_1 = require("./print-changes");
|
|
12
|
+
const shared_1 = require("./shared");
|
|
11
13
|
// axios types and values don't seem to match
|
|
12
14
|
const _axios = require("axios");
|
|
13
15
|
const axios = _axios;
|
|
@@ -32,7 +34,65 @@ function getGitHubRepoSlug(remoteName = 'origin') {
|
|
|
32
34
|
}
|
|
33
35
|
}
|
|
34
36
|
exports.getGitHubRepoSlug = getGitHubRepoSlug;
|
|
35
|
-
async function createOrUpdateGithubRelease(
|
|
37
|
+
async function createOrUpdateGithubRelease(releaseVersion, changelogContents, latestCommit, { dryRun }) {
|
|
38
|
+
const githubRepoSlug = getGitHubRepoSlug();
|
|
39
|
+
if (!githubRepoSlug) {
|
|
40
|
+
output_1.output.error({
|
|
41
|
+
title: `Unable to create a GitHub release because the GitHub repo slug could not be determined.`,
|
|
42
|
+
bodyLines: [
|
|
43
|
+
`Please ensure you have a valid GitHub remote configured. You can run \`git remote -v\` to list your current remotes.`,
|
|
44
|
+
],
|
|
45
|
+
});
|
|
46
|
+
process.exit(1);
|
|
47
|
+
}
|
|
48
|
+
const token = await resolveGithubToken();
|
|
49
|
+
const githubRequestConfig = {
|
|
50
|
+
repo: githubRepoSlug,
|
|
51
|
+
token,
|
|
52
|
+
};
|
|
53
|
+
let existingGithubReleaseForVersion;
|
|
54
|
+
try {
|
|
55
|
+
existingGithubReleaseForVersion = await getGithubReleaseByTag(githubRequestConfig, releaseVersion.gitTag);
|
|
56
|
+
}
|
|
57
|
+
catch (err) {
|
|
58
|
+
if (err.response?.status === 401) {
|
|
59
|
+
output_1.output.error({
|
|
60
|
+
title: `Unable to resolve data via the GitHub API. You can use any of the following options to resolve this:`,
|
|
61
|
+
bodyLines: [
|
|
62
|
+
'- Set the `GITHUB_TOKEN` or `GH_TOKEN` environment variable to a valid GitHub token with `repo` scope',
|
|
63
|
+
'- Have an active session via the official gh CLI tool (https://cli.github.com) in your current terminal',
|
|
64
|
+
],
|
|
65
|
+
});
|
|
66
|
+
process.exit(1);
|
|
67
|
+
}
|
|
68
|
+
if (err.response?.status === 404) {
|
|
69
|
+
// No existing release found, this is fine
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
// Rethrow unknown errors for now
|
|
73
|
+
throw err;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
const logTitle = `https://github.com/${githubRepoSlug}/releases/tag/${releaseVersion.gitTag}`;
|
|
77
|
+
if (existingGithubReleaseForVersion) {
|
|
78
|
+
console.error(`${chalk.white('UPDATE')} ${logTitle}${dryRun ? chalk.keyword('orange')(' [dry-run]') : ''}`);
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
console.error(`${chalk.green('CREATE')} ${logTitle}${dryRun ? chalk.keyword('orange')(' [dry-run]') : ''}`);
|
|
82
|
+
}
|
|
83
|
+
console.log('');
|
|
84
|
+
(0, print_changes_1.printDiff)(existingGithubReleaseForVersion ? existingGithubReleaseForVersion.body : '', changelogContents, 3, shared_1.noDiffInChangelogMessage);
|
|
85
|
+
if (!dryRun) {
|
|
86
|
+
await createOrUpdateGithubReleaseInternal(githubRequestConfig, {
|
|
87
|
+
version: releaseVersion.gitTag,
|
|
88
|
+
prerelease: releaseVersion.isPrerelease,
|
|
89
|
+
body: changelogContents,
|
|
90
|
+
commit: latestCommit,
|
|
91
|
+
}, existingGithubReleaseForVersion);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
exports.createOrUpdateGithubRelease = createOrUpdateGithubRelease;
|
|
95
|
+
async function createOrUpdateGithubReleaseInternal(githubRequestConfig, release, existingGithubReleaseForVersion) {
|
|
36
96
|
const result = await syncGithubRelease(githubRequestConfig, release, existingGithubReleaseForVersion);
|
|
37
97
|
/**
|
|
38
98
|
* If something went wrong POSTing to Github we can still pre-populate the web form on github.com
|
|
@@ -60,39 +120,22 @@ async function createOrUpdateGithubRelease(githubRequestConfig, release, existin
|
|
|
60
120
|
console.error(`An unknown error occurred while trying to create a release on GitHub, please report this on https://github.com/nrwl/nx (NOTE: make sure to redact your GitHub token from the error message!)`);
|
|
61
121
|
}
|
|
62
122
|
}
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
message: 'Do you want to finish creating the release manually in your browser?',
|
|
67
|
-
type: 'autocomplete',
|
|
68
|
-
choices: [
|
|
69
|
-
{
|
|
70
|
-
name: 'Yes',
|
|
71
|
-
hint: 'It will pre-populate the form for you',
|
|
72
|
-
},
|
|
73
|
-
{
|
|
74
|
-
name: 'No',
|
|
75
|
-
},
|
|
76
|
-
],
|
|
77
|
-
initial: 0,
|
|
78
|
-
},
|
|
79
|
-
]).catch(() => {
|
|
80
|
-
return { open: 'No' };
|
|
81
|
-
});
|
|
82
|
-
if (reply.open === 'Yes') {
|
|
83
|
-
const open = require('open');
|
|
84
|
-
await open(result.url)
|
|
85
|
-
.then(() => {
|
|
86
|
-
console.info(`\nFollow up in the browser to manually create the release:\n\n` +
|
|
87
|
-
chalk.underline(chalk.cyan(result.url)) +
|
|
88
|
-
`\n`);
|
|
89
|
-
})
|
|
90
|
-
.catch(() => {
|
|
91
|
-
console.info(`Open this link to manually create a release: \n` +
|
|
92
|
-
chalk.underline(chalk.cyan(result.url)) +
|
|
93
|
-
'\n');
|
|
94
|
-
});
|
|
123
|
+
const shouldContinueInGitHub = await promptForContinueInGitHub();
|
|
124
|
+
if (!shouldContinueInGitHub) {
|
|
125
|
+
return;
|
|
95
126
|
}
|
|
127
|
+
const open = require('open');
|
|
128
|
+
await open(result.url)
|
|
129
|
+
.then(() => {
|
|
130
|
+
console.info(`\nFollow up in the browser to manually create the release:\n\n` +
|
|
131
|
+
chalk.underline(chalk.cyan(result.url)) +
|
|
132
|
+
`\n`);
|
|
133
|
+
})
|
|
134
|
+
.catch(() => {
|
|
135
|
+
console.info(`Open this link to manually create a release: \n` +
|
|
136
|
+
chalk.underline(chalk.cyan(result.url)) +
|
|
137
|
+
'\n');
|
|
138
|
+
});
|
|
96
139
|
}
|
|
97
140
|
/**
|
|
98
141
|
* If something went wrong POSTing to Github we can still pre-populate the web form on github.com
|
|
@@ -115,7 +158,32 @@ async function createOrUpdateGithubRelease(githubRequestConfig, release, existin
|
|
|
115
158
|
});
|
|
116
159
|
}
|
|
117
160
|
}
|
|
118
|
-
|
|
161
|
+
async function promptForContinueInGitHub() {
|
|
162
|
+
try {
|
|
163
|
+
const reply = await (0, enquirer_1.prompt)([
|
|
164
|
+
{
|
|
165
|
+
name: 'open',
|
|
166
|
+
message: 'Do you want to finish creating the release manually in your browser?',
|
|
167
|
+
type: 'autocomplete',
|
|
168
|
+
choices: [
|
|
169
|
+
{
|
|
170
|
+
name: 'Yes',
|
|
171
|
+
hint: 'It will pre-populate the form for you',
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
name: 'No',
|
|
175
|
+
},
|
|
176
|
+
],
|
|
177
|
+
initial: 0,
|
|
178
|
+
},
|
|
179
|
+
]);
|
|
180
|
+
return reply.open === 'Yes';
|
|
181
|
+
}
|
|
182
|
+
catch (e) {
|
|
183
|
+
// Handle the case where the user exits the prompt with ctrl+c
|
|
184
|
+
process.exit(1);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
119
187
|
async function syncGithubRelease(githubRequestConfig, release, existingGithubReleaseForVersion) {
|
|
120
188
|
const ghRelease = {
|
|
121
189
|
tag_name: release.version,
|
|
@@ -2,6 +2,7 @@ import { ProjectGraph } from '../../../config/project-graph';
|
|
|
2
2
|
import { Tree } from '../../../generators/tree';
|
|
3
3
|
import type { ReleaseGroupWithName } from '../config/filter-release-groups';
|
|
4
4
|
import { GitCommit } from './git';
|
|
5
|
+
export declare const noDiffInChangelogMessage: string;
|
|
5
6
|
export type ReleaseVersionGeneratorResult = {
|
|
6
7
|
data: VersionData;
|
|
7
8
|
callback: (tree: Tree, opts: {
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getCommitsRelevantToProjects = exports.handleDuplicateGitTags = exports.createGitTagValues = exports.createCommitMessageValues = exports.commitChanges = exports.ReleaseVersion = void 0;
|
|
3
|
+
exports.getCommitsRelevantToProjects = exports.handleDuplicateGitTags = exports.createGitTagValues = exports.createCommitMessageValues = exports.commitChanges = exports.ReleaseVersion = exports.noDiffInChangelogMessage = void 0;
|
|
4
|
+
const chalk = require("chalk");
|
|
4
5
|
const semver_1 = require("semver");
|
|
5
6
|
const file_map_utils_1 = require("../../../project-graph/file-map-utils");
|
|
6
7
|
const utils_1 = require("../../../tasks-runner/utils");
|
|
7
8
|
const output_1 = require("../../../utils/output");
|
|
8
9
|
const git_1 = require("./git");
|
|
10
|
+
exports.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?`);
|
|
9
11
|
function isPrerelease(version) {
|
|
10
12
|
// prerelease returns an array of matching prerelease "components", or null if the version is not a prerelease
|
|
11
13
|
return (0, semver_1.prerelease)(version) !== null;
|
|
@@ -144,9 +144,6 @@ async function releaseVersion(args) {
|
|
|
144
144
|
});
|
|
145
145
|
}
|
|
146
146
|
}
|
|
147
|
-
if (args.dryRun) {
|
|
148
|
-
devkit_exports_1.logger.warn(`\nNOTE: The "dryRun" flag means no changes were made.`);
|
|
149
|
-
}
|
|
150
147
|
return {
|
|
151
148
|
// An overall workspace version cannot be relevant when filtering to independent projects
|
|
152
149
|
workspaceVersion: undefined,
|
|
@@ -234,9 +231,6 @@ async function releaseVersion(args) {
|
|
|
234
231
|
});
|
|
235
232
|
}
|
|
236
233
|
}
|
|
237
|
-
if (args.dryRun) {
|
|
238
|
-
devkit_exports_1.logger.warn(`\nNOTE: The "dryRun" flag means no changes were made.`);
|
|
239
|
-
}
|
|
240
234
|
return {
|
|
241
235
|
workspaceVersion,
|
|
242
236
|
projectsVersionData: versionData,
|
|
@@ -704,57 +704,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
|
704
704
|
SOFTWARE.
|
|
705
705
|
|
|
706
706
|
|
|
707
|
-
regenerator-runtime
|
|
708
|
-
MIT
|
|
709
|
-
MIT License
|
|
710
|
-
|
|
711
|
-
Copyright (c) 2014-present, Facebook, Inc.
|
|
712
|
-
|
|
713
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
714
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
715
|
-
in the Software without restriction, including without limitation the rights
|
|
716
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
717
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
718
|
-
furnished to do so, subject to the following conditions:
|
|
719
|
-
|
|
720
|
-
The above copyright notice and this permission notice shall be included in all
|
|
721
|
-
copies or substantial portions of the Software.
|
|
722
|
-
|
|
723
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
724
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
725
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
726
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
727
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
728
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
729
|
-
SOFTWARE.
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
tabbable
|
|
733
|
-
MIT
|
|
734
|
-
The MIT License (MIT)
|
|
735
|
-
|
|
736
|
-
Copyright (c) 2015 David Clark
|
|
737
|
-
|
|
738
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
739
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
740
|
-
in the Software without restriction, including without limitation the rights
|
|
741
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
742
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
743
|
-
furnished to do so, subject to the following conditions:
|
|
744
|
-
|
|
745
|
-
The above copyright notice and this permission notice shall be included in all
|
|
746
|
-
copies or substantial portions of the Software.
|
|
747
|
-
|
|
748
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
749
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
750
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
751
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
752
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
753
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
754
|
-
SOFTWARE.
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
707
|
toggle-selection
|
|
759
708
|
MIT
|
|
760
709
|
|