nx 17.0.0 → 17.0.2
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/changelog-renderer/index.d.ts +43 -0
- package/changelog-renderer/index.js +180 -0
- package/package.json +12 -13
- package/schemas/nx-schema.json +141 -0
- package/src/adapter/ngcli-adapter.js +32 -0
- package/src/command-line/release/changelog.js +332 -75
- package/src/command-line/release/command-object.d.ts +1 -3
- package/src/command-line/release/command-object.js +3 -17
- package/src/command-line/release/config/config.d.ts +1 -1
- package/src/command-line/release/config/config.js +153 -50
- package/src/command-line/release/utils/markdown.d.ts +1 -4
- package/src/command-line/release/utils/markdown.js +3 -136
- package/src/command-line/release/utils/print-changes.d.ts +5 -1
- package/src/command-line/release/utils/print-changes.js +3 -2
- package/src/command-line/show/show.js +2 -0
- package/src/config/nx-json.d.ts +80 -3
- package/src/config/nx-json.js +1 -1
- package/src/config/project-graph.d.ts +1 -1
- package/src/core/graph/3rdpartylicenses.txt +76 -26
- package/src/core/graph/main.js +1 -1
- package/src/core/graph/polyfills.js +1 -1
- package/src/core/graph/runtime.js +1 -1
- package/src/core/graph/styles.js +1 -1
- package/src/daemon/client/client.js +0 -6
- package/src/daemon/server/outputs-tracking.d.ts +2 -2
- package/src/daemon/server/outputs-tracking.js +2 -2
- package/src/daemon/server/project-graph-incremental-recomputation.js +1 -28
- package/src/daemon/server/server.js +22 -58
- package/src/daemon/server/shutdown-utils.d.ts +0 -6
- package/src/daemon/server/shutdown-utils.js +1 -36
- package/src/daemon/server/watcher.d.ts +2 -6
- package/src/daemon/server/watcher.js +1 -92
- package/src/migrations/update-15-0-0/prefix-outputs.js +9 -9
- package/src/project-graph/project-graph.js +6 -1
- package/src/project-graph/utils/retrieve-workspace-files.js +1 -1
- package/src/tasks-runner/utils.js +8 -4
|
@@ -10,53 +10,88 @@ exports.CATCH_ALL_RELEASE_GROUP = '__default__';
|
|
|
10
10
|
async function createNxReleaseConfig(projectGraph, userConfig = {},
|
|
11
11
|
// Optionally ensure that all configured projects have implemented a certain target
|
|
12
12
|
requiredTargetName) {
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
const WORKSPACE_DEFAULTS = {
|
|
14
|
+
version: {
|
|
15
|
+
generator: '@nx/js:release-version',
|
|
16
|
+
generatorOptions: {},
|
|
17
|
+
},
|
|
18
|
+
changelog: {
|
|
19
|
+
workspaceChangelog: {
|
|
20
|
+
createRelease: false,
|
|
21
|
+
entryWhenNoChanges: 'This was a version bump only, there were no code changes.',
|
|
22
|
+
file: '{workspaceRoot}/CHANGELOG.md',
|
|
23
|
+
renderer: 'nx/changelog-renderer',
|
|
24
|
+
renderOptions: {
|
|
25
|
+
includeAuthors: true,
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
// For projectChangelogs if the user has set any changelog config at all, then use one set of defaults, otherwise default to false for the whole feature
|
|
29
|
+
projectChangelogs: userConfig.changelog?.projectChangelogs
|
|
30
|
+
? {
|
|
31
|
+
createRelease: false,
|
|
32
|
+
file: '{projectRoot}/CHANGELOG.md',
|
|
33
|
+
entryWhenNoChanges: 'This was a version bump only for {projectName} to align it with other projects, there were no code changes.',
|
|
34
|
+
renderer: 'nx/changelog-renderer',
|
|
35
|
+
renderOptions: {
|
|
36
|
+
includeAuthors: true,
|
|
37
|
+
},
|
|
38
|
+
}
|
|
39
|
+
: false,
|
|
40
|
+
},
|
|
41
|
+
releaseTagPattern: 'v{version}',
|
|
42
|
+
};
|
|
43
|
+
const GROUP_DEFAULTS = {
|
|
44
|
+
version: {
|
|
45
|
+
generator: '@nx/js:release-version',
|
|
46
|
+
generatorOptions: {},
|
|
47
|
+
},
|
|
48
|
+
changelog: {
|
|
49
|
+
createRelease: false,
|
|
50
|
+
entryWhenNoChanges: 'This was a version bump only for {projectName} to align it with other projects, there were no code changes.',
|
|
51
|
+
file: '{projectRoot}/CHANGELOG.md',
|
|
52
|
+
renderer: 'nx/changelog-renderer',
|
|
53
|
+
renderOptions: {
|
|
54
|
+
includeAuthors: true,
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
releaseTagPattern: '{projectName}@v{version}',
|
|
58
|
+
};
|
|
17
59
|
/**
|
|
18
|
-
*
|
|
19
|
-
*
|
|
60
|
+
* We first process root level config and apply defaults, so that we know how to handle the group level
|
|
61
|
+
* overrides, if applicable.
|
|
20
62
|
*/
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
},
|
|
63
|
+
const rootVersionConfig = deepMergeDefaults([WORKSPACE_DEFAULTS.version], userConfig.version);
|
|
64
|
+
const rootChangelogConfig = deepMergeDefaults([WORKSPACE_DEFAULTS.changelog], userConfig.changelog);
|
|
65
|
+
const allProjects = (0, find_matching_projects_1.findMatchingProjects)(['*'], projectGraph.nodes);
|
|
66
|
+
const groups = userConfig.groups && Object.keys(userConfig.groups).length
|
|
67
|
+
? ensureProjectsConfigIsArray(userConfig.groups)
|
|
68
|
+
: /**
|
|
69
|
+
* No user specified release groups, so we treat all projects as being in one release group
|
|
70
|
+
* together in which all projects are released in lock step.
|
|
71
|
+
*/
|
|
72
|
+
{
|
|
73
|
+
[exports.CATCH_ALL_RELEASE_GROUP]: {
|
|
74
|
+
projects: allProjects,
|
|
75
|
+
/**
|
|
76
|
+
* For properties which are overriding config at the root, we use the root level config as the
|
|
77
|
+
* default values to merge with so that the group that matches a specific project will always
|
|
78
|
+
* be the valid source of truth for that type of config.
|
|
79
|
+
*/
|
|
80
|
+
version: deepMergeDefaults([GROUP_DEFAULTS.version], rootVersionConfig),
|
|
81
|
+
releaseTagPattern: GROUP_DEFAULTS.releaseTagPattern,
|
|
82
|
+
// Directly inherit the root level config for projectChangelogs, if set
|
|
83
|
+
changelog: rootChangelogConfig.projectChangelogs || false,
|
|
43
84
|
},
|
|
44
|
-
}
|
|
45
|
-
};
|
|
46
|
-
}
|
|
85
|
+
};
|
|
47
86
|
/**
|
|
48
|
-
* The user has specified at least one release group.
|
|
49
|
-
*
|
|
50
87
|
* Resolve all the project names into their release groups, and check
|
|
51
88
|
* that individual projects are not found in multiple groups.
|
|
52
89
|
*/
|
|
53
90
|
const releaseGroups = {};
|
|
54
91
|
const alreadyMatchedProjects = new Set();
|
|
55
|
-
for (const [releaseGroupName,
|
|
56
|
-
// Ensure that the
|
|
57
|
-
const matchingProjects = (0, find_matching_projects_1.findMatchingProjects)(
|
|
58
|
-
? userSpecifiedGroup.projects
|
|
59
|
-
: [userSpecifiedGroup.projects], projectGraph.nodes);
|
|
92
|
+
for (const [releaseGroupName, releaseGroup] of Object.entries(groups)) {
|
|
93
|
+
// Ensure that the config for the release group can resolve at least one project
|
|
94
|
+
const matchingProjects = (0, find_matching_projects_1.findMatchingProjects)(releaseGroup.projects, projectGraph.nodes);
|
|
60
95
|
if (!matchingProjects.length) {
|
|
61
96
|
return {
|
|
62
97
|
error: {
|
|
@@ -92,25 +127,35 @@ requiredTargetName) {
|
|
|
92
127
|
}
|
|
93
128
|
alreadyMatchedProjects.add(project);
|
|
94
129
|
}
|
|
95
|
-
|
|
130
|
+
// First apply any group level defaults, then apply actual root level config (if applicable), then group level config
|
|
131
|
+
const groupChangelogDefaults = [GROUP_DEFAULTS.changelog];
|
|
132
|
+
if (rootChangelogConfig.projectChangelogs) {
|
|
133
|
+
groupChangelogDefaults.push(rootChangelogConfig.projectChangelogs);
|
|
134
|
+
}
|
|
135
|
+
const groupDefaults = {
|
|
96
136
|
projects: matchingProjects,
|
|
97
|
-
version:
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
}
|
|
103
|
-
:
|
|
104
|
-
|
|
105
|
-
generatorOptions: DEFAULT_VERSION_GENERATOR_OPTIONS,
|
|
106
|
-
},
|
|
137
|
+
version: deepMergeDefaults(
|
|
138
|
+
// First apply any group level defaults, then apply actual root level config, then group level config
|
|
139
|
+
[GROUP_DEFAULTS.version, rootVersionConfig], releaseGroup.version),
|
|
140
|
+
// If the user has set any changelog config at all, including at the root level, then use one set of defaults, otherwise default to false for the whole feature
|
|
141
|
+
changelog: releaseGroup.changelog || rootChangelogConfig.projectChangelogs
|
|
142
|
+
? deepMergeDefaults(groupChangelogDefaults, releaseGroup.changelog || {})
|
|
143
|
+
: false,
|
|
144
|
+
releaseTagPattern: GROUP_DEFAULTS.releaseTagPattern,
|
|
107
145
|
};
|
|
146
|
+
releaseGroups[releaseGroupName] = deepMergeDefaults([groupDefaults], {
|
|
147
|
+
...releaseGroup,
|
|
148
|
+
// Ensure that the resolved project names take priority over the original user config (which could have contained unresolved globs etc)
|
|
149
|
+
projects: matchingProjects,
|
|
150
|
+
});
|
|
108
151
|
}
|
|
109
152
|
return {
|
|
110
153
|
error: null,
|
|
111
154
|
nxReleaseConfig: {
|
|
112
|
-
|
|
155
|
+
version: rootVersionConfig,
|
|
156
|
+
changelog: rootChangelogConfig,
|
|
113
157
|
groups: releaseGroups,
|
|
158
|
+
releaseTagPattern: userConfig.releaseTagPattern || WORKSPACE_DEFAULTS.releaseTagPattern,
|
|
114
159
|
},
|
|
115
160
|
};
|
|
116
161
|
}
|
|
@@ -155,6 +200,18 @@ async function handleNxReleaseConfigError(error) {
|
|
|
155
200
|
process.exit(1);
|
|
156
201
|
}
|
|
157
202
|
exports.handleNxReleaseConfigError = handleNxReleaseConfigError;
|
|
203
|
+
function ensureProjectsConfigIsArray(groups) {
|
|
204
|
+
const result = {};
|
|
205
|
+
for (const [groupName, groupConfig] of Object.entries(groups)) {
|
|
206
|
+
result[groupName] = {
|
|
207
|
+
...groupConfig,
|
|
208
|
+
projects: Array.isArray(groupConfig.projects)
|
|
209
|
+
? groupConfig.projects
|
|
210
|
+
: [groupConfig.projects],
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
return result;
|
|
214
|
+
}
|
|
158
215
|
function ensureProjectsHaveTarget(projects, projectGraph, requiredTargetName) {
|
|
159
216
|
const missingTargetProjects = projects.filter((project) => !(0, project_graph_utils_1.projectHasTarget)(projectGraph.nodes[project], requiredTargetName));
|
|
160
217
|
if (missingTargetProjects.length) {
|
|
@@ -168,3 +225,49 @@ function ensureProjectsHaveTarget(projects, projectGraph, requiredTargetName) {
|
|
|
168
225
|
}
|
|
169
226
|
return null;
|
|
170
227
|
}
|
|
228
|
+
function isObject(value) {
|
|
229
|
+
return value && typeof value === 'object' && !Array.isArray(value);
|
|
230
|
+
}
|
|
231
|
+
// Helper function to merge two config objects
|
|
232
|
+
function mergeConfig(objA, objB) {
|
|
233
|
+
const merged = { ...objA };
|
|
234
|
+
for (const key in objB) {
|
|
235
|
+
if (objB.hasOwnProperty(key)) {
|
|
236
|
+
// If objB[key] is explicitly set to false, null or 0, respect that value
|
|
237
|
+
if (objB[key] === false || objB[key] === null || objB[key] === 0) {
|
|
238
|
+
merged[key] = objB[key];
|
|
239
|
+
}
|
|
240
|
+
// If both objA[key] and objB[key] are objects, recursively merge them
|
|
241
|
+
else if (isObject(merged[key]) && isObject(objB[key])) {
|
|
242
|
+
merged[key] = mergeConfig(merged[key], objB[key]);
|
|
243
|
+
}
|
|
244
|
+
// If objB[key] is defined, use it (this will overwrite any existing value in merged[key])
|
|
245
|
+
else if (objB[key] !== undefined) {
|
|
246
|
+
merged[key] = objB[key];
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
return merged;
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* This function takes in a strictly typed collection of all possible default values in a particular section of config,
|
|
254
|
+
* and an optional set of partial user config, and returns a single, deeply merged config object, where the user
|
|
255
|
+
* config takes priority over the defaults in all cases (only an `undefined` value in the user config will be
|
|
256
|
+
* overwritten by the defaults, all other falsey values from the user will be respected).
|
|
257
|
+
*/
|
|
258
|
+
function deepMergeDefaults(defaultConfigs, userConfig) {
|
|
259
|
+
let result;
|
|
260
|
+
// First merge defaultConfigs sequentially (meaning later defaults will override earlier ones)
|
|
261
|
+
for (const defaultConfig of defaultConfigs) {
|
|
262
|
+
if (!result) {
|
|
263
|
+
result = defaultConfig;
|
|
264
|
+
continue;
|
|
265
|
+
}
|
|
266
|
+
result = mergeConfig(result, defaultConfig);
|
|
267
|
+
}
|
|
268
|
+
// Finally, merge the userConfig
|
|
269
|
+
if (userConfig) {
|
|
270
|
+
result = mergeConfig(result, userConfig);
|
|
271
|
+
}
|
|
272
|
+
return result;
|
|
273
|
+
}
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
import { RepoSlug } from './github';
|
|
3
|
-
export declare function generateMarkdown(commits: GitCommit[], releaseVersion: string, repoSlug?: RepoSlug): Promise<string>;
|
|
4
|
-
export declare function parseChangelogMarkdown(contents: string, tagVersionPrefix: any): {
|
|
1
|
+
export declare function parseChangelogMarkdown(contents: string): {
|
|
5
2
|
releases: {
|
|
6
3
|
version?: string;
|
|
7
4
|
body: string;
|
|
@@ -1,141 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.parseChangelogMarkdown =
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const _axios = require("axios");
|
|
7
|
-
const axios = _axios;
|
|
8
|
-
function formatName(name = '') {
|
|
9
|
-
return name
|
|
10
|
-
.split(' ')
|
|
11
|
-
.map((p) => p.trim())
|
|
12
|
-
.join(' ');
|
|
13
|
-
}
|
|
14
|
-
function groupBy(items, key) {
|
|
15
|
-
const groups = {};
|
|
16
|
-
for (const item of items) {
|
|
17
|
-
groups[item[key]] = groups[item[key]] || [];
|
|
18
|
-
groups[item[key]].push(item);
|
|
19
|
-
}
|
|
20
|
-
return groups;
|
|
21
|
-
}
|
|
22
|
-
function formatCommit(commit, repoSlug) {
|
|
23
|
-
let commitLine = '- ' +
|
|
24
|
-
(commit.scope ? `**${commit.scope.trim()}:** ` : '') +
|
|
25
|
-
(commit.isBreaking ? '⚠️ ' : '') +
|
|
26
|
-
commit.description;
|
|
27
|
-
if (repoSlug) {
|
|
28
|
-
commitLine += (0, github_1.formatReferences)(commit.references, repoSlug);
|
|
29
|
-
}
|
|
30
|
-
return commitLine;
|
|
31
|
-
}
|
|
32
|
-
// TODO: allow this to be configurable via config in a future release
|
|
33
|
-
async function generateMarkdown(commits, releaseVersion, repoSlug) {
|
|
34
|
-
const typeGroups = groupBy(commits, 'type');
|
|
35
|
-
const markdown = [];
|
|
36
|
-
const breakingChanges = [];
|
|
37
|
-
const commitTypes = {
|
|
38
|
-
feat: { title: '🚀 Features' },
|
|
39
|
-
perf: { title: '🔥 Performance' },
|
|
40
|
-
fix: { title: '🩹 Fixes' },
|
|
41
|
-
refactor: { title: '💅 Refactors' },
|
|
42
|
-
docs: { title: '📖 Documentation' },
|
|
43
|
-
build: { title: '📦 Build' },
|
|
44
|
-
types: { title: '🌊 Types' },
|
|
45
|
-
chore: { title: '🏡 Chore' },
|
|
46
|
-
examples: { title: '🏀 Examples' },
|
|
47
|
-
test: { title: '✅ Tests' },
|
|
48
|
-
style: { title: '🎨 Styles' },
|
|
49
|
-
ci: { title: '🤖 CI' },
|
|
50
|
-
};
|
|
51
|
-
// Version Title
|
|
52
|
-
markdown.push('', `## ${releaseVersion}`, '');
|
|
53
|
-
for (const type of Object.keys(commitTypes)) {
|
|
54
|
-
const group = typeGroups[type];
|
|
55
|
-
if (!group || group.length === 0) {
|
|
56
|
-
continue;
|
|
57
|
-
}
|
|
58
|
-
markdown.push('', '### ' + commitTypes[type].title, '');
|
|
59
|
-
/**
|
|
60
|
-
* In order to make the final changelog most readable, we organize commits as follows:
|
|
61
|
-
* - By scope, where scopes are in alphabetical order (commits with no scope are listed first)
|
|
62
|
-
* - Within a particular scope grouping, we list commits in chronological order
|
|
63
|
-
*/
|
|
64
|
-
const commitsInChronologicalOrder = group.reverse();
|
|
65
|
-
const commitsGroupedByScope = groupBy(commitsInChronologicalOrder, 'scope');
|
|
66
|
-
const scopesSortedAlphabetically = Object.keys(commitsGroupedByScope).sort();
|
|
67
|
-
for (const scope of scopesSortedAlphabetically) {
|
|
68
|
-
const commits = commitsGroupedByScope[scope];
|
|
69
|
-
for (const commit of commits) {
|
|
70
|
-
const line = formatCommit(commit, repoSlug);
|
|
71
|
-
markdown.push(line);
|
|
72
|
-
if (commit.isBreaking) {
|
|
73
|
-
breakingChanges.push(line);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
if (breakingChanges.length > 0) {
|
|
79
|
-
markdown.push('', '#### ⚠️ Breaking Changes', '', ...breakingChanges);
|
|
80
|
-
}
|
|
81
|
-
const _authors = new Map();
|
|
82
|
-
for (const commit of commits) {
|
|
83
|
-
if (!commit.author) {
|
|
84
|
-
continue;
|
|
85
|
-
}
|
|
86
|
-
const name = formatName(commit.author.name);
|
|
87
|
-
if (!name || name.includes('[bot]')) {
|
|
88
|
-
continue;
|
|
89
|
-
}
|
|
90
|
-
if (_authors.has(name)) {
|
|
91
|
-
const entry = _authors.get(name);
|
|
92
|
-
entry.email.add(commit.author.email);
|
|
93
|
-
}
|
|
94
|
-
else {
|
|
95
|
-
_authors.set(name, { email: new Set([commit.author.email]) });
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
// Try to map authors to github usernames
|
|
99
|
-
if (repoSlug) {
|
|
100
|
-
await Promise.all([..._authors.keys()].map(async (authorName) => {
|
|
101
|
-
const meta = _authors.get(authorName);
|
|
102
|
-
for (const email of meta.email) {
|
|
103
|
-
// For these pseudo-anonymized emails we can just extract the Github username from before the @
|
|
104
|
-
if (email.endsWith('@users.noreply.github.com')) {
|
|
105
|
-
meta.github = email.split('@')[0];
|
|
106
|
-
break;
|
|
107
|
-
}
|
|
108
|
-
// Look up any other emails against the ungh.cc API
|
|
109
|
-
const { data } = await axios
|
|
110
|
-
.get(`https://ungh.cc/users/find/${email}`)
|
|
111
|
-
.catch(() => ({ data: { user: null } }));
|
|
112
|
-
if (data?.user) {
|
|
113
|
-
meta.github = data.user.username;
|
|
114
|
-
break;
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
}));
|
|
118
|
-
}
|
|
119
|
-
const authors = [..._authors.entries()].map((e) => ({ name: e[0], ...e[1] }));
|
|
120
|
-
if (authors.length > 0) {
|
|
121
|
-
markdown.push('', '### ' + '❤️ Thank You', '', ...authors
|
|
122
|
-
// Sort the contributors by name
|
|
123
|
-
.sort((a, b) => a.name.localeCompare(b.name))
|
|
124
|
-
.map((i) => {
|
|
125
|
-
// Tag the author's Github username if we were able to resolve it so that Github adds them as a contributor
|
|
126
|
-
const github = i.github ? ` @${i.github}` : '';
|
|
127
|
-
return `- ${i.name}${github}`;
|
|
128
|
-
}));
|
|
129
|
-
}
|
|
130
|
-
return markdown.join('\n').trim();
|
|
131
|
-
}
|
|
132
|
-
exports.generateMarkdown = generateMarkdown;
|
|
133
|
-
function escapeRegExp(string) {
|
|
134
|
-
return string.replace(/[.*+\-?^${}()|[\]\\]/g, '\\$&');
|
|
135
|
-
}
|
|
136
|
-
function parseChangelogMarkdown(contents, tagVersionPrefix) {
|
|
137
|
-
const escapedTagVersionPrefix = escapeRegExp(tagVersionPrefix);
|
|
138
|
-
const CHANGELOG_RELEASE_HEAD_RE = new RegExp('^#{2,}\\s+' + escapedTagVersionPrefix + '(\\d+\\.\\d+\\.\\d+)', 'gm');
|
|
3
|
+
exports.parseChangelogMarkdown = void 0;
|
|
4
|
+
function parseChangelogMarkdown(contents) {
|
|
5
|
+
const CHANGELOG_RELEASE_HEAD_RE = new RegExp('^#{2,}\\s+(\\d+\\.\\d+\\.\\d+)', 'gm');
|
|
139
6
|
const headings = [...contents.matchAll(CHANGELOG_RELEASE_HEAD_RE)];
|
|
140
7
|
const releases = [];
|
|
141
8
|
for (let i = 0; i < headings.length; i++) {
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
1
2
|
import { Tree } from '../../../generators/tree';
|
|
2
3
|
export declare function printDiff(before: string, after: string, contextLines?: number, noDiffMessage?: string): void;
|
|
3
|
-
export declare function printChanges(tree: Tree, isDryRun: boolean, diffContextLines?: number, shouldPrintDryRunMessage?: boolean, noDiffMessage?: string
|
|
4
|
+
export declare function printChanges(tree: Tree, isDryRun: boolean, diffContextLines?: number, shouldPrintDryRunMessage?: boolean, noDiffMessage?: string, changePredicate?: (f: {
|
|
5
|
+
path: string;
|
|
6
|
+
content?: Buffer;
|
|
7
|
+
}) => boolean): void;
|
|
@@ -27,7 +27,8 @@ function printDiff(before, after, contextLines = 1, noDiffMessage = NO_DIFF_MESS
|
|
|
27
27
|
console.log('');
|
|
28
28
|
}
|
|
29
29
|
exports.printDiff = printDiff;
|
|
30
|
-
function printChanges(tree, isDryRun, diffContextLines = 1, shouldPrintDryRunMessage = true, noDiffMessage) {
|
|
30
|
+
function printChanges(tree, isDryRun, diffContextLines = 1, shouldPrintDryRunMessage = true, noDiffMessage, changePredicate) {
|
|
31
|
+
changePredicate = changePredicate || (() => true);
|
|
31
32
|
const changes = tree.listChanges();
|
|
32
33
|
console.log('');
|
|
33
34
|
if (changes.length === 0 && noDiffMessage) {
|
|
@@ -35,7 +36,7 @@ function printChanges(tree, isDryRun, diffContextLines = 1, shouldPrintDryRunMes
|
|
|
35
36
|
return;
|
|
36
37
|
}
|
|
37
38
|
// Print the changes
|
|
38
|
-
changes.forEach((f) => {
|
|
39
|
+
changes.filter(changePredicate).forEach((f) => {
|
|
39
40
|
if (f.type === 'CREATE') {
|
|
40
41
|
console.error(`${chalk.green('CREATE')} ${f.path}${isDryRun ? chalk.keyword('orange')(' [dry-run]') : ''}`);
|
|
41
42
|
printDiff('', f.content?.toString() || '', diffContextLines, noDiffMessage);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.showProjectHandler = exports.showProjectsHandler = void 0;
|
|
4
|
+
const output_1 = require("../../utils/output");
|
|
4
5
|
const nx_json_1 = require("../../config/nx-json");
|
|
5
6
|
const affected_project_graph_1 = require("../../project-graph/affected/affected-project-graph");
|
|
6
7
|
const file_utils_1 = require("../../project-graph/file-utils");
|
|
@@ -55,6 +56,7 @@ async function showProjectsHandler(args) {
|
|
|
55
56
|
console.log(project);
|
|
56
57
|
}
|
|
57
58
|
}
|
|
59
|
+
await output_1.output.drain();
|
|
58
60
|
process.exit(0);
|
|
59
61
|
}
|
|
60
62
|
exports.showProjectsHandler = showProjectsHandler;
|
package/src/config/nx-json.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ChangelogRenderOptions } from '../../changelog-renderer';
|
|
1
2
|
import { PackageManager } from '../utils/package-manager';
|
|
2
3
|
import { InputDefinition, TargetConfiguration, TargetDependencyConfig } from './workspace-json-project-json';
|
|
3
4
|
export type ImplicitDependencyEntry<T = '*' | string[]> = {
|
|
@@ -37,6 +38,50 @@ interface NxReleaseVersionConfiguration {
|
|
|
37
38
|
generator?: string;
|
|
38
39
|
generatorOptions?: Record<string, unknown>;
|
|
39
40
|
}
|
|
41
|
+
/**
|
|
42
|
+
* **ALPHA**
|
|
43
|
+
*/
|
|
44
|
+
export interface NxReleaseChangelogConfiguration {
|
|
45
|
+
/**
|
|
46
|
+
* Optionally create a release containing all relevant changes on a supported version control system, it
|
|
47
|
+
* is false by default.
|
|
48
|
+
*
|
|
49
|
+
* NOTE: if createRelease is set on a group of projects, it will cause the default releaseTagPattern of
|
|
50
|
+
* "{projectName}@v{version}" to be used for those projects, even when versioning everything together.
|
|
51
|
+
*/
|
|
52
|
+
createRelease?: 'github' | false;
|
|
53
|
+
/**
|
|
54
|
+
* This can either be set to a string value that will be written to the changelog file(s)
|
|
55
|
+
* at the workspace root and/or within project directories, or set to `false` to specify
|
|
56
|
+
* that no changelog entry should be made when there are no code changes.
|
|
57
|
+
*
|
|
58
|
+
* NOTE: The string value has a sensible default value and supports interpolation of
|
|
59
|
+
* {projectName} when generating for project level changelogs.
|
|
60
|
+
*
|
|
61
|
+
* E.g. for a project level changelog you could customize the message to something like:
|
|
62
|
+
* "entryWhenNoChanges": "There were no code changes for {projectName}"
|
|
63
|
+
*/
|
|
64
|
+
entryWhenNoChanges?: string | false;
|
|
65
|
+
/**
|
|
66
|
+
* This is either a workspace path where the changelog markdown file will be created and read from,
|
|
67
|
+
* or set to false to disable file creation altogether (e.g. if only using Github releases).
|
|
68
|
+
*
|
|
69
|
+
* Interpolation of {projectName}, {projectRoot} and {workspaceRoot} is supported.
|
|
70
|
+
*
|
|
71
|
+
* The defaults are:
|
|
72
|
+
* - "{workspaceRoot}/CHANGELOG.md" at the workspace level
|
|
73
|
+
* - "{projectRoot}/CHANGELOG.md" at the project level
|
|
74
|
+
*/
|
|
75
|
+
file?: string | false;
|
|
76
|
+
/**
|
|
77
|
+
* A path to a valid changelog renderer function used to transform commit messages and other metadata into
|
|
78
|
+
* the final changelog (usually in markdown format). Its output can be modified using the optional `renderOptions`.
|
|
79
|
+
*
|
|
80
|
+
* By default, the renderer is set to "nx/changelog-renderer" which nx provides out of the box.
|
|
81
|
+
*/
|
|
82
|
+
renderer?: string;
|
|
83
|
+
renderOptions?: ChangelogRenderOptions;
|
|
84
|
+
}
|
|
40
85
|
/**
|
|
41
86
|
* **ALPHA**
|
|
42
87
|
*/
|
|
@@ -45,14 +90,46 @@ interface NxReleaseConfiguration {
|
|
|
45
90
|
* @note: When no groups are configured at all (the default), all projects in the workspace are treated as
|
|
46
91
|
* if they were in a release group together.
|
|
47
92
|
*/
|
|
48
|
-
groups?: Record<string,
|
|
93
|
+
groups?: Record<string, // group name
|
|
94
|
+
{
|
|
95
|
+
/**
|
|
96
|
+
* Required list of one or more projects to include in the release group. Any single project can
|
|
97
|
+
* only be used in a maximum of one release group.
|
|
98
|
+
*/
|
|
49
99
|
projects: string[] | string;
|
|
50
100
|
/**
|
|
51
|
-
*
|
|
52
|
-
* is the desired generator implementation, allowing for terser config for the common case.
|
|
101
|
+
* Optionally override version configuration for this group.
|
|
53
102
|
*/
|
|
54
103
|
version?: NxReleaseVersionConfiguration;
|
|
104
|
+
/**
|
|
105
|
+
* Optionally override project changelog configuration for this group.
|
|
106
|
+
*/
|
|
107
|
+
changelog?: NxReleaseChangelogConfiguration | false;
|
|
108
|
+
/**
|
|
109
|
+
* Optionally override the git/release tag pattern to use for this group.
|
|
110
|
+
*/
|
|
111
|
+
releaseTagPattern?: string;
|
|
55
112
|
}>;
|
|
113
|
+
changelog?: {
|
|
114
|
+
workspaceChangelog?: NxReleaseChangelogConfiguration | false;
|
|
115
|
+
projectChangelogs?: NxReleaseChangelogConfiguration | false;
|
|
116
|
+
};
|
|
117
|
+
/**
|
|
118
|
+
* If no version config is provided, we will assume that @nx/js:release-version
|
|
119
|
+
* is the desired generator implementation, allowing for terser config for the common case.
|
|
120
|
+
*/
|
|
121
|
+
version?: NxReleaseVersionConfiguration;
|
|
122
|
+
/**
|
|
123
|
+
* Optional override the git/release tag pattern to use. This field is the source of truth
|
|
124
|
+
* for changelog generation and release tagging, as well as for conventional-commits parsing.
|
|
125
|
+
*
|
|
126
|
+
* It supports interpolating the version as {version} and (if releasing independently or forcing
|
|
127
|
+
* project level version control system releases) the project name as {projectName} within the string.
|
|
128
|
+
*
|
|
129
|
+
* The default releaseTagPattern for unified releases is: "v{version}"
|
|
130
|
+
* The default releaseTagPattern for releases at the project level is: "{projectName}@v{version}"
|
|
131
|
+
*/
|
|
132
|
+
releaseTagPattern?: string;
|
|
56
133
|
}
|
|
57
134
|
/**
|
|
58
135
|
* Nx.json configuration
|
package/src/config/nx-json.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.hasNxJson = exports.readNxJson = void 0;
|
|
4
|
-
const path_1 = require("path");
|
|
5
4
|
const fs_1 = require("fs");
|
|
5
|
+
const path_1 = require("path");
|
|
6
6
|
const fileutils_1 = require("../utils/fileutils");
|
|
7
7
|
const workspace_root_1 = require("../utils/workspace-root");
|
|
8
8
|
function readNxJson(root = workspace_root_1.workspaceRoot) {
|
|
@@ -24,7 +24,7 @@ export interface FileData {
|
|
|
24
24
|
*/
|
|
25
25
|
export type FileDataDependency = string | [target: string, type: DependencyType] | [source: string, target: string, type: DependencyType];
|
|
26
26
|
export declare function fileDataDepTarget(dep: FileDataDependency): string;
|
|
27
|
-
export declare function fileDataDepType(dep: FileDataDependency): "static"
|
|
27
|
+
export declare function fileDataDepType(dep: FileDataDependency): DependencyType | "static";
|
|
28
28
|
export interface FileMap {
|
|
29
29
|
nonProjectFiles: FileData[];
|
|
30
30
|
projectFileMap: ProjectFileMap;
|