nx 18.1.0-canary.20240313-81df848 → 18.1.0-canary.20240315-3b8cbae
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 +2 -0
- package/release/changelog-renderer/index.js +4 -18
- package/schemas/nx-schema.json +52 -0
- package/src/command-line/release/changelog.js +15 -13
- package/src/command-line/release/config/config.d.ts +10 -0
- package/src/command-line/release/config/config.js +85 -0
- package/src/command-line/release/config/conventional-commits.d.ts +2 -0
- package/src/command-line/release/config/conventional-commits.js +98 -0
- package/src/command-line/release/utils/resolve-semver-specifier.d.ts +2 -1
- package/src/command-line/release/utils/resolve-semver-specifier.js +2 -13
- package/src/command-line/release/utils/semver.d.ts +2 -8
- package/src/command-line/release/utils/semver.js +4 -1
- package/src/command-line/release/version.d.ts +2 -0
- package/src/command-line/release/version.js +4 -3
- package/src/config/nx-json.d.ts +25 -0
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "nx",
|
3
|
-
"version": "18.1.0-canary.
|
3
|
+
"version": "18.1.0-canary.20240315-3b8cbae",
|
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": {
|
@@ -66,7 +66,7 @@
|
|
66
66
|
"yargs-parser": "21.1.1",
|
67
67
|
"node-machine-id": "1.1.12",
|
68
68
|
"ora": "5.3.0",
|
69
|
-
"@nrwl/tao": "18.1.0-canary.
|
69
|
+
"@nrwl/tao": "18.1.0-canary.20240315-3b8cbae"
|
70
70
|
},
|
71
71
|
"peerDependencies": {
|
72
72
|
"@swc-node/register": "^1.8.0",
|
@@ -81,16 +81,16 @@
|
|
81
81
|
}
|
82
82
|
},
|
83
83
|
"optionalDependencies": {
|
84
|
-
"@nx/nx-darwin-x64": "18.1.0-canary.
|
85
|
-
"@nx/nx-darwin-arm64": "18.1.0-canary.
|
86
|
-
"@nx/nx-linux-x64-gnu": "18.1.0-canary.
|
87
|
-
"@nx/nx-linux-x64-musl": "18.1.0-canary.
|
88
|
-
"@nx/nx-win32-x64-msvc": "18.1.0-canary.
|
89
|
-
"@nx/nx-linux-arm64-gnu": "18.1.0-canary.
|
90
|
-
"@nx/nx-linux-arm64-musl": "18.1.0-canary.
|
91
|
-
"@nx/nx-linux-arm-gnueabihf": "18.1.0-canary.
|
92
|
-
"@nx/nx-win32-arm64-msvc": "18.1.0-canary.
|
93
|
-
"@nx/nx-freebsd-x64": "18.1.0-canary.
|
84
|
+
"@nx/nx-darwin-x64": "18.1.0-canary.20240315-3b8cbae",
|
85
|
+
"@nx/nx-darwin-arm64": "18.1.0-canary.20240315-3b8cbae",
|
86
|
+
"@nx/nx-linux-x64-gnu": "18.1.0-canary.20240315-3b8cbae",
|
87
|
+
"@nx/nx-linux-x64-musl": "18.1.0-canary.20240315-3b8cbae",
|
88
|
+
"@nx/nx-win32-x64-msvc": "18.1.0-canary.20240315-3b8cbae",
|
89
|
+
"@nx/nx-linux-arm64-gnu": "18.1.0-canary.20240315-3b8cbae",
|
90
|
+
"@nx/nx-linux-arm64-musl": "18.1.0-canary.20240315-3b8cbae",
|
91
|
+
"@nx/nx-linux-arm-gnueabihf": "18.1.0-canary.20240315-3b8cbae",
|
92
|
+
"@nx/nx-win32-arm64-msvc": "18.1.0-canary.20240315-3b8cbae",
|
93
|
+
"@nx/nx-freebsd-x64": "18.1.0-canary.20240315-3b8cbae"
|
94
94
|
},
|
95
95
|
"nx-migrations": {
|
96
96
|
"migrations": "./migrations.json",
|
@@ -1,3 +1,4 @@
|
|
1
|
+
import { NxReleaseConfig } from '../../src/command-line/release/config/config';
|
1
2
|
import type { GitCommit } from '../../src/command-line/release/utils/git';
|
2
3
|
import { RepoSlug } from '../../src/command-line/release/utils/github';
|
3
4
|
import type { ProjectGraph } from '../../src/config/project-graph';
|
@@ -26,6 +27,7 @@ export type ChangelogRenderer = (config: {
|
|
26
27
|
entryWhenNoChanges: string | false;
|
27
28
|
changelogRenderOptions: DefaultChangelogRenderOptions;
|
28
29
|
repoSlug?: RepoSlug;
|
30
|
+
conventionalCommitsConfig: NxReleaseConfig['conventionalCommits'];
|
29
31
|
}) => Promise<string> | string;
|
30
32
|
/**
|
31
33
|
* The specific options available to the default implementation of the ChangelogRenderer that nx exports
|
@@ -10,24 +10,10 @@ 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, commits, releaseVersion, project, entryWhenNoChanges, changelogRenderOptions, repoSlug, }) => {
|
13
|
+
const defaultChangelogRenderer = async ({ projectGraph, commits, releaseVersion, project, entryWhenNoChanges, changelogRenderOptions, repoSlug, conventionalCommitsConfig, }) => {
|
14
|
+
const commitTypes = conventionalCommitsConfig.types;
|
14
15
|
const markdownLines = [];
|
15
16
|
const breakingChanges = [];
|
16
|
-
const commitTypes = {
|
17
|
-
feat: { title: '🚀 Features' },
|
18
|
-
perf: { title: '🔥 Performance' },
|
19
|
-
fix: { title: '🩹 Fixes' },
|
20
|
-
refactor: { title: '💅 Refactors' },
|
21
|
-
docs: { title: '📖 Documentation' },
|
22
|
-
build: { title: '📦 Build' },
|
23
|
-
types: { title: '🌊 Types' },
|
24
|
-
chore: { title: '🏡 Chore' },
|
25
|
-
examples: { title: '🏀 Examples' },
|
26
|
-
test: { title: '✅ Tests' },
|
27
|
-
style: { title: '🎨 Styles' },
|
28
|
-
ci: { title: '🤖 CI' },
|
29
|
-
revert: { title: '⏪ Revert' },
|
30
|
-
};
|
31
17
|
// If the current range of commits contains both a commit and its revert, we strip them both from the final list
|
32
18
|
for (const commit of commits) {
|
33
19
|
if (commit.type === 'revert') {
|
@@ -56,7 +42,7 @@ const defaultChangelogRenderer = async ({ projectGraph, commits, releaseVersion,
|
|
56
42
|
if (!group || group.length === 0) {
|
57
43
|
continue;
|
58
44
|
}
|
59
|
-
markdownLines.push('', '### ' + commitTypes[type].title, '');
|
45
|
+
markdownLines.push('', '### ' + commitTypes[type].changelog.title, '');
|
60
46
|
/**
|
61
47
|
* In order to make the final changelog most readable, we organize commits as follows:
|
62
48
|
* - By scope, where scopes are in alphabetical order (commits with no scope are listed first)
|
@@ -99,7 +85,7 @@ const defaultChangelogRenderer = async ({ projectGraph, commits, releaseVersion,
|
|
99
85
|
if (!group || group.length === 0) {
|
100
86
|
continue;
|
101
87
|
}
|
102
|
-
markdownLines.push('', `### ${commitTypes[type].title}`, '');
|
88
|
+
markdownLines.push('', `### ${commitTypes[type].changelog.title}`, '');
|
103
89
|
const commitsInChronologicalOrder = group.reverse();
|
104
90
|
for (const commit of commitsInChronologicalOrder) {
|
105
91
|
const line = formatCommit(commit, changelogRenderOptions, repoSlug);
|
package/schemas/nx-schema.json
CHANGED
@@ -221,6 +221,9 @@
|
|
221
221
|
}
|
222
222
|
}
|
223
223
|
},
|
224
|
+
"conventionalCommits": {
|
225
|
+
"$ref": "#/definitions/NxReleaseConventionalCommitsConfiguration"
|
226
|
+
},
|
224
227
|
"projectsRelationship": {
|
225
228
|
"type": "string",
|
226
229
|
"enum": ["fixed", "independent"]
|
@@ -636,6 +639,55 @@
|
|
636
639
|
"ChangelogRenderOptions": {
|
637
640
|
"type": "object",
|
638
641
|
"additionalProperties": true
|
642
|
+
},
|
643
|
+
"NxReleaseConventionalCommitsConfiguration": {
|
644
|
+
"type": "object",
|
645
|
+
"properties": {
|
646
|
+
"types": {
|
647
|
+
"type": "object",
|
648
|
+
"description": "A map of commit types to their configuration. If a type is set to 'true', then it will be enabled with the default 'semverBump' of 'patch' and will appear in the changelog. If a type is set to 'false', then it will not trigger a version bump and will be hidden from the changelog.",
|
649
|
+
"additionalProperties": {
|
650
|
+
"oneOf": [
|
651
|
+
{
|
652
|
+
"type": "boolean"
|
653
|
+
},
|
654
|
+
{
|
655
|
+
"type": "object",
|
656
|
+
"properties": {
|
657
|
+
"semverBump": {
|
658
|
+
"type": "string",
|
659
|
+
"enum": ["major", "minor", "patch", "none"],
|
660
|
+
"description": "The semver bump to apply to the version of the project(s) when a commit of this type is included in the release.",
|
661
|
+
"default": "patch"
|
662
|
+
},
|
663
|
+
"changelog": {
|
664
|
+
"description": "Configuration for the changelog section for commits of this type. If set to 'true', then commits of this type will be included in the changelog with their default title for the type. If set to 'false', then commits of this type will not be included in the changelog.",
|
665
|
+
"oneOf": [
|
666
|
+
{
|
667
|
+
"type": "boolean"
|
668
|
+
},
|
669
|
+
{
|
670
|
+
"type": "object",
|
671
|
+
"properties": {
|
672
|
+
"title": {
|
673
|
+
"type": "string",
|
674
|
+
"description": "The title of the section in the changelog for commits of this type"
|
675
|
+
},
|
676
|
+
"hidden": {
|
677
|
+
"type": "boolean",
|
678
|
+
"description": "Whether or not to include commits of this type in the changelog",
|
679
|
+
"default": false
|
680
|
+
}
|
681
|
+
}
|
682
|
+
}
|
683
|
+
]
|
684
|
+
}
|
685
|
+
}
|
686
|
+
}
|
687
|
+
]
|
688
|
+
}
|
689
|
+
}
|
690
|
+
}
|
639
691
|
}
|
640
692
|
}
|
641
693
|
}
|
@@ -130,7 +130,7 @@ async function releaseChangelog(args) {
|
|
130
130
|
}
|
131
131
|
// Make sure that the fromRef is actually resolvable
|
132
132
|
const workspaceChangelogFromSHA = await (0, git_1.getCommitHash)(workspaceChangelogFromRef);
|
133
|
-
const workspaceChangelogCommits = await getCommits(workspaceChangelogFromSHA, toSHA);
|
133
|
+
const workspaceChangelogCommits = await getCommits(workspaceChangelogFromSHA, toSHA, nxReleaseConfig.conventionalCommits);
|
134
134
|
const workspaceChangelog = await generateChangelogForWorkspace(tree, args, projectGraph, nxReleaseConfig, workspaceChangelogVersion, workspaceChangelogCommits);
|
135
135
|
if (workspaceChangelog &&
|
136
136
|
shouldCreateGitHubRelease(nxReleaseConfig.changelog.workspaceChangelog, args.createRelease)) {
|
@@ -172,7 +172,7 @@ async function releaseChangelog(args) {
|
|
172
172
|
let commits = null;
|
173
173
|
if (!fromRef && useAutomaticFromRef) {
|
174
174
|
const firstCommit = await (0, git_1.getFirstGitCommit)();
|
175
|
-
const allCommits = await getCommits(firstCommit, toSHA);
|
175
|
+
const allCommits = await getCommits(firstCommit, toSHA, nxReleaseConfig.conventionalCommits);
|
176
176
|
const commitsForProject = allCommits.filter((c) => c.affectedFiles.find((f) => f.startsWith(project.data.root)));
|
177
177
|
fromRef = commitsForProject[0]?.shortHash;
|
178
178
|
if (args.verbose) {
|
@@ -184,9 +184,9 @@ async function releaseChangelog(args) {
|
|
184
184
|
throw new Error(`Unable to determine the previous git tag. If this is the first release of your workspace, use the --first-release option or set the "release.changelog.automaticFromRef" config property in nx.json to generate a changelog from the first commit. Otherwise, be sure to configure the "release.releaseTagPattern" property in nx.json to match the structure of your repository's git tags.`);
|
185
185
|
}
|
186
186
|
if (!commits) {
|
187
|
-
commits = await getCommits(fromRef, toSHA);
|
187
|
+
commits = await getCommits(fromRef, toSHA, nxReleaseConfig.conventionalCommits);
|
188
188
|
}
|
189
|
-
const projectChangelogs = await generateChangelogForProjects(tree, args, projectGraph, commits, projectsVersionData,
|
189
|
+
const projectChangelogs = await generateChangelogForProjects(tree, args, projectGraph, commits, projectsVersionData, releaseGroup, [project], nxReleaseConfig);
|
190
190
|
let hasPushed = false;
|
191
191
|
for (const [projectName, projectChangelog] of Object.entries(projectChangelogs)) {
|
192
192
|
if (projectChangelogs &&
|
@@ -218,8 +218,8 @@ async function releaseChangelog(args) {
|
|
218
218
|
}
|
219
219
|
// Make sure that the fromRef is actually resolvable
|
220
220
|
const fromSHA = await (0, git_1.getCommitHash)(fromRef);
|
221
|
-
const commits = await getCommits(fromSHA, toSHA);
|
222
|
-
const projectChangelogs = await generateChangelogForProjects(tree, args, projectGraph, commits, projectsVersionData,
|
221
|
+
const commits = await getCommits(fromSHA, toSHA, nxReleaseConfig.conventionalCommits);
|
222
|
+
const projectChangelogs = await generateChangelogForProjects(tree, args, projectGraph, commits, projectsVersionData, releaseGroup, projectNodes, nxReleaseConfig);
|
223
223
|
let hasPushed = false;
|
224
224
|
for (const [projectName, projectChangelog] of Object.entries(projectChangelogs)) {
|
225
225
|
if (projectChangelogs &&
|
@@ -449,6 +449,7 @@ async function generateChangelogForWorkspace(tree, args, projectGraph, nxRelease
|
|
449
449
|
repoSlug: githubRepoSlug,
|
450
450
|
entryWhenNoChanges: config.entryWhenNoChanges,
|
451
451
|
changelogRenderOptions: config.renderOptions,
|
452
|
+
conventionalCommitsConfig: nxReleaseConfig.conventionalCommits,
|
452
453
|
});
|
453
454
|
/**
|
454
455
|
* If interactive mode, make the changelog contents available for the user to modify in their editor of choice,
|
@@ -491,7 +492,7 @@ async function generateChangelogForWorkspace(tree, args, projectGraph, nxRelease
|
|
491
492
|
contents,
|
492
493
|
};
|
493
494
|
}
|
494
|
-
async function generateChangelogForProjects(tree, args, projectGraph, commits, projectsVersionData,
|
495
|
+
async function generateChangelogForProjects(tree, args, projectGraph, commits, projectsVersionData, releaseGroup, projects, nxReleaseConfig) {
|
495
496
|
const config = releaseGroup.changelog;
|
496
497
|
// The entire feature is disabled at the release group level, exit early
|
497
498
|
if (config === false) {
|
@@ -547,6 +548,7 @@ async function generateChangelogForProjects(tree, args, projectGraph, commits, p
|
|
547
548
|
})
|
548
549
|
: false,
|
549
550
|
changelogRenderOptions: config.renderOptions,
|
551
|
+
conventionalCommitsConfig: nxReleaseConfig.conventionalCommits,
|
550
552
|
});
|
551
553
|
/**
|
552
554
|
* If interactive mode, make the changelog contents available for the user to modify in their editor of choice,
|
@@ -605,17 +607,17 @@ function checkChangelogFilesEnabled(nxReleaseConfig) {
|
|
605
607
|
}
|
606
608
|
return false;
|
607
609
|
}
|
608
|
-
async function getCommits(fromSHA, toSHA) {
|
610
|
+
async function getCommits(fromSHA, toSHA, conventionalCommitsConfig) {
|
609
611
|
const rawCommits = await (0, git_1.getGitDiff)(fromSHA, toSHA);
|
610
612
|
// Parse as conventional commits
|
611
613
|
return (0, git_1.parseCommits)(rawCommits).filter((c) => {
|
612
614
|
const type = c.type;
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
return
|
615
|
+
const typeConfig = conventionalCommitsConfig.types[type];
|
616
|
+
if (!typeConfig) {
|
617
|
+
// don't include commits with unknown types
|
618
|
+
return false;
|
617
619
|
}
|
618
|
-
return
|
620
|
+
return !typeConfig.changelog.hidden;
|
619
621
|
});
|
620
622
|
}
|
621
623
|
function shouldCreateGitHubRelease(changelogConfig, createReleaseArg = undefined) {
|
@@ -17,6 +17,13 @@ type RemoveTrueFromProperties<T, K extends keyof T> = {
|
|
17
17
|
type RemoveTrueFromPropertiesOnEach<T, K extends keyof T[keyof T]> = {
|
18
18
|
[U in keyof T]: RemoveTrueFromProperties<T[U], K>;
|
19
19
|
};
|
20
|
+
type RemoveBooleanFromType<T> = T extends boolean ? never : T;
|
21
|
+
type RemoveBooleanFromProperties<T, K extends keyof T> = {
|
22
|
+
[P in keyof T]: P extends K ? RemoveBooleanFromType<T[P]> : T[P];
|
23
|
+
};
|
24
|
+
type RemoveBooleanFromPropertiesOnEach<T, K extends keyof T[keyof T]> = {
|
25
|
+
[U in keyof T]: RemoveBooleanFromProperties<T[U], K>;
|
26
|
+
};
|
20
27
|
export declare const IMPLICIT_DEFAULT_RELEASE_GROUP = "__default__";
|
21
28
|
/**
|
22
29
|
* Our source of truth is a deeply required variant of the user-facing config interface, so that command
|
@@ -30,6 +37,9 @@ export declare const IMPLICIT_DEFAULT_RELEASE_GROUP = "__default__";
|
|
30
37
|
export type NxReleaseConfig = Omit<DeepRequired<NxJsonConfiguration['release'] & {
|
31
38
|
groups: DeepRequired<RemoveTrueFromPropertiesOnEach<EnsureProjectsArray<NxJsonConfiguration['release']['groups']>, 'changelog'>>;
|
32
39
|
changelog: RemoveTrueFromProperties<DeepRequired<NxJsonConfiguration['release']['changelog']>, 'workspaceChangelog' | 'projectChangelogs'>;
|
40
|
+
conventionalCommits: {
|
41
|
+
types: RemoveBooleanFromPropertiesOnEach<DeepRequired<RemoveBooleanFromProperties<DeepRequired<NxJsonConfiguration['release']['conventionalCommits']['types']>, string>>, 'changelog'>;
|
42
|
+
};
|
33
43
|
}>, 'projects'>;
|
34
44
|
export interface CreateNxReleaseConfigError {
|
35
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';
|
@@ -20,6 +20,7 @@ const find_matching_projects_1 = require("../../../utils/find-matching-projects"
|
|
20
20
|
const output_1 = require("../../../utils/output");
|
21
21
|
const workspace_root_1 = require("../../../utils/workspace-root");
|
22
22
|
const resolve_nx_json_error_message_1 = require("../utils/resolve-nx-json-error-message");
|
23
|
+
const conventional_commits_1 = require("./conventional-commits");
|
23
24
|
exports.IMPLICIT_DEFAULT_RELEASE_GROUP = '__default__';
|
24
25
|
// Apply default configuration to any optional user configuration and handle known errors
|
25
26
|
async function createNxReleaseConfig(projectGraph, projectFileMap, userConfig = {}) {
|
@@ -130,6 +131,7 @@ async function createNxReleaseConfig(projectGraph, projectFileMap, userConfig =
|
|
130
131
|
(workspaceProjectsRelationship === 'independent'
|
131
132
|
? defaultIndependentReleaseTagPattern
|
132
133
|
: defaultFixedReleaseTagPattern),
|
134
|
+
conventionalCommits: conventional_commits_1.DEFAULT_CONVENTIONAL_COMMITS_CONFIG,
|
133
135
|
};
|
134
136
|
const groupProjectsRelationship = userConfig.projectsRelationship || WORKSPACE_DEFAULTS.projectsRelationship;
|
135
137
|
const GROUP_DEFAULTS = {
|
@@ -183,6 +185,7 @@ async function createNxReleaseConfig(projectGraph, projectFileMap, userConfig =
|
|
183
185
|
git: userConfig.git,
|
184
186
|
},
|
185
187
|
], normalizeTrueToEmptyObject(userConfig.changelog));
|
188
|
+
const rootConventionalCommitsConfig = deepMergeDefaults([WORKSPACE_DEFAULTS.conventionalCommits], fillUnspecifiedConventionalCommitsProperties(normalizeConventionalCommitsConfig(userConfig.conventionalCommits)));
|
186
189
|
// these options are not supported at the group level, only the root/command level
|
187
190
|
const rootVersionWithoutGlobalOptions = { ...rootVersionConfig };
|
188
191
|
delete rootVersionWithoutGlobalOptions.git;
|
@@ -323,6 +326,7 @@ async function createNxReleaseConfig(projectGraph, projectFileMap, userConfig =
|
|
323
326
|
version: rootVersionConfig,
|
324
327
|
changelog: rootChangelogConfig,
|
325
328
|
groups: releaseGroups,
|
329
|
+
conventionalCommits: rootConventionalCommitsConfig,
|
326
330
|
},
|
327
331
|
};
|
328
332
|
}
|
@@ -335,6 +339,87 @@ exports.createNxReleaseConfig = createNxReleaseConfig;
|
|
335
339
|
function normalizeTrueToEmptyObject(value) {
|
336
340
|
return value === true ? {} : value;
|
337
341
|
}
|
342
|
+
function normalizeConventionalCommitsConfig(userConventionalCommitsConfig) {
|
343
|
+
if (!userConventionalCommitsConfig || !userConventionalCommitsConfig.types) {
|
344
|
+
return userConventionalCommitsConfig;
|
345
|
+
}
|
346
|
+
const types = {};
|
347
|
+
for (const [t, typeConfig] of Object.entries(userConventionalCommitsConfig.types)) {
|
348
|
+
if (typeConfig === false) {
|
349
|
+
types[t] = {
|
350
|
+
semverBump: 'none',
|
351
|
+
changelog: {
|
352
|
+
hidden: true,
|
353
|
+
},
|
354
|
+
};
|
355
|
+
continue;
|
356
|
+
}
|
357
|
+
if (typeConfig === true) {
|
358
|
+
types[t] = {};
|
359
|
+
continue;
|
360
|
+
}
|
361
|
+
if (typeConfig.changelog === false) {
|
362
|
+
types[t] = {
|
363
|
+
...typeConfig,
|
364
|
+
changelog: {
|
365
|
+
hidden: true,
|
366
|
+
},
|
367
|
+
};
|
368
|
+
continue;
|
369
|
+
}
|
370
|
+
if (typeConfig.changelog === true) {
|
371
|
+
types[t] = {
|
372
|
+
...typeConfig,
|
373
|
+
changelog: {},
|
374
|
+
};
|
375
|
+
continue;
|
376
|
+
}
|
377
|
+
types[t] = typeConfig;
|
378
|
+
}
|
379
|
+
return {
|
380
|
+
...userConventionalCommitsConfig,
|
381
|
+
types,
|
382
|
+
};
|
383
|
+
}
|
384
|
+
/**
|
385
|
+
* New, custom types specified by users will not be given the appropriate
|
386
|
+
* defaults with `deepMergeDefaults`, so we need to fill in the gaps here.
|
387
|
+
*/
|
388
|
+
function fillUnspecifiedConventionalCommitsProperties(config) {
|
389
|
+
if (!config || !config.types) {
|
390
|
+
return config;
|
391
|
+
}
|
392
|
+
const types = {};
|
393
|
+
for (const [t, typeConfig] of Object.entries(config.types)) {
|
394
|
+
const defaultTypeConfig = conventional_commits_1.DEFAULT_CONVENTIONAL_COMMITS_CONFIG.types[t];
|
395
|
+
const semverBump = typeConfig.semverBump ||
|
396
|
+
// preserve our default semver bump if it's not 'none'
|
397
|
+
// this prevents a 'feat' from becoming a 'patch' just
|
398
|
+
// because they modified the changelog config for 'feat'
|
399
|
+
(defaultTypeConfig?.semverBump !== 'none' &&
|
400
|
+
defaultTypeConfig?.semverBump) ||
|
401
|
+
'patch';
|
402
|
+
// don't preserve our default behavior for hidden, ever.
|
403
|
+
// we should assume that if users are explicitly enabling a
|
404
|
+
// type, then they intend it to be visible in the changelog
|
405
|
+
const hidden = typeConfig.changelog?.hidden || false;
|
406
|
+
const title = typeConfig.changelog?.title ||
|
407
|
+
// our default title is better than just the unmodified type name
|
408
|
+
defaultTypeConfig?.changelog.title ||
|
409
|
+
t;
|
410
|
+
types[t] = {
|
411
|
+
semverBump,
|
412
|
+
changelog: {
|
413
|
+
hidden,
|
414
|
+
title,
|
415
|
+
},
|
416
|
+
};
|
417
|
+
}
|
418
|
+
return {
|
419
|
+
...config,
|
420
|
+
types,
|
421
|
+
};
|
422
|
+
}
|
338
423
|
async function handleNxReleaseConfigError(error) {
|
339
424
|
switch (error.code) {
|
340
425
|
case 'PROJECTS_AND_GROUPS_DEFINED':
|
@@ -0,0 +1,98 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.DEFAULT_CONVENTIONAL_COMMITS_CONFIG = void 0;
|
4
|
+
exports.DEFAULT_CONVENTIONAL_COMMITS_CONFIG = {
|
5
|
+
types: {
|
6
|
+
feat: {
|
7
|
+
semverBump: 'minor',
|
8
|
+
changelog: {
|
9
|
+
title: '🚀 Features',
|
10
|
+
hidden: false,
|
11
|
+
},
|
12
|
+
},
|
13
|
+
fix: {
|
14
|
+
semverBump: 'patch',
|
15
|
+
changelog: {
|
16
|
+
title: '🩹 Fixes',
|
17
|
+
hidden: false,
|
18
|
+
},
|
19
|
+
},
|
20
|
+
perf: {
|
21
|
+
semverBump: 'none',
|
22
|
+
changelog: {
|
23
|
+
title: '🔥 Performance',
|
24
|
+
hidden: false,
|
25
|
+
},
|
26
|
+
},
|
27
|
+
refactor: {
|
28
|
+
semverBump: 'none',
|
29
|
+
changelog: {
|
30
|
+
title: '💅 Refactors',
|
31
|
+
hidden: true,
|
32
|
+
},
|
33
|
+
},
|
34
|
+
docs: {
|
35
|
+
semverBump: 'none',
|
36
|
+
changelog: {
|
37
|
+
title: '📖 Documentation',
|
38
|
+
hidden: true,
|
39
|
+
},
|
40
|
+
},
|
41
|
+
build: {
|
42
|
+
semverBump: 'none',
|
43
|
+
changelog: {
|
44
|
+
title: '📦 Build',
|
45
|
+
hidden: true,
|
46
|
+
},
|
47
|
+
},
|
48
|
+
types: {
|
49
|
+
semverBump: 'none',
|
50
|
+
changelog: {
|
51
|
+
title: '🌊 Types',
|
52
|
+
hidden: true,
|
53
|
+
},
|
54
|
+
},
|
55
|
+
chore: {
|
56
|
+
semverBump: 'none',
|
57
|
+
changelog: {
|
58
|
+
title: '🏡 Chore',
|
59
|
+
hidden: true,
|
60
|
+
},
|
61
|
+
},
|
62
|
+
examples: {
|
63
|
+
semverBump: 'none',
|
64
|
+
changelog: {
|
65
|
+
title: '🏀 Examples',
|
66
|
+
hidden: true,
|
67
|
+
},
|
68
|
+
},
|
69
|
+
test: {
|
70
|
+
semverBump: 'none',
|
71
|
+
changelog: {
|
72
|
+
title: '✅ Tests',
|
73
|
+
hidden: true,
|
74
|
+
},
|
75
|
+
},
|
76
|
+
style: {
|
77
|
+
semverBump: 'none',
|
78
|
+
changelog: {
|
79
|
+
title: '🎨 Styles',
|
80
|
+
hidden: true,
|
81
|
+
},
|
82
|
+
},
|
83
|
+
ci: {
|
84
|
+
semverBump: 'none',
|
85
|
+
changelog: {
|
86
|
+
title: '🤖 CI',
|
87
|
+
hidden: true,
|
88
|
+
},
|
89
|
+
},
|
90
|
+
revert: {
|
91
|
+
semverBump: 'none',
|
92
|
+
changelog: {
|
93
|
+
title: '⏪ Revert',
|
94
|
+
hidden: true,
|
95
|
+
},
|
96
|
+
},
|
97
|
+
},
|
98
|
+
};
|
@@ -1,3 +1,4 @@
|
|
1
1
|
import { ProjectGraph } from '../../../config/project-graph';
|
2
|
-
|
2
|
+
import { NxReleaseConfig } from '../config/config';
|
3
|
+
export declare function resolveSemverSpecifierFromConventionalCommits(from: string, projectGraph: ProjectGraph, projectNames: string[], conventionalCommitsConfig: NxReleaseConfig['conventionalCommits']): Promise<string | null>;
|
3
4
|
export declare function resolveSemverSpecifierFromPrompt(selectionMessage: string, customVersionMessage: string): Promise<string>;
|
@@ -6,22 +6,11 @@ const semver_1 = require("semver");
|
|
6
6
|
const git_1 = require("./git");
|
7
7
|
const semver_2 = require("./semver");
|
8
8
|
const shared_1 = require("./shared");
|
9
|
-
|
10
|
-
const CONVENTIONAL_COMMITS_CONFIG = {
|
11
|
-
types: {
|
12
|
-
feat: {
|
13
|
-
semver: 'minor',
|
14
|
-
},
|
15
|
-
fix: {
|
16
|
-
semver: 'patch',
|
17
|
-
},
|
18
|
-
},
|
19
|
-
};
|
20
|
-
async function resolveSemverSpecifierFromConventionalCommits(from, projectGraph, projectNames) {
|
9
|
+
async function resolveSemverSpecifierFromConventionalCommits(from, projectGraph, projectNames, conventionalCommitsConfig) {
|
21
10
|
const commits = await (0, git_1.getGitDiff)(from);
|
22
11
|
const parsedCommits = (0, git_1.parseCommits)(commits);
|
23
12
|
const relevantCommits = await (0, shared_1.getCommitsRelevantToProjects)(projectGraph, parsedCommits, projectNames);
|
24
|
-
return (0, semver_2.determineSemverChange)(relevantCommits,
|
13
|
+
return (0, semver_2.determineSemverChange)(relevantCommits, conventionalCommitsConfig);
|
25
14
|
}
|
26
15
|
exports.resolveSemverSpecifierFromConventionalCommits = resolveSemverSpecifierFromConventionalCommits;
|
27
16
|
async function resolveSemverSpecifierFromPrompt(selectionMessage, customVersionMessage) {
|
@@ -3,15 +3,9 @@
|
|
3
3
|
* https://github.com/unjs/changelogen
|
4
4
|
*/
|
5
5
|
import { ReleaseType } from 'semver';
|
6
|
+
import { NxReleaseConfig } from '../config/config';
|
6
7
|
import { GitCommit } from './git';
|
7
8
|
export declare function isRelativeVersionKeyword(val: string): val is ReleaseType;
|
8
9
|
export declare function isValidSemverSpecifier(specifier: string): boolean;
|
9
|
-
export
|
10
|
-
types: {
|
11
|
-
[type: string]: {
|
12
|
-
semver: 'patch' | 'minor' | 'major';
|
13
|
-
};
|
14
|
-
};
|
15
|
-
}
|
16
|
-
export declare function determineSemverChange(commits: GitCommit[], config: ConventionalCommitsConfig): 'patch' | 'minor' | 'major' | null;
|
10
|
+
export declare function determineSemverChange(commits: GitCommit[], config: NxReleaseConfig['conventionalCommits']): 'patch' | 'minor' | 'major' | null;
|
17
11
|
export declare function deriveNewSemverVersion(currentSemverVersion: string, semverSpecifier: string, preid?: string): string;
|
@@ -18,7 +18,7 @@ exports.isValidSemverSpecifier = isValidSemverSpecifier;
|
|
18
18
|
function determineSemverChange(commits, config) {
|
19
19
|
let [hasMajor, hasMinor, hasPatch] = [false, false, false];
|
20
20
|
for (const commit of commits) {
|
21
|
-
const semverType = config.types[commit.type]?.
|
21
|
+
const semverType = config.types[commit.type]?.semverBump;
|
22
22
|
if (semverType === 'major' || commit.isBreaking) {
|
23
23
|
hasMajor = true;
|
24
24
|
}
|
@@ -28,6 +28,9 @@ function determineSemverChange(commits, config) {
|
|
28
28
|
else if (semverType === 'patch') {
|
29
29
|
hasPatch = true;
|
30
30
|
}
|
31
|
+
else if (semverType === 'none' || !semverType) {
|
32
|
+
// do not report a change
|
33
|
+
}
|
31
34
|
}
|
32
35
|
return hasMajor ? 'major' : hasMinor ? 'minor' : hasPatch ? 'patch' : null;
|
33
36
|
}
|
@@ -1,5 +1,6 @@
|
|
1
1
|
import { ProjectGraph, ProjectGraphProjectNode } from '../../config/project-graph';
|
2
2
|
import { VersionOptions } from './command-object';
|
3
|
+
import { NxReleaseConfig } from './config/config';
|
3
4
|
import { ReleaseGroupWithName } from './config/filter-release-groups';
|
4
5
|
import { VersionData } from './utils/shared';
|
5
6
|
export { deriveNewSemverVersion } from './utils/semver';
|
@@ -21,6 +22,7 @@ export interface ReleaseVersionGeneratorSchema {
|
|
21
22
|
skipLockFileUpdate?: boolean;
|
22
23
|
installArgs?: string;
|
23
24
|
installIgnoreScripts?: boolean;
|
25
|
+
conventionalCommitsConfig?: NxReleaseConfig['conventionalCommits'];
|
24
26
|
}
|
25
27
|
export interface NxReleaseVersionResult {
|
26
28
|
/**
|
@@ -97,7 +97,7 @@ async function releaseVersion(args) {
|
|
97
97
|
// all project data from the project graph (not to be confused with projectNamesToRunVersionOn)
|
98
98
|
projects,
|
99
99
|
});
|
100
|
-
const generatorCallback = await runVersionOnProjects(projectGraph, nxJson, args, tree, generatorData, args.generatorOptionsOverrides, projectNames, releaseGroup, versionData);
|
100
|
+
const generatorCallback = await runVersionOnProjects(projectGraph, nxJson, args, tree, generatorData, args.generatorOptionsOverrides, projectNames, releaseGroup, versionData, nxReleaseConfig.conventionalCommits);
|
101
101
|
// Capture the callback so that we can run it after flushing the changes to disk
|
102
102
|
generatorCallbacks.push(async () => {
|
103
103
|
const changedFiles = await generatorCallback(tree, {
|
@@ -179,7 +179,7 @@ async function releaseVersion(args) {
|
|
179
179
|
// all project data from the project graph (not to be confused with projectNamesToRunVersionOn)
|
180
180
|
projects,
|
181
181
|
});
|
182
|
-
const generatorCallback = await runVersionOnProjects(projectGraph, nxJson, args, tree, generatorData, args.generatorOptionsOverrides, projectNames, releaseGroup, versionData);
|
182
|
+
const generatorCallback = await runVersionOnProjects(projectGraph, nxJson, args, tree, generatorData, args.generatorOptionsOverrides, projectNames, releaseGroup, versionData, nxReleaseConfig.conventionalCommits);
|
183
183
|
// Capture the callback so that we can run it after flushing the changes to disk
|
184
184
|
generatorCallbacks.push(async () => {
|
185
185
|
const changedFiles = await generatorCallback(tree, {
|
@@ -262,7 +262,7 @@ function appendVersionData(existingVersionData, newVersionData) {
|
|
262
262
|
}
|
263
263
|
return existingVersionData;
|
264
264
|
}
|
265
|
-
async function runVersionOnProjects(projectGraph, nxJson, args, tree, generatorData, generatorOverrides, projectNames, releaseGroup, versionData) {
|
265
|
+
async function runVersionOnProjects(projectGraph, nxJson, args, tree, generatorData, generatorOverrides, projectNames, releaseGroup, versionData, conventionalCommitsConfig) {
|
266
266
|
const generatorOptions = {
|
267
267
|
// Always ensure a string to avoid generator schema validation errors
|
268
268
|
specifier: args.specifier ?? '',
|
@@ -274,6 +274,7 @@ async function runVersionOnProjects(projectGraph, nxJson, args, tree, generatorD
|
|
274
274
|
projectGraph,
|
275
275
|
releaseGroup,
|
276
276
|
firstRelease: args.firstRelease ?? false,
|
277
|
+
conventionalCommitsConfig,
|
277
278
|
};
|
278
279
|
// Apply generator defaults from schema.json file etc
|
279
280
|
const combinedOpts = await (0, params_1.combineOptionsForGenerator)(generatorOptions, generatorData.collectionName, generatorData.normalizedGeneratorName, (0, project_graph_1.readProjectsConfigurationFromProjectGraph)(projectGraph), nxJson, generatorData.schema, false, null, (0, node_path_1.relative)(process.cwd(), workspace_root_1.workspaceRoot), args.verbose);
|
package/src/config/nx-json.d.ts
CHANGED
@@ -120,6 +120,30 @@ export interface NxReleaseGitConfiguration {
|
|
120
120
|
*/
|
121
121
|
tagArgs?: string;
|
122
122
|
}
|
123
|
+
export interface NxReleaseConventionalCommitsConfiguration {
|
124
|
+
types?: Record<string,
|
125
|
+
/**
|
126
|
+
* A map of commit types to their configuration.
|
127
|
+
* If a type is set to 'true', then it will be enabled with the default 'semverBump' of 'patch' and will appear in the changelog.
|
128
|
+
* If a type is set to 'false', then it will not trigger a version bump and will be hidden from the changelog.
|
129
|
+
*/
|
130
|
+
{
|
131
|
+
/**
|
132
|
+
* The semver bump to apply when a commit of this type is found.
|
133
|
+
* If set to "none", the commit will be ignored for versioning purposes.
|
134
|
+
*/
|
135
|
+
semverBump?: 'patch' | 'minor' | 'major' | 'none';
|
136
|
+
/**
|
137
|
+
* Configuration for the changelog section for commits of this type.
|
138
|
+
* If set to 'true', then commits of this type will be included in the changelog with their default title for the type.
|
139
|
+
* If set to 'false', then commits of this type will not be included in the changelog.
|
140
|
+
*/
|
141
|
+
changelog?: {
|
142
|
+
title?: string;
|
143
|
+
hidden?: boolean;
|
144
|
+
} | boolean;
|
145
|
+
} | boolean>;
|
146
|
+
}
|
123
147
|
interface NxReleaseConfiguration {
|
124
148
|
/**
|
125
149
|
* Shorthand for amending the projects which will be included in the implicit default release group (all projects by default).
|
@@ -229,6 +253,7 @@ interface NxReleaseConfiguration {
|
|
229
253
|
* Enable and configure automatic git operations as part of the release
|
230
254
|
*/
|
231
255
|
git?: NxReleaseGitConfiguration;
|
256
|
+
conventionalCommits?: NxReleaseConventionalCommitsConfiguration;
|
232
257
|
}
|
233
258
|
/**
|
234
259
|
* Nx.json configuration
|