nx 21.0.0-canary.20250429-cf4a1f3 → 21.0.0-canary.20250501-8f50358
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/migrations.json +16 -1
- package/package.json +11 -11
- package/release/changelog-renderer/index.d.ts +7 -7
- package/release/changelog-renderer/index.js +12 -31
- package/schemas/nx-schema.json +8 -3
- package/src/command-line/migrate/migrate-ui-api.d.ts +2 -1
- package/src/command-line/migrate/migrate-ui-api.js +4 -3
- package/src/command-line/migrate/migrate.d.ts +12 -6
- package/src/command-line/migrate/migrate.js +31 -9
- package/src/command-line/release/changelog.d.ts +3 -2
- package/src/command-line/release/changelog.js +57 -70
- package/src/command-line/release/command-object.d.ts +1 -1
- package/src/command-line/release/config/config.d.ts +8 -1
- package/src/command-line/release/config/config.js +18 -11
- package/src/command-line/release/release.js +30 -18
- package/src/command-line/release/utils/git.d.ts +1 -0
- package/src/command-line/release/utils/git.js +27 -8
- package/src/command-line/release/utils/remote-release-clients/github.d.ts +57 -0
- package/src/command-line/release/utils/remote-release-clients/github.js +309 -0
- package/src/command-line/release/utils/remote-release-clients/gitlab.d.ts +62 -0
- package/src/command-line/release/utils/remote-release-clients/gitlab.js +271 -0
- package/src/command-line/release/utils/remote-release-clients/remote-release-client.d.ts +111 -0
- package/src/command-line/release/utils/remote-release-clients/remote-release-client.js +136 -0
- package/src/command-line/repair/repair.js +8 -2
- package/src/command-line/report/report.js +1 -1
- package/src/command-line/yargs-utils/shared-options.d.ts +1 -1
- package/src/command-line/yargs-utils/shared-options.js +22 -3
- package/src/config/misc-interfaces.d.ts +9 -1
- package/src/config/nx-json.d.ts +8 -5
- package/src/core/graph/main.js +1 -1
- package/src/core/graph/styles.css +1 -1
- package/src/devkit-exports.d.ts +1 -1
- package/src/migrations/update-21-0-0/release-changelog-config-changes.d.ts +2 -0
- package/src/migrations/update-21-0-0/release-changelog-config-changes.js +38 -0
- package/src/migrations/update-21-0-0/remove-custom-tasks-runner.d.ts +2 -0
- package/src/migrations/update-21-0-0/remove-custom-tasks-runner.js +38 -0
- package/src/migrations/update-21-0-0/remove-legacy-cache.d.ts +2 -0
- package/src/migrations/update-21-0-0/remove-legacy-cache.js +17 -0
- package/src/native/index.d.ts +6 -1
- package/src/native/native-bindings.js +1 -0
- package/src/native/native-file-cache-location.js +2 -1
- package/src/native/nx.wasm32-wasi.wasm +0 -0
- package/src/project-graph/plugins/get-plugins.js +19 -14
- package/src/tasks-runner/batch/run-batch.js +1 -1
- package/src/tasks-runner/cache.d.ts +1 -2
- package/src/tasks-runner/cache.js +2 -18
- package/src/tasks-runner/is-tui-enabled.d.ts +16 -1
- package/src/tasks-runner/is-tui-enabled.js +40 -28
- package/src/tasks-runner/life-cycles/tui-summary-life-cycle.js +8 -7
- package/src/tasks-runner/pseudo-terminal.d.ts +1 -0
- package/src/tasks-runner/pseudo-terminal.js +11 -1
- package/src/tasks-runner/run-command.js +5 -27
- package/src/tasks-runner/running-tasks/node-child-process.d.ts +1 -0
- package/src/tasks-runner/running-tasks/node-child-process.js +7 -0
- package/src/tasks-runner/task-graph-utils.d.ts +3 -0
- package/src/tasks-runner/task-graph-utils.js +31 -2
- package/src/tasks-runner/task-orchestrator.js +16 -4
- package/src/utils/is-ci.d.ts +1 -1
- package/src/utils/is-ci.js +4 -1
- package/src/utils/package-manager.d.ts +1 -0
- package/src/utils/package-manager.js +29 -16
- package/src/command-line/release/utils/github.d.ts +0 -32
- package/src/command-line/release/utils/github.js +0 -326
@@ -2,7 +2,6 @@
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
3
|
exports.releaseChangelogCLIHandler = void 0;
|
4
4
|
exports.createAPI = createAPI;
|
5
|
-
exports.shouldCreateGitHubRelease = shouldCreateGitHubRelease;
|
6
5
|
const chalk = require("chalk");
|
7
6
|
const enquirer_1 = require("enquirer");
|
8
7
|
const node_fs_1 = require("node:fs");
|
@@ -24,11 +23,11 @@ const filter_release_groups_1 = require("./config/filter-release-groups");
|
|
24
23
|
const use_legacy_versioning_1 = require("./config/use-legacy-versioning");
|
25
24
|
const version_plans_1 = require("./config/version-plans");
|
26
25
|
const git_1 = require("./utils/git");
|
27
|
-
const github_1 = require("./utils/github");
|
28
26
|
const launch_editor_1 = require("./utils/launch-editor");
|
29
27
|
const markdown_1 = require("./utils/markdown");
|
30
28
|
const print_changes_1 = require("./utils/print-changes");
|
31
29
|
const print_config_1 = require("./utils/print-config");
|
30
|
+
const remote_release_client_1 = require("./utils/remote-release-clients/remote-release-client");
|
32
31
|
const resolve_changelog_renderer_1 = require("./utils/resolve-changelog-renderer");
|
33
32
|
const resolve_nx_json_error_message_1 = require("./utils/resolve-nx-json-error-message");
|
34
33
|
const shared_1 = require("./utils/shared");
|
@@ -226,21 +225,13 @@ function createAPI(overrideReleaseConfig) {
|
|
226
225
|
const workspaceChangelog = await generateChangelogForWorkspace({
|
227
226
|
tree,
|
228
227
|
args,
|
229
|
-
projectGraph,
|
230
228
|
nxReleaseConfig,
|
231
229
|
workspaceChangelogVersion,
|
232
230
|
changes: workspaceChangelogChanges,
|
233
|
-
// TODO(v22): remove this after the changelog renderer is refactored to remove coupling with git commits
|
234
|
-
commits: filterHiddenCommits(workspaceChangelogCommits, nxReleaseConfig.conventionalCommits),
|
235
231
|
});
|
236
|
-
|
237
|
-
|
238
|
-
postGitTasks.push(
|
239
|
-
output_1.output.logSingleLine(`Creating GitHub Release`);
|
240
|
-
await (0, github_1.createOrUpdateGithubRelease)(nxReleaseConfig.changelog.workspaceChangelog
|
241
|
-
? nxReleaseConfig.changelog.workspaceChangelog.createRelease
|
242
|
-
: config_1.defaultCreateReleaseProvider, workspaceChangelog.releaseVersion, workspaceChangelog.contents, latestCommit, { dryRun: args.dryRun });
|
243
|
-
});
|
232
|
+
// Add the post git task (e.g. create a remote release) for the workspace changelog, if applicable
|
233
|
+
if (workspaceChangelog && workspaceChangelog.postGitTask) {
|
234
|
+
postGitTasks.push(workspaceChangelog.postGitTask);
|
244
235
|
}
|
245
236
|
/**
|
246
237
|
* Compute any additional dependency bumps up front because there could be cases of circular dependencies,
|
@@ -381,17 +372,14 @@ function createAPI(overrideReleaseConfig) {
|
|
381
372
|
nxReleaseConfig,
|
382
373
|
projectToAdditionalDependencyBumps,
|
383
374
|
});
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
: config_1.defaultCreateReleaseProvider, projectChangelog.releaseVersion, projectChangelog.contents, latestCommit, { dryRun: args.dryRun });
|
392
|
-
});
|
375
|
+
if (projectChangelogs) {
|
376
|
+
for (const [projectName, projectChangelog] of Object.entries(projectChangelogs)) {
|
377
|
+
// Add the post git task (e.g. create a remote release) for the project changelog, if applicable
|
378
|
+
if (projectChangelog.postGitTask) {
|
379
|
+
postGitTasks.push(projectChangelog.postGitTask);
|
380
|
+
}
|
381
|
+
allProjectChangelogs[projectName] = projectChangelog;
|
393
382
|
}
|
394
|
-
allProjectChangelogs[projectName] = projectChangelog;
|
395
383
|
}
|
396
384
|
}
|
397
385
|
}
|
@@ -486,17 +474,14 @@ function createAPI(overrideReleaseConfig) {
|
|
486
474
|
nxReleaseConfig,
|
487
475
|
projectToAdditionalDependencyBumps,
|
488
476
|
});
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
: config_1.defaultCreateReleaseProvider, projectChangelog.releaseVersion, projectChangelog.contents, latestCommit, { dryRun: args.dryRun });
|
497
|
-
});
|
477
|
+
if (projectChangelogs) {
|
478
|
+
for (const [projectName, projectChangelog] of Object.entries(projectChangelogs)) {
|
479
|
+
// Add the post git task (e.g. create a remote release) for the project changelog, if applicable
|
480
|
+
if (projectChangelog.postGitTask) {
|
481
|
+
postGitTasks.push(projectChangelog.postGitTask);
|
482
|
+
}
|
483
|
+
allProjectChangelogs[projectName] = projectChangelog;
|
498
484
|
}
|
499
|
-
allProjectChangelogs[projectName] = projectChangelog;
|
500
485
|
}
|
501
486
|
}
|
502
487
|
}
|
@@ -546,6 +531,19 @@ function resolveChangelogVersions(args, releaseGroups, releaseGroupToFilteredPro
|
|
546
531
|
projectsVersionData: versionData,
|
547
532
|
};
|
548
533
|
}
|
534
|
+
// Can be overridden to something more specific as we resolve the remote release client within nested logic
|
535
|
+
let remoteReleaseProviderName;
|
536
|
+
// If already set, and not the same as the remote release client, append
|
537
|
+
function applyRemoteReleaseProviderName(newRemoteReleaseProviderName) {
|
538
|
+
if (remoteReleaseProviderName) {
|
539
|
+
if (remoteReleaseProviderName !== newRemoteReleaseProviderName) {
|
540
|
+
remoteReleaseProviderName = `${remoteReleaseProviderName}/${newRemoteReleaseProviderName}`;
|
541
|
+
}
|
542
|
+
}
|
543
|
+
else {
|
544
|
+
remoteReleaseProviderName = newRemoteReleaseProviderName;
|
545
|
+
}
|
546
|
+
}
|
549
547
|
async function applyChangesAndExit(args, nxReleaseConfig, tree, toSHA, postGitTasks, commitMessageValues, gitTagValues, releaseGroups) {
|
550
548
|
let latestCommit = toSHA;
|
551
549
|
const changes = tree.listChanges();
|
@@ -563,19 +561,21 @@ async function applyChangesAndExit(args, nxReleaseConfig, tree, toSHA, postGitTa
|
|
563
561
|
],
|
564
562
|
});
|
565
563
|
if (!postGitTasks.length) {
|
566
|
-
//
|
564
|
+
// No post git tasks (e.g. remote release creation) to perform so we can just exit
|
567
565
|
return;
|
568
566
|
}
|
569
567
|
if ((0, is_ci_1.isCI)()) {
|
570
568
|
output_1.output.warn({
|
571
|
-
title: `Skipped
|
569
|
+
title: `Skipped ${remoteReleaseProviderName ?? 'remote'} release creation because no changes were detected for any changelog files.`,
|
572
570
|
});
|
573
571
|
return;
|
574
572
|
}
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
573
|
+
/**
|
574
|
+
* Prompt the user to see if they want to create a remote release anyway.
|
575
|
+
* We know that the user has configured remote releases because we have postGitTasks.
|
576
|
+
*/
|
577
|
+
const shouldCreateRemoteReleaseAnyway = await promptForRemoteRelease();
|
578
|
+
if (!shouldCreateRemoteReleaseAnyway) {
|
579
579
|
return;
|
580
580
|
}
|
581
581
|
for (const postGitTask of postGitTasks) {
|
@@ -658,7 +658,7 @@ async function applyChangesAndExit(args, nxReleaseConfig, tree, toSHA, postGitTa
|
|
658
658
|
}
|
659
659
|
return;
|
660
660
|
}
|
661
|
-
async function generateChangelogForWorkspace({ tree, args,
|
661
|
+
async function generateChangelogForWorkspace({ tree, args, nxReleaseConfig, workspaceChangelogVersion, changes, }) {
|
662
662
|
const config = nxReleaseConfig.changelog.workspaceChangelog;
|
663
663
|
// The entire feature is disabled at the workspace level, exit early
|
664
664
|
if (config === false) {
|
@@ -716,16 +716,17 @@ async function generateChangelogForWorkspace({ tree, args, projectGraph, nxRelea
|
|
716
716
|
title: `${prefix} an entry in ${interpolatedTreePath} for ${chalk.white(releaseVersion.gitTag)}`,
|
717
717
|
});
|
718
718
|
}
|
719
|
-
const
|
719
|
+
const remoteReleaseClient = await (0, remote_release_client_1.createRemoteReleaseClient)(config.createRelease, gitRemote);
|
720
|
+
applyRemoteReleaseProviderName(remoteReleaseClient.remoteReleaseProviderName);
|
720
721
|
const changelogRenderer = new ChangelogRendererClass({
|
721
722
|
changes,
|
722
723
|
changelogEntryVersion: releaseVersion.rawVersion,
|
723
724
|
project: null,
|
724
725
|
isVersionPlans: false,
|
725
|
-
repoData: githubRepoData,
|
726
726
|
entryWhenNoChanges: config.entryWhenNoChanges,
|
727
727
|
changelogRenderOptions: config.renderOptions,
|
728
728
|
conventionalCommitsConfig: nxReleaseConfig.conventionalCommits,
|
729
|
+
remoteReleaseClient,
|
729
730
|
});
|
730
731
|
let contents = await changelogRenderer.render();
|
731
732
|
/**
|
@@ -764,9 +765,13 @@ async function generateChangelogForWorkspace({ tree, args, projectGraph, nxRelea
|
|
764
765
|
tree.write(interpolatedTreePath, rootChangelogContents);
|
765
766
|
(0, print_changes_1.printAndFlushChanges)(tree, !!dryRun, 3, false, shared_1.noDiffInChangelogMessage);
|
766
767
|
}
|
768
|
+
const postGitTask = args.createRelease !== false && config.createRelease
|
769
|
+
? remoteReleaseClient.createPostGitTask(releaseVersion, contents, dryRun)
|
770
|
+
: null;
|
767
771
|
return {
|
768
772
|
releaseVersion,
|
769
773
|
contents,
|
774
|
+
postGitTask,
|
770
775
|
};
|
771
776
|
}
|
772
777
|
async function generateChangelogForProjects({ tree, args, changes, projectsVersionData, releaseGroup, projects, nxReleaseConfig, projectToAdditionalDependencyBumps, }) {
|
@@ -780,6 +785,9 @@ async function generateChangelogForProjects({ tree, args, changes, projectsVersi
|
|
780
785
|
const dryRun = !!args.dryRun;
|
781
786
|
const gitRemote = args.gitRemote;
|
782
787
|
const ChangelogRendererClass = (0, resolve_changelog_renderer_1.resolveChangelogRenderer)(config.renderer);
|
788
|
+
// Maximum of one remote release client per release group
|
789
|
+
const remoteReleaseClient = await (0, remote_release_client_1.createRemoteReleaseClient)(config.createRelease, gitRemote);
|
790
|
+
applyRemoteReleaseProviderName(remoteReleaseClient.remoteReleaseProviderName);
|
783
791
|
const projectChangelogs = {};
|
784
792
|
for (const project of projects) {
|
785
793
|
let interpolatedTreePath = config.file || '';
|
@@ -809,12 +817,10 @@ async function generateChangelogForProjects({ tree, args, changes, projectsVersi
|
|
809
817
|
title: `${prefix} an entry in ${interpolatedTreePath} for ${chalk.white(releaseVersion.gitTag)}`,
|
810
818
|
});
|
811
819
|
}
|
812
|
-
const githubRepoData = (0, github_1.getGitHubRepoData)(gitRemote, config.createRelease);
|
813
820
|
const changelogRenderer = new ChangelogRendererClass({
|
814
821
|
changes,
|
815
822
|
changelogEntryVersion: releaseVersion.rawVersion,
|
816
823
|
project: project.name,
|
817
|
-
repoData: githubRepoData,
|
818
824
|
entryWhenNoChanges: typeof config.entryWhenNoChanges === 'string'
|
819
825
|
? (0, utils_1.interpolate)(config.entryWhenNoChanges, {
|
820
826
|
projectName: project.name,
|
@@ -828,6 +834,7 @@ async function generateChangelogForProjects({ tree, args, changes, projectsVersi
|
|
828
834
|
? null
|
829
835
|
: nxReleaseConfig.conventionalCommits,
|
830
836
|
dependencyBumps: projectToAdditionalDependencyBumps.get(project.name),
|
837
|
+
remoteReleaseClient,
|
831
838
|
});
|
832
839
|
let contents = await changelogRenderer.render();
|
833
840
|
/**
|
@@ -868,9 +875,13 @@ async function generateChangelogForProjects({ tree, args, changes, projectsVersi
|
|
868
875
|
// Only print the change for the current changelog file at this point
|
869
876
|
(f) => f.path === interpolatedTreePath);
|
870
877
|
}
|
878
|
+
const postGitTask = args.createRelease !== false && config.createRelease
|
879
|
+
? remoteReleaseClient.createPostGitTask(releaseVersion, contents, dryRun)
|
880
|
+
: null;
|
871
881
|
projectChangelogs[project.name] = {
|
872
882
|
releaseVersion,
|
873
883
|
contents,
|
884
|
+
postGitTask,
|
874
885
|
};
|
875
886
|
}
|
876
887
|
return projectChangelogs;
|
@@ -903,36 +914,12 @@ function filterHiddenChanges(changes, conventionalCommitsConfig) {
|
|
903
914
|
return !typeConfig.changelog.hidden;
|
904
915
|
});
|
905
916
|
}
|
906
|
-
|
907
|
-
function filterHiddenCommits(commits, conventionalCommitsConfig) {
|
908
|
-
if (!commits) {
|
909
|
-
return [];
|
910
|
-
}
|
911
|
-
return commits.filter((commit) => {
|
912
|
-
const type = commit.type;
|
913
|
-
const typeConfig = conventionalCommitsConfig.types[type];
|
914
|
-
if (!typeConfig) {
|
915
|
-
// don't include commits with unknown types
|
916
|
-
return false;
|
917
|
-
}
|
918
|
-
return !typeConfig.changelog.hidden;
|
919
|
-
});
|
920
|
-
}
|
921
|
-
function shouldCreateGitHubRelease(changelogConfig, createReleaseArg = undefined) {
|
922
|
-
if (createReleaseArg !== undefined) {
|
923
|
-
return createReleaseArg === 'github';
|
924
|
-
}
|
925
|
-
if (changelogConfig === false) {
|
926
|
-
return false;
|
927
|
-
}
|
928
|
-
return changelogConfig.createRelease !== false;
|
929
|
-
}
|
930
|
-
async function promptForGitHubRelease() {
|
917
|
+
async function promptForRemoteRelease() {
|
931
918
|
try {
|
932
919
|
const result = await (0, enquirer_1.prompt)([
|
933
920
|
{
|
934
921
|
name: 'confirmation',
|
935
|
-
message:
|
922
|
+
message: `Do you want to create a ${remoteReleaseProviderName ?? 'remote'} release anyway?`,
|
936
923
|
type: 'confirm',
|
937
924
|
},
|
938
925
|
]);
|
@@ -40,7 +40,7 @@ export type ChangelogOptions = NxReleaseArgs & GitOptions & VersionPlanArgs & Fi
|
|
40
40
|
to?: string;
|
41
41
|
from?: string;
|
42
42
|
interactive?: string;
|
43
|
-
createRelease?: false | 'github';
|
43
|
+
createRelease?: false | 'github' | 'gitlab';
|
44
44
|
};
|
45
45
|
export type PublishOptions = NxReleaseArgs & Partial<RunManyOptions> & {
|
46
46
|
outputStyle?: OutputStyle;
|
@@ -51,5 +51,12 @@ export declare function createNxReleaseConfig(projectGraph: ProjectGraph, projec
|
|
51
51
|
nxReleaseConfig: NxReleaseConfig | null;
|
52
52
|
}>;
|
53
53
|
export declare function handleNxReleaseConfigError(error: CreateNxReleaseConfigError, useLegacyVersioning: boolean): Promise<never>;
|
54
|
-
|
54
|
+
/**
|
55
|
+
* Full form of the createRelease config, with the provider, hostname, and apiBaseUrl resolved.
|
56
|
+
*/
|
57
|
+
export interface ResolvedCreateRemoteReleaseProvider {
|
58
|
+
provider: string;
|
59
|
+
hostname: string;
|
60
|
+
apiBaseUrl: string;
|
61
|
+
}
|
55
62
|
export {};
|
@@ -1,6 +1,6 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.
|
3
|
+
exports.DEFAULT_VERSION_ACTIONS_PATH = exports.IMPLICIT_DEFAULT_RELEASE_GROUP = void 0;
|
4
4
|
exports.createNxReleaseConfig = createNxReleaseConfig;
|
5
5
|
exports.handleNxReleaseConfigError = handleNxReleaseConfigError;
|
6
6
|
/**
|
@@ -23,6 +23,8 @@ const find_matching_projects_1 = require("../../../utils/find-matching-projects"
|
|
23
23
|
const output_1 = require("../../../utils/output");
|
24
24
|
const path_1 = require("../../../utils/path");
|
25
25
|
const workspace_root_1 = require("../../../utils/workspace-root");
|
26
|
+
const github_1 = require("../utils/remote-release-clients/github");
|
27
|
+
const gitlab_1 = require("../utils/remote-release-clients/gitlab");
|
26
28
|
const resolve_changelog_renderer_1 = require("../utils/resolve-changelog-renderer");
|
27
29
|
const resolve_nx_json_error_message_1 = require("../utils/resolve-nx-json-error-message");
|
28
30
|
const conventional_commits_1 = require("./conventional-commits");
|
@@ -170,7 +172,7 @@ async function createNxReleaseConfig(projectGraph, projectFileMap, userConfig =
|
|
170
172
|
renderer: defaultRendererPath,
|
171
173
|
renderOptions: {
|
172
174
|
authors: true,
|
173
|
-
|
175
|
+
applyUsernameToAuthors: true,
|
174
176
|
commitReferences: true,
|
175
177
|
versionTitleDate: true,
|
176
178
|
},
|
@@ -184,7 +186,7 @@ async function createNxReleaseConfig(projectGraph, projectFileMap, userConfig =
|
|
184
186
|
renderer: defaultRendererPath,
|
185
187
|
renderOptions: {
|
186
188
|
authors: true,
|
187
|
-
|
189
|
+
applyUsernameToAuthors: true,
|
188
190
|
commitReferences: true,
|
189
191
|
versionTitleDate: true,
|
190
192
|
},
|
@@ -225,7 +227,7 @@ async function createNxReleaseConfig(projectGraph, projectFileMap, userConfig =
|
|
225
227
|
renderer: defaultRendererPath,
|
226
228
|
renderOptions: {
|
227
229
|
authors: true,
|
228
|
-
|
230
|
+
applyUsernameToAuthors: true,
|
229
231
|
commitReferences: true,
|
230
232
|
versionTitleDate: true,
|
231
233
|
},
|
@@ -930,13 +932,11 @@ const supportedCreateReleaseProviders = [
|
|
930
932
|
name: 'github-enterprise-server',
|
931
933
|
defaultApiBaseUrl: 'https://__hostname__/api/v3',
|
932
934
|
},
|
935
|
+
{
|
936
|
+
name: 'gitlab',
|
937
|
+
defaultApiBaseUrl: 'https://__hostname__/api/v4',
|
938
|
+
},
|
933
939
|
];
|
934
|
-
// User opts into the default by specifying the string value 'github'
|
935
|
-
exports.defaultCreateReleaseProvider = {
|
936
|
-
provider: 'github',
|
937
|
-
hostname: 'github.com',
|
938
|
-
apiBaseUrl: 'https://api.github.com',
|
939
|
-
};
|
940
940
|
function validateCreateReleaseConfig(changelogConfig) {
|
941
941
|
const createRelease = changelogConfig.createRelease;
|
942
942
|
// Disabled: valid
|
@@ -945,7 +945,14 @@ function validateCreateReleaseConfig(changelogConfig) {
|
|
945
945
|
}
|
946
946
|
// GitHub shorthand, expand to full object form, mark as valid
|
947
947
|
if (createRelease === 'github') {
|
948
|
-
changelogConfig.createRelease =
|
948
|
+
changelogConfig.createRelease =
|
949
|
+
github_1.defaultCreateReleaseProvider;
|
950
|
+
return null;
|
951
|
+
}
|
952
|
+
// Gitlab shorthand, expand to full object form, mark as valid
|
953
|
+
if (createRelease === 'gitlab') {
|
954
|
+
changelogConfig.createRelease =
|
955
|
+
gitlab_1.defaultCreateReleaseProvider;
|
949
956
|
return null;
|
950
957
|
}
|
951
958
|
// Object config, ensure that properties are valid
|
@@ -17,8 +17,8 @@ const use_legacy_versioning_1 = require("./config/use-legacy-versioning");
|
|
17
17
|
const version_plans_1 = require("./config/version-plans");
|
18
18
|
const publish_1 = require("./publish");
|
19
19
|
const git_1 = require("./utils/git");
|
20
|
-
const github_1 = require("./utils/github");
|
21
20
|
const print_config_1 = require("./utils/print-config");
|
21
|
+
const remote_release_client_1 = require("./utils/remote-release-clients/remote-release-client");
|
22
22
|
const resolve_nx_json_error_message_1 = require("./utils/resolve-nx-json-error-message");
|
23
23
|
const shared_1 = require("./utils/shared");
|
24
24
|
const version_1 = require("./version");
|
@@ -84,10 +84,10 @@ function createAPI(overrideReleaseConfig) {
|
|
84
84
|
const shouldCommit = userProvidedReleaseConfig.git?.commit ?? true;
|
85
85
|
const shouldStage = (shouldCommit || userProvidedReleaseConfig.git?.stageChanges) ?? false;
|
86
86
|
const shouldTag = userProvidedReleaseConfig.git?.tag ?? true;
|
87
|
-
const
|
88
|
-
// If the workspace or any of the release groups specify that a
|
89
|
-
const shouldPush = (
|
90
|
-
releaseGroups.some((group) => (
|
87
|
+
const shouldCreateWorkspaceRemoteRelease = shouldCreateRemoteRelease(nxReleaseConfig.changelog.workspaceChangelog);
|
88
|
+
// If the workspace or any of the release groups specify that a remote release should be created, we need to push the changes to the remote
|
89
|
+
const shouldPush = (shouldCreateWorkspaceRemoteRelease ||
|
90
|
+
releaseGroups.some((group) => shouldCreateRemoteRelease(group.changelog))) ??
|
91
91
|
false;
|
92
92
|
const versionResult = await releaseVersion({
|
93
93
|
...args,
|
@@ -179,19 +179,27 @@ function createAPI(overrideReleaseConfig) {
|
|
179
179
|
hasPushedChanges = true;
|
180
180
|
}
|
181
181
|
let latestCommit;
|
182
|
-
if (
|
182
|
+
if (shouldCreateWorkspaceRemoteRelease &&
|
183
|
+
changelogResult.workspaceChangelog) {
|
184
|
+
const remoteReleaseClient = await (0, remote_release_client_1.createRemoteReleaseClient)(
|
185
|
+
// shouldCreateWorkspaceRemoteRelease() ensures that the createRelease property exists and is not false
|
186
|
+
nxReleaseConfig.changelog.workspaceChangelog
|
187
|
+
.createRelease);
|
183
188
|
if (!hasPushedChanges) {
|
184
|
-
throw new Error(
|
189
|
+
throw new Error(`It is not possible to create a ${remoteReleaseClient.remoteReleaseProviderName} release for the workspace without pushing the changes to the remote, please ensure that you have not disabled git push in your nx release config`);
|
185
190
|
}
|
186
|
-
output_1.output.logSingleLine(`Creating
|
191
|
+
output_1.output.logSingleLine(`Creating ${remoteReleaseClient.remoteReleaseProviderName} Release`);
|
187
192
|
latestCommit = await (0, git_1.getCommitHash)('HEAD');
|
188
|
-
await (
|
189
|
-
? nxReleaseConfig.changelog.workspaceChangelog.createRelease
|
190
|
-
: false, changelogResult.workspaceChangelog.releaseVersion, changelogResult.workspaceChangelog.contents, latestCommit, { dryRun: args.dryRun });
|
193
|
+
await remoteReleaseClient.createOrUpdateRelease(changelogResult.workspaceChangelog.releaseVersion, changelogResult.workspaceChangelog.contents, latestCommit, { dryRun: args.dryRun });
|
191
194
|
}
|
192
195
|
for (const releaseGroup of releaseGroups) {
|
193
|
-
const
|
194
|
-
if (
|
196
|
+
const shouldCreateProjectRemoteReleases = shouldCreateRemoteRelease(releaseGroup.changelog);
|
197
|
+
if (shouldCreateProjectRemoteReleases &&
|
198
|
+
changelogResult.projectChangelogs) {
|
199
|
+
const remoteReleaseClient = await (0, remote_release_client_1.createRemoteReleaseClient)(
|
200
|
+
// shouldCreateProjectRemoteReleases() ensures that the createRelease property exists and is not false
|
201
|
+
releaseGroup.changelog
|
202
|
+
.createRelease);
|
195
203
|
const projects = args.projects?.length
|
196
204
|
? // If the user has passed a list of projects, we need to use the filtered list of projects within the release group
|
197
205
|
Array.from(releaseGroupToFilteredProjects.get(releaseGroup))
|
@@ -204,15 +212,13 @@ function createAPI(overrideReleaseConfig) {
|
|
204
212
|
continue;
|
205
213
|
}
|
206
214
|
if (!hasPushedChanges) {
|
207
|
-
throw new Error(
|
215
|
+
throw new Error(`It is not possible to create a ${remoteReleaseClient.remoteReleaseProviderName} release for the project without pushing the changes to the remote, please ensure that you have not disabled git push in your nx release config`);
|
208
216
|
}
|
209
|
-
output_1.output.logSingleLine(`Creating
|
217
|
+
output_1.output.logSingleLine(`Creating ${remoteReleaseClient.remoteReleaseProviderName} Release`);
|
210
218
|
if (!latestCommit) {
|
211
219
|
latestCommit = await (0, git_1.getCommitHash)('HEAD');
|
212
220
|
}
|
213
|
-
await (
|
214
|
-
? releaseGroup.changelog.createRelease
|
215
|
-
: false, changelog.releaseVersion, changelog.contents, latestCommit, { dryRun: args.dryRun });
|
221
|
+
await remoteReleaseClient.createOrUpdateRelease(changelog.releaseVersion, changelog.contents, latestCommit, { dryRun: args.dryRun });
|
216
222
|
}
|
217
223
|
}
|
218
224
|
}
|
@@ -253,3 +259,9 @@ async function promptForPublish() {
|
|
253
259
|
return false;
|
254
260
|
}
|
255
261
|
}
|
262
|
+
function shouldCreateRemoteRelease(changelogConfig) {
|
263
|
+
if (changelogConfig === false) {
|
264
|
+
return false;
|
265
|
+
}
|
266
|
+
return changelogConfig.createRelease !== false;
|
267
|
+
}
|
@@ -63,6 +63,7 @@ export declare function parseConventionalCommitsMessage(message: string): {
|
|
63
63
|
description: string;
|
64
64
|
breaking: boolean;
|
65
65
|
} | null;
|
66
|
+
export declare function extractReferencesFromCommit(commit: RawGitCommit): Reference[];
|
66
67
|
export declare function parseGitCommit(commit: RawGitCommit, isVersionPlanCommit?: boolean): GitCommit | null;
|
67
68
|
export declare function getCommitHash(ref: string): Promise<string>;
|
68
69
|
export declare function getFirstGitCommit(): Promise<string>;
|
@@ -8,6 +8,7 @@ exports.gitTag = gitTag;
|
|
8
8
|
exports.gitPush = gitPush;
|
9
9
|
exports.parseCommits = parseCommits;
|
10
10
|
exports.parseConventionalCommitsMessage = parseConventionalCommitsMessage;
|
11
|
+
exports.extractReferencesFromCommit = extractReferencesFromCommit;
|
11
12
|
exports.parseGitCommit = parseGitCommit;
|
12
13
|
exports.getCommitHash = getCommitHash;
|
13
14
|
exports.getFirstGitCommit = getFirstGitCommit;
|
@@ -362,17 +363,32 @@ function parseConventionalCommitsMessage(message) {
|
|
362
363
|
breaking: Boolean(match.groups.breaking),
|
363
364
|
};
|
364
365
|
}
|
365
|
-
function
|
366
|
+
function extractReferencesFromCommit(commit) {
|
366
367
|
const references = [];
|
367
|
-
|
368
|
+
// Extract GitHub style PR references from commit message
|
369
|
+
for (const m of commit.message.matchAll(PullRequestRE)) {
|
368
370
|
references.push({ type: 'pull-request', value: m[1] });
|
369
371
|
}
|
370
|
-
|
372
|
+
// Extract GitLab style merge request references from commit body
|
373
|
+
for (const m of commit.body.matchAll(GitLabMergeRequestRE)) {
|
374
|
+
if (m[1]) {
|
375
|
+
references.push({ type: 'pull-request', value: m[1] });
|
376
|
+
}
|
377
|
+
}
|
378
|
+
// Extract issue references from commit message
|
379
|
+
for (const m of commit.message.matchAll(IssueRE)) {
|
380
|
+
if (!references.some((i) => i.value === m[1])) {
|
381
|
+
references.push({ type: 'issue', value: m[1] });
|
382
|
+
}
|
383
|
+
}
|
384
|
+
// Extract issue references from commit body
|
385
|
+
for (const m of commit.body.matchAll(IssueRE)) {
|
371
386
|
if (!references.some((i) => i.value === m[1])) {
|
372
387
|
references.push({ type: 'issue', value: m[1] });
|
373
388
|
}
|
374
389
|
}
|
375
|
-
|
390
|
+
// Add commit hash reference
|
391
|
+
references.push({ value: commit.shortHash, type: 'hash' });
|
376
392
|
return references;
|
377
393
|
}
|
378
394
|
function getAllAuthorsForCommit(commit) {
|
@@ -390,7 +406,10 @@ function getAllAuthorsForCommit(commit) {
|
|
390
406
|
// https://regex101.com/r/FSfNvA/1
|
391
407
|
const ConventionalCommitRegex = /(?<type>[a-z]+)(\((?<scope>.+)\))?(?<breaking>!)?: (?<description>.+)/i;
|
392
408
|
const CoAuthoredByRegex = /co-authored-by:\s*(?<name>.+)(<(?<email>.+)>)/gim;
|
409
|
+
// GitHub style PR references
|
393
410
|
const PullRequestRE = /\([ a-z]*(#\d+)\s*\)/gm;
|
411
|
+
// GitLab style merge request references
|
412
|
+
const GitLabMergeRequestRE = /See merge request (?:[a-z0-9/-]+)?(![\d]+)/gim;
|
394
413
|
const IssueRE = /(#\d+)/gm;
|
395
414
|
const ChangedFileRegex = /(A|M|D|R\d*|C\d*)\t([^\t\n]*)\t?(.*)?/gm;
|
396
415
|
const RevertHashRE = /This reverts commit (?<hash>[\da-f]{40})./gm;
|
@@ -402,7 +421,7 @@ function parseGitCommit(commit, isVersionPlanCommit = false) {
|
|
402
421
|
description: commit.message,
|
403
422
|
type: '',
|
404
423
|
scope: '',
|
405
|
-
references:
|
424
|
+
references: extractReferencesFromCommit(commit),
|
406
425
|
// The commit message is not the source of truth for a breaking (major) change in version plans, so the value is not relevant
|
407
426
|
// TODO(v22): Make the current GitCommit interface more clearly tied to conventional commits
|
408
427
|
isBreaking: false,
|
@@ -420,9 +439,9 @@ function parseGitCommit(commit, isVersionPlanCommit = false) {
|
|
420
439
|
const scope = parsedMessage.scope;
|
421
440
|
const isBreaking = parsedMessage.breaking || commit.body.includes('BREAKING CHANGE:');
|
422
441
|
let description = parsedMessage.description;
|
423
|
-
// Extract references from
|
424
|
-
const references =
|
425
|
-
// Remove references
|
442
|
+
// Extract issue and PR references from the commit
|
443
|
+
const references = extractReferencesFromCommit(commit);
|
444
|
+
// Remove GitHub style references from description (NOTE: GitLab style references only seem to appear in the body, so we don't need to remove them here)
|
426
445
|
description = description.replace(PullRequestRE, '').trim();
|
427
446
|
let type = parsedMessage.type;
|
428
447
|
// Extract any reverted hashes, if applicable
|
@@ -0,0 +1,57 @@
|
|
1
|
+
import type { PostGitTask } from '../../changelog';
|
2
|
+
import { type ResolvedCreateRemoteReleaseProvider } from '../../config/config';
|
3
|
+
import { Reference } from '../git';
|
4
|
+
import { ReleaseVersion } from '../shared';
|
5
|
+
import { RemoteReleaseClient, RemoteReleaseOptions, RemoteReleaseResult, RemoteRepoData } from './remote-release-client';
|
6
|
+
export interface GithubRepoData extends RemoteRepoData {
|
7
|
+
}
|
8
|
+
export interface GithubRemoteRelease {
|
9
|
+
id?: string;
|
10
|
+
body: string;
|
11
|
+
tag_name: string;
|
12
|
+
target_commitish?: string;
|
13
|
+
name?: string;
|
14
|
+
draft?: boolean;
|
15
|
+
prerelease?: boolean;
|
16
|
+
make_latest?: 'legacy' | boolean;
|
17
|
+
}
|
18
|
+
export declare const defaultCreateReleaseProvider: ResolvedCreateRemoteReleaseProvider;
|
19
|
+
export declare class GithubRemoteReleaseClient extends RemoteReleaseClient<GithubRemoteRelease> {
|
20
|
+
remoteReleaseProviderName: string;
|
21
|
+
/**
|
22
|
+
* Get GitHub repository data from git remote
|
23
|
+
*/
|
24
|
+
static resolveRepoData(createReleaseConfig: false | ResolvedCreateRemoteReleaseProvider, remoteName?: string): GithubRepoData | null;
|
25
|
+
/**
|
26
|
+
* Resolve a GitHub token from environment variables or gh CLI
|
27
|
+
*/
|
28
|
+
static resolveTokenData(hostname: string): Promise<{
|
29
|
+
token: string;
|
30
|
+
headerName: string;
|
31
|
+
} | null>;
|
32
|
+
createPostGitTask(releaseVersion: ReleaseVersion, changelogContents: string, dryRun: boolean): PostGitTask;
|
33
|
+
applyUsernameToAuthors(authors: Map<string, {
|
34
|
+
email: Set<string>;
|
35
|
+
username?: string;
|
36
|
+
}>): Promise<void>;
|
37
|
+
/**
|
38
|
+
* Get a release by tag
|
39
|
+
*/
|
40
|
+
protected getReleaseByTag(tag: string): Promise<GithubRemoteRelease>;
|
41
|
+
/**
|
42
|
+
* Create a new release
|
43
|
+
*/
|
44
|
+
protected createRelease(remoteRelease: GithubRemoteRelease): Promise<any>;
|
45
|
+
protected updateRelease(id: string, remoteRelease: GithubRemoteRelease): Promise<any>;
|
46
|
+
protected getManualRemoteReleaseURL(remoteReleaseOptions: RemoteReleaseOptions): string;
|
47
|
+
protected handleAuthError(): void;
|
48
|
+
protected logReleaseAction(existingRelease: GithubRemoteRelease | undefined, gitTag: string, dryRun: boolean): void;
|
49
|
+
protected handleError(error: any, result: RemoteReleaseResult): Promise<void>;
|
50
|
+
private promptForContinueInGitHub;
|
51
|
+
/**
|
52
|
+
* Format references for the release (e.g., PRs, issues)
|
53
|
+
*/
|
54
|
+
formatReferences(references: Reference[]): string;
|
55
|
+
protected syncRelease(remoteReleaseOptions: RemoteReleaseOptions, existingRelease?: GithubRemoteRelease): Promise<RemoteReleaseResult>;
|
56
|
+
private getRequiredRemoteRepoData;
|
57
|
+
}
|