nx 21.3.0-canary.20250718-9f1c811 → 21.3.0
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/bin/nx.js +19 -2
- package/package.json +11 -11
- package/schemas/nx-schema.json +18 -0
- package/src/command-line/release/changelog.js +47 -3
- package/src/command-line/release/config/config.js +14 -1
- package/src/command-line/release/utils/git.d.ts +35 -4
- package/src/command-line/release/utils/git.js +71 -11
- package/src/command-line/release/utils/shared.d.ts +1 -0
- package/src/command-line/release/utils/shared.js +1 -0
- package/src/command-line/release/version/release-group-processor.js +6 -1
- package/src/config/nx-json.d.ts +40 -0
- package/src/core/graph/main.js +1 -1
- package/src/native/nx.wasm32-wasi.wasm +0 -0
- package/src/nx-cloud/utilities/url-shorten.d.ts +0 -4
- package/src/nx-cloud/utilities/url-shorten.js +1 -70
package/bin/nx.js
CHANGED
@@ -64,14 +64,14 @@ async function main() {
|
|
64
64
|
if (!workspace) {
|
65
65
|
handleNoWorkspace(GLOBAL_NX_VERSION);
|
66
66
|
}
|
67
|
-
if (!localNx) {
|
67
|
+
if (!localNx && !isNxCloudCommand(process.argv[2])) {
|
68
68
|
handleMissingLocalInstallation(workspace ? workspace.dir : null);
|
69
69
|
}
|
70
70
|
// this file is already in the local workspace
|
71
71
|
if (isLocalInstall) {
|
72
72
|
await (0, init_local_1.initLocal)(workspace);
|
73
73
|
}
|
74
|
-
else {
|
74
|
+
else if (localNx) {
|
75
75
|
// Nx is being run from globally installed CLI - hand off to the local
|
76
76
|
warnIfUsingOutdatedGlobalInstall(GLOBAL_NX_VERSION, LOCAL_NX_VERSION);
|
77
77
|
if (localNx.includes('.nx')) {
|
@@ -82,6 +82,11 @@ async function main() {
|
|
82
82
|
require(localNx);
|
83
83
|
}
|
84
84
|
}
|
85
|
+
else if (isNxCloudCommand(process.argv[2])) {
|
86
|
+
// nx-cloud commands can run without local Nx installation
|
87
|
+
process.env.NX_DAEMON = 'false';
|
88
|
+
require('nx/src/command-line/nx-commands').commandsObject.argv;
|
89
|
+
}
|
85
90
|
}
|
86
91
|
}
|
87
92
|
function handleNoWorkspace(globalNxVersion) {
|
@@ -132,6 +137,18 @@ function resolveNx(workspace) {
|
|
132
137
|
paths: [workspace ? workspace.dir : globalsRoot],
|
133
138
|
});
|
134
139
|
}
|
140
|
+
function isNxCloudCommand(command) {
|
141
|
+
const nxCloudCommands = [
|
142
|
+
'start-ci-run',
|
143
|
+
'login',
|
144
|
+
'logout',
|
145
|
+
'connect',
|
146
|
+
'view-logs',
|
147
|
+
'fix-ci',
|
148
|
+
'record',
|
149
|
+
];
|
150
|
+
return nxCloudCommands.includes(command);
|
151
|
+
}
|
135
152
|
function handleMissingLocalInstallation(detectedWorkspaceRoot) {
|
136
153
|
output_1.output.error({
|
137
154
|
title: detectedWorkspaceRoot
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "nx",
|
3
|
-
"version": "21.3.0
|
3
|
+
"version": "21.3.0",
|
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": {
|
@@ -83,16 +83,16 @@
|
|
83
83
|
}
|
84
84
|
},
|
85
85
|
"optionalDependencies": {
|
86
|
-
"@nx/nx-darwin-arm64": "21.3.0
|
87
|
-
"@nx/nx-darwin-x64": "21.3.0
|
88
|
-
"@nx/nx-freebsd-x64": "21.3.0
|
89
|
-
"@nx/nx-linux-arm-gnueabihf": "21.3.0
|
90
|
-
"@nx/nx-linux-arm64-gnu": "21.3.0
|
91
|
-
"@nx/nx-linux-arm64-musl": "21.3.0
|
92
|
-
"@nx/nx-linux-x64-gnu": "21.3.0
|
93
|
-
"@nx/nx-linux-x64-musl": "21.3.0
|
94
|
-
"@nx/nx-win32-arm64-msvc": "21.3.0
|
95
|
-
"@nx/nx-win32-x64-msvc": "21.3.0
|
86
|
+
"@nx/nx-darwin-arm64": "21.3.0",
|
87
|
+
"@nx/nx-darwin-x64": "21.3.0",
|
88
|
+
"@nx/nx-freebsd-x64": "21.3.0",
|
89
|
+
"@nx/nx-linux-arm-gnueabihf": "21.3.0",
|
90
|
+
"@nx/nx-linux-arm64-gnu": "21.3.0",
|
91
|
+
"@nx/nx-linux-arm64-musl": "21.3.0",
|
92
|
+
"@nx/nx-linux-x64-gnu": "21.3.0",
|
93
|
+
"@nx/nx-linux-x64-musl": "21.3.0",
|
94
|
+
"@nx/nx-win32-arm64-msvc": "21.3.0",
|
95
|
+
"@nx/nx-win32-x64-msvc": "21.3.0"
|
96
96
|
},
|
97
97
|
"nx-migrations": {
|
98
98
|
"migrations": "./migrations.json",
|
package/schemas/nx-schema.json
CHANGED
@@ -207,6 +207,13 @@
|
|
207
207
|
],
|
208
208
|
"description": "By default, we will try and resolve the latest match for the releaseTagPattern from the current branch, falling back to all branches if no match is found on the current branch. Setting this to true will cause us to ALWAYS check all branches for the latest match. Setting it to false will cause us to ONLY check the current branch for the latest match. Setting it to an array of strings will cause us to check all branches WHEN the current branch is one of the strings in the array. Glob patterns are supported."
|
209
209
|
},
|
210
|
+
"releaseTagPatternRequireSemver": {
|
211
|
+
"type": "boolean",
|
212
|
+
"description": "Whether to require semver to be used for the release tag pattern. If set to false, the release tag pattern will not be checked for semver compliance."
|
213
|
+
},
|
214
|
+
"releaseTagPatternStrictPreid": {
|
215
|
+
"$ref": "#/definitions/NxReleaseReleaseTagPatternStrictPreidConfiguration"
|
216
|
+
},
|
210
217
|
"versionPlans": {
|
211
218
|
"oneOf": [
|
212
219
|
{
|
@@ -295,6 +302,13 @@
|
|
295
302
|
}
|
296
303
|
],
|
297
304
|
"description": "By default, we will try and resolve the latest match for the releaseTagPattern from the current branch, falling back to all branches if no match is found on the current branch. Setting this to true will cause us to ALWAYS check all branches for the latest match. Setting it to false will cause us to ONLY check the current branch for the latest match. Setting it to an array of strings will cause us to check all branches WHEN the current branch is one of the strings in the array. Glob patterns are supported."
|
305
|
+
},
|
306
|
+
"releaseTagPatternRequireSemver": {
|
307
|
+
"type": "boolean",
|
308
|
+
"description": "Whether to require semver to be used for the release tag pattern. If set to false, the release tag pattern will not be checked for semver compliance."
|
309
|
+
},
|
310
|
+
"releaseTagPatternStrictPreid": {
|
311
|
+
"$ref": "#/definitions/NxReleaseReleaseTagPatternStrictPreidConfiguration"
|
298
312
|
}
|
299
313
|
}
|
300
314
|
},
|
@@ -925,6 +939,10 @@
|
|
925
939
|
}
|
926
940
|
}
|
927
941
|
},
|
942
|
+
"NxReleaseReleaseTagPatternStrictPreidConfiguration": {
|
943
|
+
"type": "boolean",
|
944
|
+
"description": "When set to true and multiple tags match your configured \"releaseTagPattern\", the git tag matching logic will strictly prefer the tag which contain a semver preid which matches the one given to the nx release invocation.\n\nFor example, let's say your \"releaseTagPattern\" is \"{projectName}@{version}\" and you have the following tags for project \"my-lib\", which uses semver:\n- my-lib@1.2.4-beta.1\n- my-lib@1.2.4-alpha.1\n- my-lib@1.2.3\n\nIf \"releaseTagPatternStrictPreid\" is set to true and you run:\n- `nx release --preid beta`, the git tag \"my-lib@1.2.4-beta.1\" will be resolved.\n- `nx release --preid alpha`, the git tag \"my-lib@1.2.4-alpha.1\" will be resolved.\n- `nx release` (no preid), the git tag \"my-lib@1.2.3\" will be resolved.\n\nIf \"releaseTagPatternStrictPreid\" is set to false, the git tag \"my-lib@1.2.4-beta.1\" will always be resolved as the latest tag that matches the pattern, regardless of any preid which gets passed to nx release.\n\nNOTE: This feature was added in a minor version and is therefore set to false by default, but this may change in a future major version."
|
945
|
+
},
|
928
946
|
"ChangelogRenderOptions": {
|
929
947
|
"type": "object",
|
930
948
|
"additionalProperties": true
|
@@ -5,6 +5,7 @@ exports.createAPI = createAPI;
|
|
5
5
|
const chalk = require("chalk");
|
6
6
|
const enquirer_1 = require("enquirer");
|
7
7
|
const node_fs_1 = require("node:fs");
|
8
|
+
const semver_1 = require("semver");
|
8
9
|
const tmp_1 = require("tmp");
|
9
10
|
const nx_json_1 = require("../../config/nx-json");
|
10
11
|
const tree_1 = require("../../generators/tree");
|
@@ -120,6 +121,16 @@ function createAPI(overrideReleaseConfig) {
|
|
120
121
|
const to = args.to || 'HEAD';
|
121
122
|
const toSHA = await (0, git_1.getCommitHash)(to);
|
122
123
|
const headSHA = to === 'HEAD' ? toSHA : await (0, git_1.getCommitHash)('HEAD');
|
124
|
+
/**
|
125
|
+
* Extract the preid from the workspace version and the project versions
|
126
|
+
*/
|
127
|
+
const workspacePreid = workspaceChangelogVersion
|
128
|
+
? extractPreid(workspaceChangelogVersion)
|
129
|
+
: undefined;
|
130
|
+
const projectsPreid = Object.fromEntries(Object.entries(projectsVersionData).map(([projectName, v]) => [
|
131
|
+
projectName,
|
132
|
+
v.newVersion ? extractPreid(v.newVersion) : undefined,
|
133
|
+
]));
|
123
134
|
/**
|
124
135
|
* Protect the user against attempting to create a new commit when recreating an old release changelog,
|
125
136
|
* this seems like it would always be unintentional.
|
@@ -191,7 +202,13 @@ function createAPI(overrideReleaseConfig) {
|
|
191
202
|
}
|
192
203
|
else {
|
193
204
|
let workspaceChangelogFromRef = args.from ||
|
194
|
-
(await (0, git_1.getLatestGitTagForPattern)(nxReleaseConfig.releaseTagPattern, {},
|
205
|
+
(await (0, git_1.getLatestGitTagForPattern)(nxReleaseConfig.releaseTagPattern, {}, {
|
206
|
+
checkAllBranchesWhen: nxReleaseConfig.releaseTagPatternCheckAllBranchesWhen,
|
207
|
+
preid: workspacePreid ??
|
208
|
+
projectsPreid?.[Object.keys(projectsPreid)[0]],
|
209
|
+
releaseTagPatternRequireSemver: nxReleaseConfig.releaseTagPatternRequireSemver,
|
210
|
+
releaseTagPatternStrictPreid: nxReleaseConfig.releaseTagPatternStrictPreid,
|
211
|
+
}))?.tag;
|
195
212
|
if (!workspaceChangelogFromRef) {
|
196
213
|
if (useAutomaticFromRef) {
|
197
214
|
workspaceChangelogFromRef = await (0, git_1.getFirstGitCommit)();
|
@@ -326,7 +343,12 @@ function createAPI(overrideReleaseConfig) {
|
|
326
343
|
(await (0, git_1.getLatestGitTagForPattern)(releaseGroup.releaseTagPattern, {
|
327
344
|
projectName: project.name,
|
328
345
|
releaseGroupName: releaseGroup.name,
|
329
|
-
},
|
346
|
+
}, {
|
347
|
+
checkAllBranchesWhen: releaseGroup.releaseTagPatternCheckAllBranchesWhen,
|
348
|
+
preid: projectsPreid[project.name],
|
349
|
+
releaseTagPatternRequireSemver: releaseGroup.releaseTagPatternRequireSemver,
|
350
|
+
releaseTagPatternStrictPreid: releaseGroup.releaseTagPatternStrictPreid,
|
351
|
+
}))?.tag;
|
330
352
|
if (!fromRef && useAutomaticFromRef) {
|
331
353
|
const firstCommit = await (0, git_1.getFirstGitCommit)();
|
332
354
|
commits = await filterProjectCommits({
|
@@ -436,7 +458,13 @@ function createAPI(overrideReleaseConfig) {
|
|
436
458
|
}
|
437
459
|
else {
|
438
460
|
let fromRef = args.from ||
|
439
|
-
(await (0, git_1.getLatestGitTagForPattern)(releaseGroup.releaseTagPattern, {},
|
461
|
+
(await (0, git_1.getLatestGitTagForPattern)(releaseGroup.releaseTagPattern, {}, {
|
462
|
+
checkAllBranchesWhen: releaseGroup.releaseTagPatternCheckAllBranchesWhen,
|
463
|
+
preid: workspacePreid ??
|
464
|
+
projectsPreid?.[Object.keys(projectsPreid)[0]],
|
465
|
+
releaseTagPatternRequireSemver: releaseGroup.releaseTagPatternRequireSemver,
|
466
|
+
releaseTagPatternStrictPreid: releaseGroup.releaseTagPatternStrictPreid,
|
467
|
+
}))?.tag;
|
440
468
|
if (!fromRef) {
|
441
469
|
if (useAutomaticFromRef) {
|
442
470
|
fromRef = await (0, git_1.getFirstGitCommit)();
|
@@ -967,3 +995,19 @@ function versionPlanSemverReleaseTypeToChangelogType(bump) {
|
|
967
995
|
throw new Error(`Invalid semver bump type: ${bump}`);
|
968
996
|
}
|
969
997
|
}
|
998
|
+
function extractPreid(version) {
|
999
|
+
if (!(0, shared_1.isPrerelease)(version)) {
|
1000
|
+
return undefined;
|
1001
|
+
}
|
1002
|
+
const preid = (0, semver_1.prerelease)(version)?.[0];
|
1003
|
+
if (typeof preid === 'string') {
|
1004
|
+
if (preid.trim() === '') {
|
1005
|
+
return undefined;
|
1006
|
+
}
|
1007
|
+
return preid;
|
1008
|
+
}
|
1009
|
+
if (typeof preid === 'number') {
|
1010
|
+
return preid.toString();
|
1011
|
+
}
|
1012
|
+
return undefined;
|
1013
|
+
}
|
@@ -114,11 +114,15 @@ async function createNxReleaseConfig(projectGraph, projectFileMap, userConfig =
|
|
114
114
|
};
|
115
115
|
const defaultFixedReleaseTagPattern = 'v{version}';
|
116
116
|
/**
|
117
|
-
* TODO(
|
117
|
+
* TODO(v22): in v22, make it so that this pattern is used by default when any custom groups are used
|
118
118
|
*/
|
119
119
|
const defaultFixedGroupReleaseTagPattern = '{releaseGroupName}-v{version}';
|
120
120
|
const defaultIndependentReleaseTagPattern = '{projectName}@{version}';
|
121
121
|
const defaultReleaseTagPatternRequireSemver = true;
|
122
|
+
/**
|
123
|
+
* TODO(v22): in v22, set this to true by default
|
124
|
+
*/
|
125
|
+
const defaultReleaseTagPatternStrictPreid = false;
|
122
126
|
const workspaceProjectsRelationship = userConfig.projectsRelationship || 'fixed';
|
123
127
|
const defaultGeneratorOptions = {};
|
124
128
|
if (userConfig.version?.conventionalCommits) {
|
@@ -203,6 +207,8 @@ async function createNxReleaseConfig(projectGraph, projectFileMap, userConfig =
|
|
203
207
|
releaseTagPatternCheckAllBranchesWhen: userConfig.releaseTagPatternCheckAllBranchesWhen ?? undefined,
|
204
208
|
releaseTagPatternRequireSemver: userConfig.releaseTagPatternRequireSemver ??
|
205
209
|
defaultReleaseTagPatternRequireSemver,
|
210
|
+
releaseTagPatternStrictPreid: userConfig.releaseTagPatternStrictPreid ??
|
211
|
+
defaultReleaseTagPatternStrictPreid,
|
206
212
|
conventionalCommits: conventional_commits_1.DEFAULT_CONVENTIONAL_COMMITS_CONFIG,
|
207
213
|
versionPlans: (userConfig.versionPlans ||
|
208
214
|
false),
|
@@ -210,6 +216,8 @@ async function createNxReleaseConfig(projectGraph, projectFileMap, userConfig =
|
|
210
216
|
const groupProjectsRelationship = userConfig.projectsRelationship || WORKSPACE_DEFAULTS.projectsRelationship;
|
211
217
|
const groupReleaseTagPatternRequireSemver = userConfig.releaseTagPatternRequireSemver ??
|
212
218
|
WORKSPACE_DEFAULTS.releaseTagPatternRequireSemver;
|
219
|
+
const groupReleaseTagPatternStrictPreid = userConfig.releaseTagPatternStrictPreid ??
|
220
|
+
defaultReleaseTagPatternStrictPreid;
|
213
221
|
const GROUP_DEFAULTS = {
|
214
222
|
projectsRelationship: groupProjectsRelationship,
|
215
223
|
version: USE_LEGACY_VERSIONING
|
@@ -244,6 +252,7 @@ async function createNxReleaseConfig(projectGraph, projectFileMap, userConfig =
|
|
244
252
|
: WORKSPACE_DEFAULTS.releaseTagPattern,
|
245
253
|
releaseTagPatternCheckAllBranchesWhen: userConfig.releaseTagPatternCheckAllBranchesWhen ?? undefined,
|
246
254
|
releaseTagPatternRequireSemver: groupReleaseTagPatternRequireSemver,
|
255
|
+
releaseTagPatternStrictPreid: groupReleaseTagPatternStrictPreid,
|
247
256
|
versionPlans: false,
|
248
257
|
};
|
249
258
|
/**
|
@@ -429,6 +438,9 @@ async function createNxReleaseConfig(projectGraph, projectFileMap, userConfig =
|
|
429
438
|
releaseTagPatternRequireSemver: releaseGroup.releaseTagPatternRequireSemver ??
|
430
439
|
userConfig.releaseTagPatternRequireSemver ??
|
431
440
|
defaultReleaseTagPatternRequireSemver,
|
441
|
+
releaseTagPatternStrictPreid: releaseGroup.releaseTagPatternStrictPreid ??
|
442
|
+
userConfig.releaseTagPatternStrictPreid ??
|
443
|
+
defaultReleaseTagPatternStrictPreid,
|
432
444
|
versionPlans: releaseGroup.versionPlans ?? rootVersionPlansConfig,
|
433
445
|
};
|
434
446
|
const finalReleaseGroup = deepMergeDefaults([groupDefaults], {
|
@@ -503,6 +515,7 @@ async function createNxReleaseConfig(projectGraph, projectFileMap, userConfig =
|
|
503
515
|
releaseTagPattern: WORKSPACE_DEFAULTS.releaseTagPattern,
|
504
516
|
releaseTagPatternCheckAllBranchesWhen: WORKSPACE_DEFAULTS.releaseTagPatternCheckAllBranchesWhen,
|
505
517
|
releaseTagPatternRequireSemver: WORKSPACE_DEFAULTS.releaseTagPatternRequireSemver,
|
518
|
+
releaseTagPatternStrictPreid: WORKSPACE_DEFAULTS.releaseTagPatternStrictPreid,
|
506
519
|
git: rootGitConfig,
|
507
520
|
version: rootVersionConfig,
|
508
521
|
changelog: rootChangelogConfig,
|
@@ -12,6 +12,10 @@ export interface Reference {
|
|
12
12
|
type: 'hash' | 'issue' | 'pull-request';
|
13
13
|
value: string;
|
14
14
|
}
|
15
|
+
export interface GitTagAndVersion {
|
16
|
+
tag: string;
|
17
|
+
extractedVersion: string;
|
18
|
+
}
|
15
19
|
export interface GitCommit extends RawGitCommit {
|
16
20
|
description: string;
|
17
21
|
type: string;
|
@@ -22,10 +26,37 @@ export interface GitCommit extends RawGitCommit {
|
|
22
26
|
affectedFiles: string[];
|
23
27
|
revertedHashes: string[];
|
24
28
|
}
|
25
|
-
export
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
+
export interface GetLatestGitTagForPatternOptions {
|
30
|
+
checkAllBranchesWhen?: boolean | string[];
|
31
|
+
preid?: string;
|
32
|
+
releaseTagPatternRequireSemver: boolean;
|
33
|
+
releaseTagPatternStrictPreid: boolean;
|
34
|
+
}
|
35
|
+
/**
|
36
|
+
* Extract the tag and version from a tag string
|
37
|
+
*
|
38
|
+
* @param tag - The tag string to extract the tag and version from
|
39
|
+
* @param tagRegexp - The regex to use to extract the tag and version from the tag string
|
40
|
+
*
|
41
|
+
* @returns The tag and version
|
42
|
+
*/
|
43
|
+
export declare function extractTagAndVersion(tag: string, tagRegexp: string, options: GetLatestGitTagForPatternOptions): GitTagAndVersion;
|
44
|
+
/**
|
45
|
+
* Get the latest git tag for the configured release tag pattern.
|
46
|
+
*
|
47
|
+
* This function will:
|
48
|
+
* - Get all tags from the git repo, sorted by version
|
49
|
+
* - Filter the tags into a list with SEMVER-compliant tags, matching the release tag pattern
|
50
|
+
* - If a preid is provided, prioritise tags for that preid, then semver tags without a preid
|
51
|
+
* - If no preid is provided, search only for stable semver tags (i.e. no pre-release or build metadata)
|
52
|
+
*
|
53
|
+
* @param releaseTagPattern - The pattern to filter the tags list by
|
54
|
+
* @param additionalInterpolationData - Additional data used when interpolating the release tag pattern
|
55
|
+
* @param options - The options to use when getting the latest git tag for the pattern
|
56
|
+
*
|
57
|
+
* @returns The tag and version
|
58
|
+
*/
|
59
|
+
export declare function getLatestGitTagForPattern(releaseTagPattern: string, additionalInterpolationData: {}, options: GetLatestGitTagForPatternOptions): Promise<GitTagAndVersion | null>;
|
29
60
|
export declare function getGitDiff(from: string | undefined, to?: string): Promise<RawGitCommit[]>;
|
30
61
|
export declare function gitAdd({ changedFiles, deletedFiles, dryRun, verbose, logFn, cwd, }: {
|
31
62
|
changedFiles?: string[];
|
@@ -1,5 +1,6 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.extractTagAndVersion = extractTagAndVersion;
|
3
4
|
exports.getLatestGitTagForPattern = getLatestGitTagForPattern;
|
4
5
|
exports.getGitDiff = getGitDiff;
|
5
6
|
exports.gitAdd = gitAdd;
|
@@ -21,12 +22,50 @@ const minimatch_1 = require("minimatch");
|
|
21
22
|
const utils_1 = require("../../../tasks-runner/utils");
|
22
23
|
const workspace_root_1 = require("../../../utils/workspace-root");
|
23
24
|
const exec_command_1 = require("./exec-command");
|
25
|
+
const shared_1 = require("./shared");
|
24
26
|
function escapeRegExp(string) {
|
25
27
|
return string.replace(/[/\-\\^$*+?.()|[\]{}]/g, '\\$&');
|
26
28
|
}
|
27
29
|
// https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string
|
28
30
|
const SEMVER_REGEX = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/g;
|
29
|
-
|
31
|
+
/**
|
32
|
+
* Extract the tag and version from a tag string
|
33
|
+
*
|
34
|
+
* @param tag - The tag string to extract the tag and version from
|
35
|
+
* @param tagRegexp - The regex to use to extract the tag and version from the tag string
|
36
|
+
*
|
37
|
+
* @returns The tag and version
|
38
|
+
*/
|
39
|
+
function extractTagAndVersion(tag, tagRegexp, options) {
|
40
|
+
const { releaseTagPatternRequireSemver } = options;
|
41
|
+
const [latestMatchingTag, ...rest] = tag.match(tagRegexp);
|
42
|
+
let version = releaseTagPatternRequireSemver
|
43
|
+
? rest.filter((r) => {
|
44
|
+
return r.match(SEMVER_REGEX);
|
45
|
+
})[0]
|
46
|
+
: rest[0];
|
47
|
+
return {
|
48
|
+
tag: latestMatchingTag,
|
49
|
+
extractedVersion: version ?? null,
|
50
|
+
};
|
51
|
+
}
|
52
|
+
/**
|
53
|
+
* Get the latest git tag for the configured release tag pattern.
|
54
|
+
*
|
55
|
+
* This function will:
|
56
|
+
* - Get all tags from the git repo, sorted by version
|
57
|
+
* - Filter the tags into a list with SEMVER-compliant tags, matching the release tag pattern
|
58
|
+
* - If a preid is provided, prioritise tags for that preid, then semver tags without a preid
|
59
|
+
* - If no preid is provided, search only for stable semver tags (i.e. no pre-release or build metadata)
|
60
|
+
*
|
61
|
+
* @param releaseTagPattern - The pattern to filter the tags list by
|
62
|
+
* @param additionalInterpolationData - Additional data used when interpolating the release tag pattern
|
63
|
+
* @param options - The options to use when getting the latest git tag for the pattern
|
64
|
+
*
|
65
|
+
* @returns The tag and version
|
66
|
+
*/
|
67
|
+
async function getLatestGitTagForPattern(releaseTagPattern, additionalInterpolationData = {}, options) {
|
68
|
+
const { checkAllBranchesWhen, releaseTagPatternRequireSemver, releaseTagPatternStrictPreid, preid, } = options;
|
30
69
|
/**
|
31
70
|
* By default, we will try and resolve the latest match for the releaseTagPattern from the current branch,
|
32
71
|
* falling back to all branches if no match is found on the current branch.
|
@@ -118,16 +157,37 @@ async function getLatestGitTagForPattern(releaseTagPattern, additionalInterpolat
|
|
118
157
|
if (!matchingTags.length) {
|
119
158
|
return null;
|
120
159
|
}
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
160
|
+
if (!releaseTagPatternStrictPreid) {
|
161
|
+
// If not using strict preid, we can just return the first matching tag
|
162
|
+
return extractTagAndVersion(matchingTags[0], tagRegexp, options);
|
163
|
+
}
|
164
|
+
if (preid && preid.length > 0) {
|
165
|
+
// When a preid is provided, first try to find a tag for it
|
166
|
+
const preidReleaseTags = matchingTags.filter((tag) => {
|
167
|
+
const match = tag.match(tagRegexp);
|
168
|
+
if (!match)
|
169
|
+
return false;
|
170
|
+
const version = match.find((part) => part.match(SEMVER_REGEX));
|
171
|
+
return version && version.includes(`-${preid}.`);
|
172
|
+
});
|
173
|
+
if (preidReleaseTags.length > 0) {
|
174
|
+
return extractTagAndVersion(preidReleaseTags[0], tagRegexp, options);
|
175
|
+
}
|
176
|
+
}
|
177
|
+
// Then try to find the latest stable release tag
|
178
|
+
const stableReleaseTags = matchingTags.filter((tag) => {
|
179
|
+
const matches = tag.match(tagRegexp);
|
180
|
+
if (!matches)
|
181
|
+
return false;
|
182
|
+
const [, version] = matches;
|
183
|
+
return version && !(0, shared_1.isPrerelease)(version);
|
184
|
+
});
|
185
|
+
// If there are stable release tags, use the latest one
|
186
|
+
if (stableReleaseTags.length > 0) {
|
187
|
+
return extractTagAndVersion(stableReleaseTags[0], tagRegexp, options);
|
188
|
+
}
|
189
|
+
// Otherwise return null
|
190
|
+
return null;
|
131
191
|
}
|
132
192
|
catch {
|
133
193
|
return null;
|
@@ -1,6 +1,7 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
3
|
exports.ReleaseVersion = exports.noDiffInChangelogMessage = void 0;
|
4
|
+
exports.isPrerelease = isPrerelease;
|
4
5
|
exports.commitChanges = commitChanges;
|
5
6
|
exports.createCommitMessageValues = createCommitMessageValues;
|
6
7
|
exports.createGitTagValues = createGitTagValues;
|
@@ -198,7 +198,12 @@ class ReleaseGroupProcessor {
|
|
198
198
|
if (finalConfigForProject.currentVersionResolver === 'git-tag') {
|
199
199
|
latestMatchingGitTag = await (0, git_1.getLatestGitTagForPattern)(releaseTagPattern, {
|
200
200
|
projectName: projectGraphNode.name,
|
201
|
-
},
|
201
|
+
}, {
|
202
|
+
checkAllBranchesWhen: releaseGroupNode.group.releaseTagPatternCheckAllBranchesWhen,
|
203
|
+
preid: this.options.preid,
|
204
|
+
releaseTagPatternRequireSemver: releaseGroupNode.group.releaseTagPatternRequireSemver,
|
205
|
+
releaseTagPatternStrictPreid: releaseGroupNode.group.releaseTagPatternStrictPreid,
|
206
|
+
});
|
202
207
|
this.cachedLatestMatchingGitTag.set(projectName, latestMatchingGitTag);
|
203
208
|
}
|
204
209
|
// Cache the current version for the project
|
package/src/config/nx-json.d.ts
CHANGED
@@ -349,6 +349,26 @@ export interface NxReleaseConfiguration {
|
|
349
349
|
* - Setting this to false will cause us to not use semver to match the version allowing for non-semver versions
|
350
350
|
*/
|
351
351
|
releaseTagPatternRequireSemver?: boolean;
|
352
|
+
/**
|
353
|
+
* When set to true and multiple tags match your configured "releaseTagPattern", the git tag matching logic will strictly prefer the tag which contain a semver preid which matches the one
|
354
|
+
* given to the nx release invocation.
|
355
|
+
*
|
356
|
+
* For example, let's say your "releaseTagPattern" is "{projectName}@{version}" and you have the following tags for project "my-lib", which uses semver:
|
357
|
+
* - my-lib@1.2.4-beta.1
|
358
|
+
* - my-lib@1.2.4-alpha.1
|
359
|
+
* - my-lib@1.2.3
|
360
|
+
*
|
361
|
+
* If "releaseTagPatternStrictPreid" is set to true and you run:
|
362
|
+
* - `nx release --preid beta`, the git tag "my-lib@1.2.4-beta.1" will be resolved.
|
363
|
+
* - `nx release --preid alpha`, the git tag "my-lib@1.2.4-alpha.1" will be resolved.
|
364
|
+
* - `nx release` (no preid), the git tag "my-lib@1.2.3" will be resolved.
|
365
|
+
*
|
366
|
+
* If "releaseTagPatternStrictPreid" is set to false, the git tag "my-lib@1.2.4-beta.1" will always be resolved as the latest tag that matches the pattern,
|
367
|
+
* regardless of any preid which gets passed to nx release.
|
368
|
+
*
|
369
|
+
* NOTE: This feature was added in a minor version and is therefore set to false by default, but this may change in a future major version.
|
370
|
+
*/
|
371
|
+
releaseTagPatternStrictPreid?: boolean;
|
352
372
|
/**
|
353
373
|
* Enables using version plans as a specifier source for versioning and
|
354
374
|
* to determine changes for changelog generation.
|
@@ -424,6 +444,26 @@ export interface NxReleaseConfiguration {
|
|
424
444
|
* - Setting this to false will cause us to not use semver to match the version allowing for non-semver versions
|
425
445
|
*/
|
426
446
|
releaseTagPatternRequireSemver?: boolean;
|
447
|
+
/**
|
448
|
+
* When set to true and multiple tags match your configured "releaseTagPattern", the git tag matching logic will strictly prefer the tag which contain a semver preid which matches the one
|
449
|
+
* given to the nx release invocation.
|
450
|
+
*
|
451
|
+
* For example, let's say your "releaseTagPattern" is "{projectName}@{version}" and you have the following tags for project "my-lib", which uses semver:
|
452
|
+
* - my-lib@1.2.4-beta.1
|
453
|
+
* - my-lib@1.2.4-alpha.1
|
454
|
+
* - my-lib@1.2.3
|
455
|
+
*
|
456
|
+
* If "releaseTagPatternStrictPreid" is set to true and you run:
|
457
|
+
* - `nx release --preid beta`, the git tag "my-lib@1.2.4-beta.1" will be resolved.
|
458
|
+
* - `nx release --preid alpha`, the git tag "my-lib@1.2.4-alpha.1" will be resolved.
|
459
|
+
* - `nx release` (no preid), the git tag "my-lib@1.2.3" will be resolved.
|
460
|
+
*
|
461
|
+
* If "releaseTagPatternStrictPreid" is set to false, the git tag "my-lib@1.2.4-beta.1" will always be resolved as the latest tag that matches the pattern,
|
462
|
+
* regardless of any preid which gets passed to nx release.
|
463
|
+
*
|
464
|
+
* NOTE: This feature was added in a minor version and is therefore set to false by default, but this may change in a future major version.
|
465
|
+
*/
|
466
|
+
releaseTagPatternStrictPreid?: boolean;
|
427
467
|
/**
|
428
468
|
* Enable and configure automatic git operations as part of the release
|
429
469
|
*/
|