nx 19.8.0-canary.20240920-999abe9 → 19.9.0-canary.20240921-a510b36
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 +12 -12
- package/release/changelog-renderer/index.d.ts +3 -1
- package/release/changelog-renderer/index.js +8 -8
- package/schemas/nx-schema.json +21 -0
- package/src/command-line/release/changelog.js +16 -10
- package/src/command-line/release/config/config.d.ts +2 -1
- package/src/command-line/release/config/config.js +165 -20
- package/src/command-line/release/release.js +6 -2
- package/src/command-line/release/utils/github.d.ts +14 -6
- package/src/command-line/release/utils/github.js +49 -24
- package/src/config/nx-json.d.ts +8 -1
- package/src/core/graph/main.js +1 -1
- package/src/core/graph/styles.js +1 -1
- package/src/native/index.d.ts +1 -1
- package/src/native/nx.wasm32-wasi.wasm +0 -0
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "nx",
|
3
|
-
"version": "19.
|
3
|
+
"version": "19.9.0-canary.20240921-a510b36",
|
4
4
|
"private": false,
|
5
5
|
"description": "The core Nx plugin contains the core functionality of Nx like the project graph, nx commands and task orchestration.",
|
6
6
|
"repository": {
|
@@ -68,7 +68,7 @@
|
|
68
68
|
"yargs-parser": "21.1.1",
|
69
69
|
"node-machine-id": "1.1.12",
|
70
70
|
"ora": "5.3.0",
|
71
|
-
"@nrwl/tao": "19.
|
71
|
+
"@nrwl/tao": "19.9.0-canary.20240921-a510b36"
|
72
72
|
},
|
73
73
|
"peerDependencies": {
|
74
74
|
"@swc-node/register": "^1.8.0",
|
@@ -83,16 +83,16 @@
|
|
83
83
|
}
|
84
84
|
},
|
85
85
|
"optionalDependencies": {
|
86
|
-
"@nx/nx-darwin-x64": "19.
|
87
|
-
"@nx/nx-darwin-arm64": "19.
|
88
|
-
"@nx/nx-linux-x64-gnu": "19.
|
89
|
-
"@nx/nx-linux-x64-musl": "19.
|
90
|
-
"@nx/nx-win32-x64-msvc": "19.
|
91
|
-
"@nx/nx-linux-arm64-gnu": "19.
|
92
|
-
"@nx/nx-linux-arm64-musl": "19.
|
93
|
-
"@nx/nx-linux-arm-gnueabihf": "19.
|
94
|
-
"@nx/nx-win32-arm64-msvc": "19.
|
95
|
-
"@nx/nx-freebsd-x64": "19.
|
86
|
+
"@nx/nx-darwin-x64": "19.9.0-canary.20240921-a510b36",
|
87
|
+
"@nx/nx-darwin-arm64": "19.9.0-canary.20240921-a510b36",
|
88
|
+
"@nx/nx-linux-x64-gnu": "19.9.0-canary.20240921-a510b36",
|
89
|
+
"@nx/nx-linux-x64-musl": "19.9.0-canary.20240921-a510b36",
|
90
|
+
"@nx/nx-win32-x64-msvc": "19.9.0-canary.20240921-a510b36",
|
91
|
+
"@nx/nx-linux-arm64-gnu": "19.9.0-canary.20240921-a510b36",
|
92
|
+
"@nx/nx-linux-arm64-musl": "19.9.0-canary.20240921-a510b36",
|
93
|
+
"@nx/nx-linux-arm-gnueabihf": "19.9.0-canary.20240921-a510b36",
|
94
|
+
"@nx/nx-win32-arm64-msvc": "19.9.0-canary.20240921-a510b36",
|
95
|
+
"@nx/nx-freebsd-x64": "19.9.0-canary.20240921-a510b36"
|
96
96
|
},
|
97
97
|
"nx-migrations": {
|
98
98
|
"migrations": "./migrations.json",
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import { ChangelogChange } from '../../src/command-line/release/changelog';
|
2
2
|
import { NxReleaseConfig } from '../../src/command-line/release/config/config';
|
3
3
|
import { GitCommit } from '../../src/command-line/release/utils/git';
|
4
|
-
import { RepoSlug } from '../../src/command-line/release/utils/github';
|
4
|
+
import { GithubRepoData, RepoSlug } from '../../src/command-line/release/utils/github';
|
5
5
|
import type { ProjectGraph } from '../../src/config/project-graph';
|
6
6
|
/**
|
7
7
|
* The ChangelogRenderOptions are specific to each ChangelogRenderer implementation, and are taken
|
@@ -30,6 +30,7 @@ export type DependencyBump = {
|
|
30
30
|
* @param {string | false} config.entryWhenNoChanges The (already interpolated) string to use as the changelog entry when there are no changes, or `false` if no entry should be generated
|
31
31
|
* @param {ChangelogRenderOptions} config.changelogRenderOptions The options specific to the ChangelogRenderer implementation
|
32
32
|
* @param {DependencyBump[]} config.dependencyBumps Optional list of additional dependency bumps that occurred as part of the release, outside of the commit data
|
33
|
+
* @param {GithubRepoData} config.repoData Resolved data for the current GitHub repository
|
33
34
|
*/
|
34
35
|
export type ChangelogRenderer = (config: {
|
35
36
|
projectGraph: ProjectGraph;
|
@@ -41,6 +42,7 @@ export type ChangelogRenderer = (config: {
|
|
41
42
|
changelogRenderOptions: DefaultChangelogRenderOptions;
|
42
43
|
dependencyBumps?: DependencyBump[];
|
43
44
|
repoSlug?: RepoSlug;
|
45
|
+
repoData?: GithubRepoData;
|
44
46
|
conventionalCommitsConfig: NxReleaseConfig['conventionalCommits'] | null;
|
45
47
|
}) => Promise<string> | string;
|
46
48
|
/**
|
@@ -10,7 +10,7 @@ const axios = _axios;
|
|
10
10
|
* The default ChangelogRenderer implementation that nx exports for the common case of generating markdown
|
11
11
|
* from the given commits and other metadata.
|
12
12
|
*/
|
13
|
-
const defaultChangelogRenderer = async ({ projectGraph, changes, releaseVersion, project, entryWhenNoChanges, changelogRenderOptions, dependencyBumps, repoSlug, conventionalCommitsConfig, }) => {
|
13
|
+
const defaultChangelogRenderer = async ({ projectGraph, changes, releaseVersion, project, entryWhenNoChanges, changelogRenderOptions, dependencyBumps, repoSlug, conventionalCommitsConfig, repoData, }) => {
|
14
14
|
const markdownLines = [];
|
15
15
|
// If the current range of changes contains both a commit and its revert, we strip them both from the final list. Changes from version plans are unaffected, as they have no hashes.
|
16
16
|
for (const change of changes) {
|
@@ -46,7 +46,7 @@ const defaultChangelogRenderer = async ({ projectGraph, changes, releaseVersion,
|
|
46
46
|
if (relevantChanges[i].isBreaking) {
|
47
47
|
const change = relevantChanges[i];
|
48
48
|
additionalChangesForAuthorsSection.push(change);
|
49
|
-
const line = formatChange(change, changelogRenderOptions, isVersionPlans,
|
49
|
+
const line = formatChange(change, changelogRenderOptions, isVersionPlans, repoData);
|
50
50
|
breakingChanges.push(line);
|
51
51
|
relevantChanges.splice(i, 1);
|
52
52
|
}
|
@@ -89,7 +89,7 @@ const defaultChangelogRenderer = async ({ projectGraph, changes, releaseVersion,
|
|
89
89
|
for (const scope of scopesSortedAlphabetically) {
|
90
90
|
const changes = changesGroupedByScope[scope];
|
91
91
|
for (const change of changes) {
|
92
|
-
const line = formatChange(change, changelogRenderOptions, isVersionPlans,
|
92
|
+
const line = formatChange(change, changelogRenderOptions, isVersionPlans, repoData);
|
93
93
|
markdownLines.push(line);
|
94
94
|
if (change.isBreaking) {
|
95
95
|
const breakingChangeExplanation = extractBreakingChangeExplanation(change.body);
|
@@ -132,7 +132,7 @@ const defaultChangelogRenderer = async ({ projectGraph, changes, releaseVersion,
|
|
132
132
|
markdownLines.push('', `### ${changeTypes[type].changelog.title}`, '');
|
133
133
|
const changesInChronologicalOrder = group.reverse();
|
134
134
|
for (const change of changesInChronologicalOrder) {
|
135
|
-
const line = formatChange(change, changelogRenderOptions, isVersionPlans,
|
135
|
+
const line = formatChange(change, changelogRenderOptions, isVersionPlans, repoData);
|
136
136
|
markdownLines.push(line + '\n');
|
137
137
|
if (change.isBreaking) {
|
138
138
|
const breakingChangeExplanation = extractBreakingChangeExplanation(change.body);
|
@@ -176,7 +176,7 @@ const defaultChangelogRenderer = async ({ projectGraph, changes, releaseVersion,
|
|
176
176
|
}
|
177
177
|
}
|
178
178
|
// Try to map authors to github usernames
|
179
|
-
if (
|
179
|
+
if (repoData && changelogRenderOptions.mapAuthorsToGitHubUsernames) {
|
180
180
|
await Promise.all([..._authors.keys()].map(async (authorName) => {
|
181
181
|
const meta = _authors.get(authorName);
|
182
182
|
for (const email of meta.email) {
|
@@ -245,7 +245,7 @@ function groupBy(items, key) {
|
|
245
245
|
}
|
246
246
|
return groups;
|
247
247
|
}
|
248
|
-
function formatChange(change, changelogRenderOptions, isVersionPlans,
|
248
|
+
function formatChange(change, changelogRenderOptions, isVersionPlans, repoData) {
|
249
249
|
let description = change.description;
|
250
250
|
let extraLines = [];
|
251
251
|
let extraLinesStr = '';
|
@@ -267,8 +267,8 @@ function formatChange(change, changelogRenderOptions, isVersionPlans, repoSlug)
|
|
267
267
|
(!isVersionPlans && change.isBreaking ? '⚠️ ' : '') +
|
268
268
|
(!isVersionPlans && change.scope ? `**${change.scope.trim()}:** ` : '') +
|
269
269
|
description;
|
270
|
-
if (
|
271
|
-
changeLine += (0, github_1.formatReferences)(change.githubReferences,
|
270
|
+
if (repoData && changelogRenderOptions.commitReferences) {
|
271
|
+
changeLine += (0, github_1.formatReferences)(change.githubReferences, repoData);
|
272
272
|
}
|
273
273
|
if (extraLinesStr) {
|
274
274
|
changeLine += '\n\n' + extraLinesStr;
|
package/schemas/nx-schema.json
CHANGED
@@ -691,6 +691,9 @@
|
|
691
691
|
{
|
692
692
|
"type": "boolean",
|
693
693
|
"enum": [false]
|
694
|
+
},
|
695
|
+
{
|
696
|
+
"$ref": "#/definitions/CreateReleaseProviderConfiguration"
|
694
697
|
}
|
695
698
|
]
|
696
699
|
},
|
@@ -724,6 +727,24 @@
|
|
724
727
|
}
|
725
728
|
}
|
726
729
|
},
|
730
|
+
"CreateReleaseProviderConfiguration": {
|
731
|
+
"type": "object",
|
732
|
+
"properties": {
|
733
|
+
"provider": {
|
734
|
+
"type": "string",
|
735
|
+
"enum": ["github-enterprise-server"]
|
736
|
+
},
|
737
|
+
"hostname": {
|
738
|
+
"type": "string",
|
739
|
+
"description": "The hostname of the VCS provider instance, e.g. github.example.com"
|
740
|
+
},
|
741
|
+
"apiBaseUrl": {
|
742
|
+
"type": "string",
|
743
|
+
"description": "The base URL for the relevant VCS provider API. If not set, this will default to `https://${hostname}/api/v3`"
|
744
|
+
}
|
745
|
+
},
|
746
|
+
"required": ["provider", "hostname"]
|
747
|
+
},
|
727
748
|
"NxReleaseVersionPlansConfiguration": {
|
728
749
|
"type": "object",
|
729
750
|
"properties": {
|
@@ -242,7 +242,9 @@ function createAPI(overrideReleaseConfig) {
|
|
242
242
|
hasPushed = true;
|
243
243
|
}
|
244
244
|
output_1.output.logSingleLine(`Creating GitHub Release`);
|
245
|
-
await (0, github_1.createOrUpdateGithubRelease)(
|
245
|
+
await (0, github_1.createOrUpdateGithubRelease)(nxReleaseConfig.changelog.workspaceChangelog
|
246
|
+
? nxReleaseConfig.changelog.workspaceChangelog.createRelease
|
247
|
+
: config_1.defaultCreateReleaseProvider, workspaceChangelog.releaseVersion, workspaceChangelog.contents, latestCommit, { dryRun: args.dryRun });
|
246
248
|
});
|
247
249
|
}
|
248
250
|
/**
|
@@ -401,7 +403,9 @@ function createAPI(overrideReleaseConfig) {
|
|
401
403
|
hasPushed = true;
|
402
404
|
}
|
403
405
|
output_1.output.logSingleLine(`Creating GitHub Release`);
|
404
|
-
await (0, github_1.createOrUpdateGithubRelease)(
|
406
|
+
await (0, github_1.createOrUpdateGithubRelease)(releaseGroup.changelog
|
407
|
+
? releaseGroup.changelog.createRelease
|
408
|
+
: config_1.defaultCreateReleaseProvider, projectChangelog.releaseVersion, projectChangelog.contents, latestCommit, { dryRun: args.dryRun });
|
405
409
|
});
|
406
410
|
}
|
407
411
|
allProjectChangelogs[projectName] = projectChangelog;
|
@@ -516,7 +520,9 @@ function createAPI(overrideReleaseConfig) {
|
|
516
520
|
hasPushed = true;
|
517
521
|
}
|
518
522
|
output_1.output.logSingleLine(`Creating GitHub Release`);
|
519
|
-
await (0, github_1.createOrUpdateGithubRelease)(
|
523
|
+
await (0, github_1.createOrUpdateGithubRelease)(releaseGroup.changelog
|
524
|
+
? releaseGroup.changelog.createRelease
|
525
|
+
: config_1.defaultCreateReleaseProvider, projectChangelog.releaseVersion, projectChangelog.contents, latestCommit, { dryRun: args.dryRun });
|
520
526
|
});
|
521
527
|
}
|
522
528
|
allProjectChangelogs[projectName] = projectChangelog;
|
@@ -730,14 +736,15 @@ async function generateChangelogForWorkspace({ tree, args, projectGraph, nxRelea
|
|
730
736
|
title: `${prefix} an entry in ${interpolatedTreePath} for ${chalk.white(releaseVersion.gitTag)}`,
|
731
737
|
});
|
732
738
|
}
|
733
|
-
const
|
739
|
+
const githubRepoData = (0, github_1.getGitHubRepoData)(gitRemote, config.createRelease);
|
734
740
|
let contents = await changelogRenderer({
|
735
741
|
projectGraph,
|
736
742
|
changes,
|
737
743
|
commits,
|
738
744
|
releaseVersion: releaseVersion.rawVersion,
|
739
745
|
project: null,
|
740
|
-
repoSlug:
|
746
|
+
repoSlug: githubRepoData?.slug,
|
747
|
+
repoData: githubRepoData,
|
741
748
|
entryWhenNoChanges: config.entryWhenNoChanges,
|
742
749
|
changelogRenderOptions: config.renderOptions,
|
743
750
|
conventionalCommitsConfig: nxReleaseConfig.conventionalCommits,
|
@@ -822,16 +829,15 @@ async function generateChangelogForProjects({ tree, args, projectGraph, changes,
|
|
822
829
|
title: `${prefix} an entry in ${interpolatedTreePath} for ${chalk.white(releaseVersion.gitTag)}`,
|
823
830
|
});
|
824
831
|
}
|
825
|
-
const
|
826
|
-
? (0, github_1.getGitHubRepoSlug)(gitRemote)
|
827
|
-
: undefined;
|
832
|
+
const githubRepoData = (0, github_1.getGitHubRepoData)(gitRemote, config.createRelease);
|
828
833
|
let contents = await changelogRenderer({
|
829
834
|
projectGraph,
|
830
835
|
changes,
|
831
836
|
commits,
|
832
837
|
releaseVersion: releaseVersion.rawVersion,
|
833
838
|
project: project.name,
|
834
|
-
repoSlug:
|
839
|
+
repoSlug: githubRepoData?.slug,
|
840
|
+
repoData: githubRepoData,
|
835
841
|
entryWhenNoChanges: typeof config.entryWhenNoChanges === 'string'
|
836
842
|
? (0, utils_1.interpolate)(config.entryWhenNoChanges, {
|
837
843
|
projectName: project.name,
|
@@ -937,7 +943,7 @@ function shouldCreateGitHubRelease(changelogConfig, createReleaseArg = undefined
|
|
937
943
|
if (createReleaseArg !== undefined) {
|
938
944
|
return createReleaseArg === 'github';
|
939
945
|
}
|
940
|
-
return (changelogConfig || {}).createRelease
|
946
|
+
return (changelogConfig || {}).createRelease !== false;
|
941
947
|
}
|
942
948
|
async function promptForGitHubRelease() {
|
943
949
|
try {
|
@@ -42,7 +42,7 @@ export type NxReleaseConfig = Omit<DeepRequired<NxJsonConfiguration['release'] &
|
|
42
42
|
};
|
43
43
|
}>, 'projects'>;
|
44
44
|
export interface CreateNxReleaseConfigError {
|
45
|
-
code: 'PROJECTS_AND_GROUPS_DEFINED' | 'RELEASE_GROUP_MATCHES_NO_PROJECTS' | 'RELEASE_GROUP_RELEASE_TAG_PATTERN_VERSION_PLACEHOLDER_MISSING_OR_EXCESSIVE' | 'PROJECT_MATCHES_MULTIPLE_GROUPS' | 'CONVENTIONAL_COMMITS_SHORTHAND_MIXED_WITH_OVERLAPPING_GENERATOR_OPTIONS' | 'GLOBAL_GIT_CONFIG_MIXED_WITH_GRANULAR_GIT_CONFIG';
|
45
|
+
code: 'PROJECTS_AND_GROUPS_DEFINED' | 'RELEASE_GROUP_MATCHES_NO_PROJECTS' | 'RELEASE_GROUP_RELEASE_TAG_PATTERN_VERSION_PLACEHOLDER_MISSING_OR_EXCESSIVE' | 'PROJECT_MATCHES_MULTIPLE_GROUPS' | 'CONVENTIONAL_COMMITS_SHORTHAND_MIXED_WITH_OVERLAPPING_GENERATOR_OPTIONS' | 'GLOBAL_GIT_CONFIG_MIXED_WITH_GRANULAR_GIT_CONFIG' | 'CANNOT_RESOLVE_CHANGELOG_RENDERER' | 'INVALID_CHANGELOG_CREATE_RELEASE_PROVIDER' | 'INVALID_CHANGELOG_CREATE_RELEASE_HOSTNAME' | 'INVALID_CHANGELOG_CREATE_RELEASE_API_BASE_URL';
|
46
46
|
data: Record<string, string | string[]>;
|
47
47
|
}
|
48
48
|
export declare function createNxReleaseConfig(projectGraph: ProjectGraph, projectFileMap: ProjectFileMap, userConfig?: NxJsonConfiguration['release']): Promise<{
|
@@ -50,4 +50,5 @@ export declare function createNxReleaseConfig(projectGraph: ProjectGraph, projec
|
|
50
50
|
nxReleaseConfig: NxReleaseConfig | null;
|
51
51
|
}>;
|
52
52
|
export declare function handleNxReleaseConfigError(error: CreateNxReleaseConfigError): Promise<never>;
|
53
|
+
export declare const defaultCreateReleaseProvider: any;
|
53
54
|
export {};
|
@@ -1,6 +1,6 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.IMPLICIT_DEFAULT_RELEASE_GROUP = void 0;
|
3
|
+
exports.defaultCreateReleaseProvider = exports.IMPLICIT_DEFAULT_RELEASE_GROUP = void 0;
|
4
4
|
exports.createNxReleaseConfig = createNxReleaseConfig;
|
5
5
|
exports.handleNxReleaseConfigError = handleNxReleaseConfigError;
|
6
6
|
/**
|
@@ -17,6 +17,7 @@ exports.handleNxReleaseConfigError = handleNxReleaseConfigError;
|
|
17
17
|
* and easy to consume config object for all the `nx release` command implementations.
|
18
18
|
*/
|
19
19
|
const node_path_1 = require("node:path");
|
20
|
+
const node_url_1 = require("node:url");
|
20
21
|
const fileutils_1 = require("../../../utils/fileutils");
|
21
22
|
const find_matching_projects_1 = require("../../../utils/find-matching-projects");
|
22
23
|
const output_1 = require("../../../utils/output");
|
@@ -368,7 +369,13 @@ async function createNxReleaseConfig(projectGraph, projectFileMap, userConfig =
|
|
368
369
|
}
|
369
370
|
releaseGroups[releaseGroupName] = finalReleaseGroup;
|
370
371
|
}
|
371
|
-
|
372
|
+
const configError = validateChangelogConfig(releaseGroups, rootChangelogConfig);
|
373
|
+
if (configError) {
|
374
|
+
return {
|
375
|
+
error: configError,
|
376
|
+
nxReleaseConfig: null,
|
377
|
+
};
|
378
|
+
}
|
372
379
|
return {
|
373
380
|
error: null,
|
374
381
|
nxReleaseConfig: {
|
@@ -547,6 +554,48 @@ async function handleNxReleaseConfigError(error) {
|
|
547
554
|
});
|
548
555
|
}
|
549
556
|
break;
|
557
|
+
case 'CANNOT_RESOLVE_CHANGELOG_RENDERER': {
|
558
|
+
const nxJsonMessage = await (0, resolve_nx_json_error_message_1.resolveNxJsonConfigErrorMessage)(['release']);
|
559
|
+
output_1.output.error({
|
560
|
+
title: `There was an error when resolving the configured changelog renderer at path: ${error.data.workspaceRelativePath}`,
|
561
|
+
bodyLines: [nxJsonMessage],
|
562
|
+
});
|
563
|
+
}
|
564
|
+
case 'INVALID_CHANGELOG_CREATE_RELEASE_PROVIDER':
|
565
|
+
{
|
566
|
+
const nxJsonMessage = await (0, resolve_nx_json_error_message_1.resolveNxJsonConfigErrorMessage)([
|
567
|
+
'release',
|
568
|
+
]);
|
569
|
+
output_1.output.error({
|
570
|
+
title: `Your "changelog.createRelease" config specifies an unsupported provider "${error.data.provider}". The supported providers are ${error.data.supportedProviders
|
571
|
+
.map((p) => `"${p}"`)
|
572
|
+
.join(', ')}`,
|
573
|
+
bodyLines: [nxJsonMessage],
|
574
|
+
});
|
575
|
+
}
|
576
|
+
break;
|
577
|
+
case 'INVALID_CHANGELOG_CREATE_RELEASE_HOSTNAME':
|
578
|
+
{
|
579
|
+
const nxJsonMessage = await (0, resolve_nx_json_error_message_1.resolveNxJsonConfigErrorMessage)([
|
580
|
+
'release',
|
581
|
+
]);
|
582
|
+
output_1.output.error({
|
583
|
+
title: `Your "changelog.createRelease" config specifies an invalid hostname "${error.data.hostname}". Please ensure you provide a valid hostname value, such as "example.com"`,
|
584
|
+
bodyLines: [nxJsonMessage],
|
585
|
+
});
|
586
|
+
}
|
587
|
+
break;
|
588
|
+
case 'INVALID_CHANGELOG_CREATE_RELEASE_API_BASE_URL':
|
589
|
+
{
|
590
|
+
const nxJsonMessage = await (0, resolve_nx_json_error_message_1.resolveNxJsonConfigErrorMessage)([
|
591
|
+
'release',
|
592
|
+
]);
|
593
|
+
output_1.output.error({
|
594
|
+
title: `Your "changelog.createRelease" config specifies an invalid apiBaseUrl "${error.data.apiBaseUrl}". Please ensure you provide a valid URL value, such as "https://example.com"`,
|
595
|
+
bodyLines: [nxJsonMessage],
|
596
|
+
});
|
597
|
+
}
|
598
|
+
break;
|
550
599
|
default:
|
551
600
|
throw new Error(`Unhandled error code: ${error.code}`);
|
552
601
|
}
|
@@ -678,42 +727,138 @@ function isProjectPublic(project, projectGraph, projectFileMap) {
|
|
678
727
|
return false;
|
679
728
|
}
|
680
729
|
}
|
681
|
-
|
730
|
+
/**
|
731
|
+
* We need to ensure that changelog renderers are resolvable up front so that we do not end up erroring after performing
|
732
|
+
* actions later, and we also make sure that any configured createRelease options are valid.
|
733
|
+
*
|
734
|
+
* For the createRelease config, we also set a default apiBaseUrl if applicable.
|
735
|
+
*/
|
736
|
+
function validateChangelogConfig(releaseGroups, rootChangelogConfig) {
|
682
737
|
/**
|
683
738
|
* If any form of changelog config is enabled, ensure that any provided changelog renderers are resolvable
|
684
739
|
* up front so that we do not end up erroring only after the versioning step has been completed.
|
685
740
|
*/
|
686
741
|
const uniqueRendererPaths = new Set();
|
687
742
|
if (rootChangelogConfig.workspaceChangelog &&
|
688
|
-
typeof rootChangelogConfig.workspaceChangelog !== 'boolean'
|
689
|
-
rootChangelogConfig.workspaceChangelog.renderer?.length) {
|
690
|
-
|
743
|
+
typeof rootChangelogConfig.workspaceChangelog !== 'boolean') {
|
744
|
+
if (rootChangelogConfig.workspaceChangelog.renderer?.length) {
|
745
|
+
uniqueRendererPaths.add(rootChangelogConfig.workspaceChangelog.renderer);
|
746
|
+
}
|
747
|
+
const createReleaseError = validateCreateReleaseConfig(rootChangelogConfig.workspaceChangelog);
|
748
|
+
if (createReleaseError) {
|
749
|
+
return createReleaseError;
|
750
|
+
}
|
691
751
|
}
|
692
752
|
if (rootChangelogConfig.projectChangelogs &&
|
693
|
-
typeof rootChangelogConfig.projectChangelogs !== 'boolean'
|
694
|
-
rootChangelogConfig.projectChangelogs.renderer?.length) {
|
695
|
-
|
753
|
+
typeof rootChangelogConfig.projectChangelogs !== 'boolean') {
|
754
|
+
if (rootChangelogConfig.projectChangelogs.renderer?.length) {
|
755
|
+
uniqueRendererPaths.add(rootChangelogConfig.projectChangelogs.renderer);
|
756
|
+
}
|
757
|
+
const createReleaseError = validateCreateReleaseConfig(rootChangelogConfig.projectChangelogs);
|
758
|
+
if (createReleaseError) {
|
759
|
+
return createReleaseError;
|
760
|
+
}
|
696
761
|
}
|
697
762
|
for (const group of Object.values(releaseGroups)) {
|
698
|
-
if (group.changelog &&
|
699
|
-
|
700
|
-
|
701
|
-
|
763
|
+
if (group.changelog && typeof group.changelog !== 'boolean') {
|
764
|
+
if (group.changelog.renderer?.length) {
|
765
|
+
uniqueRendererPaths.add(group.changelog.renderer);
|
766
|
+
}
|
767
|
+
const createReleaseError = validateCreateReleaseConfig(group.changelog);
|
768
|
+
if (createReleaseError) {
|
769
|
+
return createReleaseError;
|
770
|
+
}
|
702
771
|
}
|
703
772
|
}
|
704
773
|
if (!uniqueRendererPaths.size) {
|
705
|
-
return;
|
774
|
+
return null;
|
706
775
|
}
|
707
776
|
for (const rendererPath of uniqueRendererPaths) {
|
708
777
|
try {
|
709
778
|
(0, resolve_changelog_renderer_1.resolveChangelogRenderer)(rendererPath);
|
710
779
|
}
|
711
|
-
catch
|
712
|
-
|
713
|
-
|
714
|
-
|
715
|
-
|
716
|
-
|
780
|
+
catch {
|
781
|
+
return {
|
782
|
+
code: 'CANNOT_RESOLVE_CHANGELOG_RENDERER',
|
783
|
+
data: {
|
784
|
+
workspaceRelativePath: (0, node_path_1.relative)(workspace_root_1.workspaceRoot, rendererPath),
|
785
|
+
},
|
786
|
+
};
|
717
787
|
}
|
718
788
|
}
|
789
|
+
return null;
|
790
|
+
}
|
791
|
+
const supportedCreateReleaseProviders = [
|
792
|
+
{
|
793
|
+
name: 'github-enterprise-server',
|
794
|
+
defaultApiBaseUrl: 'https://__hostname__/api/v3',
|
795
|
+
},
|
796
|
+
];
|
797
|
+
// User opts into the default by specifying the string value 'github'
|
798
|
+
exports.defaultCreateReleaseProvider = {
|
799
|
+
provider: 'github',
|
800
|
+
hostname: 'github.com',
|
801
|
+
apiBaseUrl: 'https://api.github.com',
|
802
|
+
};
|
803
|
+
function validateCreateReleaseConfig(changelogConfig) {
|
804
|
+
const createRelease = changelogConfig.createRelease;
|
805
|
+
// Disabled: valid
|
806
|
+
if (!createRelease) {
|
807
|
+
return null;
|
808
|
+
}
|
809
|
+
// GitHub shorthand, expand to full object form, mark as valid
|
810
|
+
if (createRelease === 'github') {
|
811
|
+
changelogConfig.createRelease = exports.defaultCreateReleaseProvider;
|
812
|
+
return null;
|
813
|
+
}
|
814
|
+
// Object config, ensure that properties are valid
|
815
|
+
const supportedProvider = supportedCreateReleaseProviders.find((p) => p.name === createRelease.provider);
|
816
|
+
if (!supportedProvider) {
|
817
|
+
return {
|
818
|
+
code: 'INVALID_CHANGELOG_CREATE_RELEASE_PROVIDER',
|
819
|
+
data: {
|
820
|
+
provider: createRelease.provider,
|
821
|
+
supportedProviders: supportedCreateReleaseProviders.map((p) => p.name),
|
822
|
+
},
|
823
|
+
};
|
824
|
+
}
|
825
|
+
if (!isValidHostname(createRelease.hostname)) {
|
826
|
+
return {
|
827
|
+
code: 'INVALID_CHANGELOG_CREATE_RELEASE_HOSTNAME',
|
828
|
+
data: {
|
829
|
+
hostname: createRelease.hostname,
|
830
|
+
},
|
831
|
+
};
|
832
|
+
}
|
833
|
+
// user provided a custom apiBaseUrl, ensure it is valid (accounting for empty string case)
|
834
|
+
if (createRelease.apiBaseUrl ||
|
835
|
+
typeof createRelease.apiBaseUrl === 'string') {
|
836
|
+
if (!isValidUrl(createRelease.apiBaseUrl)) {
|
837
|
+
return {
|
838
|
+
code: 'INVALID_CHANGELOG_CREATE_RELEASE_API_BASE_URL',
|
839
|
+
data: {
|
840
|
+
apiBaseUrl: createRelease.apiBaseUrl,
|
841
|
+
},
|
842
|
+
};
|
843
|
+
}
|
844
|
+
}
|
845
|
+
else {
|
846
|
+
// Set default apiBaseUrl when not provided by the user
|
847
|
+
createRelease.apiBaseUrl = supportedProvider.defaultApiBaseUrl.replace('__hostname__', createRelease.hostname);
|
848
|
+
}
|
849
|
+
return null;
|
850
|
+
}
|
851
|
+
function isValidHostname(hostname) {
|
852
|
+
// Regular expression to match a valid hostname
|
853
|
+
const hostnameRegex = /^(?!:\/\/)(?=.{1,255}$)(?!.*\.$)(?!.*?\.\.)(?!.*?-$)(?!^-)([a-zA-Z0-9-]{1,63}\.?)+[a-zA-Z]{2,}$/;
|
854
|
+
return hostnameRegex.test(hostname);
|
855
|
+
}
|
856
|
+
function isValidUrl(str) {
|
857
|
+
try {
|
858
|
+
new node_url_1.URL(str);
|
859
|
+
return true;
|
860
|
+
}
|
861
|
+
catch {
|
862
|
+
return false;
|
863
|
+
}
|
719
864
|
}
|
@@ -168,7 +168,9 @@ function createAPI(overrideReleaseConfig) {
|
|
168
168
|
hasPushedChanges = true;
|
169
169
|
output_1.output.logSingleLine(`Creating GitHub Release`);
|
170
170
|
latestCommit = await (0, git_1.getCommitHash)('HEAD');
|
171
|
-
await (0, github_1.createOrUpdateGithubRelease)(
|
171
|
+
await (0, github_1.createOrUpdateGithubRelease)(nxReleaseConfig.changelog.workspaceChangelog
|
172
|
+
? nxReleaseConfig.changelog.workspaceChangelog.createRelease
|
173
|
+
: false, changelogResult.workspaceChangelog.releaseVersion, changelogResult.workspaceChangelog.contents, latestCommit, { dryRun: args.dryRun });
|
172
174
|
}
|
173
175
|
for (const releaseGroup of releaseGroups) {
|
174
176
|
const shouldCreateProjectReleases = (0, changelog_1.shouldCreateGitHubRelease)(releaseGroup.changelog);
|
@@ -197,7 +199,9 @@ function createAPI(overrideReleaseConfig) {
|
|
197
199
|
if (!latestCommit) {
|
198
200
|
latestCommit = await (0, git_1.getCommitHash)('HEAD');
|
199
201
|
}
|
200
|
-
await (0, github_1.createOrUpdateGithubRelease)(
|
202
|
+
await (0, github_1.createOrUpdateGithubRelease)(releaseGroup.changelog
|
203
|
+
? releaseGroup.changelog.createRelease
|
204
|
+
: false, changelog.releaseVersion, changelog.contents, latestCommit, { dryRun: args.dryRun });
|
201
205
|
}
|
202
206
|
}
|
203
207
|
}
|
@@ -1,11 +1,14 @@
|
|
1
|
+
import { NxReleaseChangelogConfiguration } from '../../../config/nx-json';
|
1
2
|
import { Reference } from './git';
|
2
3
|
import { ReleaseVersion } from './shared';
|
3
4
|
export type RepoSlug = `${string}/${string}`;
|
4
|
-
|
5
|
+
interface GithubRequestConfig {
|
5
6
|
repo: string;
|
7
|
+
hostname: string;
|
8
|
+
apiBaseUrl: string;
|
6
9
|
token: string | null;
|
7
10
|
}
|
8
|
-
|
11
|
+
interface GithubRelease {
|
9
12
|
id?: string;
|
10
13
|
tag_name: string;
|
11
14
|
target_commitish?: string;
|
@@ -14,10 +17,15 @@ export interface GithubRelease {
|
|
14
17
|
draft?: boolean;
|
15
18
|
prerelease?: boolean;
|
16
19
|
}
|
17
|
-
export
|
18
|
-
|
20
|
+
export interface GithubRepoData {
|
21
|
+
hostname: string;
|
22
|
+
slug: RepoSlug;
|
23
|
+
apiBaseUrl: string;
|
24
|
+
}
|
25
|
+
export declare function getGitHubRepoData(remoteName: string, createReleaseConfig: NxReleaseChangelogConfiguration['createRelease']): GithubRepoData | null;
|
26
|
+
export declare function createOrUpdateGithubRelease(createReleaseConfig: NxReleaseChangelogConfiguration['createRelease'], releaseVersion: ReleaseVersion, changelogContents: string, latestCommit: string, { dryRun }: {
|
19
27
|
dryRun: boolean;
|
20
28
|
}): Promise<void>;
|
21
|
-
export declare function resolveGithubToken(): Promise<string | null>;
|
22
29
|
export declare function getGithubReleaseByTag(config: GithubRequestConfig, tag: string): Promise<GithubRelease>;
|
23
|
-
export declare function formatReferences(references: Reference[],
|
30
|
+
export declare function formatReferences(references: Reference[], repoData: GithubRepoData): string;
|
31
|
+
export {};
|