@releasekit/version 0.3.0-next.3 → 0.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/README.md +5 -3
- package/dist/cli.js +0 -105
- package/docs/CI_CD_INTEGRATION.md +13 -13
- package/docs/versioning.md +14 -14
- package/package.json +14 -12
- package/version.schema.json +1 -1
- package/dist/baseError-ZCZHF6A2.js +0 -7
- package/dist/chunk-GQLJ7JQY.js +0 -18
- package/dist/chunk-LMPZV35Z.js +0 -20
- package/dist/chunk-ZEXPJ53Z.js +0 -2061
- package/dist/cli.cjs +0 -2230
- package/dist/cli.d.cts +0 -4
- package/dist/cli.d.ts +0 -4
- package/dist/commandExecutor-E44ID5U4.js +0 -8
- package/dist/index.cjs +0 -2150
- package/dist/index.d.cts +0 -208
- package/dist/index.d.ts +0 -208
- package/dist/index.js +0 -31
package/dist/cli.cjs
DELETED
|
@@ -1,2230 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
"use strict";
|
|
3
|
-
var __create = Object.create;
|
|
4
|
-
var __defProp = Object.defineProperty;
|
|
5
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
-
var __esm = (fn, res) => function __init() {
|
|
10
|
-
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
11
|
-
};
|
|
12
|
-
var __export = (target, all) => {
|
|
13
|
-
for (var name in all)
|
|
14
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
15
|
-
};
|
|
16
|
-
var __copyProps = (to, from, except, desc) => {
|
|
17
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
18
|
-
for (let key of __getOwnPropNames(from))
|
|
19
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
20
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
21
|
-
}
|
|
22
|
-
return to;
|
|
23
|
-
};
|
|
24
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
25
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
26
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
27
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
28
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
29
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
30
|
-
mod
|
|
31
|
-
));
|
|
32
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
33
|
-
|
|
34
|
-
// src/errors/baseError.ts
|
|
35
|
-
var baseError_exports = {};
|
|
36
|
-
__export(baseError_exports, {
|
|
37
|
-
BasePackageVersionerError: () => BaseVersionError,
|
|
38
|
-
BaseVersionError: () => BaseVersionError
|
|
39
|
-
});
|
|
40
|
-
var import_core, BaseVersionError;
|
|
41
|
-
var init_baseError = __esm({
|
|
42
|
-
"src/errors/baseError.ts"() {
|
|
43
|
-
"use strict";
|
|
44
|
-
import_core = require("@releasekit/core");
|
|
45
|
-
BaseVersionError = class _BaseVersionError extends import_core.ReleaseKitError {
|
|
46
|
-
code;
|
|
47
|
-
suggestions;
|
|
48
|
-
constructor(message, code, suggestions) {
|
|
49
|
-
super(message);
|
|
50
|
-
this.code = code;
|
|
51
|
-
this.suggestions = suggestions ?? [];
|
|
52
|
-
}
|
|
53
|
-
static isVersionError(error) {
|
|
54
|
-
return error instanceof _BaseVersionError;
|
|
55
|
-
}
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
// src/git/commandExecutor.ts
|
|
61
|
-
var commandExecutor_exports = {};
|
|
62
|
-
__export(commandExecutor_exports, {
|
|
63
|
-
execAsync: () => execAsync,
|
|
64
|
-
execSync: () => execSync
|
|
65
|
-
});
|
|
66
|
-
var import_node_child_process, execAsync, execSync;
|
|
67
|
-
var init_commandExecutor = __esm({
|
|
68
|
-
"src/git/commandExecutor.ts"() {
|
|
69
|
-
"use strict";
|
|
70
|
-
import_node_child_process = require("child_process");
|
|
71
|
-
execAsync = (file, args, options) => {
|
|
72
|
-
const defaultOptions = { maxBuffer: 1024 * 1024 * 10, ...options };
|
|
73
|
-
return new Promise((resolve2, reject) => {
|
|
74
|
-
(0, import_node_child_process.execFile)(file, args, defaultOptions, (error, stdout, stderr) => {
|
|
75
|
-
if (error) {
|
|
76
|
-
reject(error);
|
|
77
|
-
} else {
|
|
78
|
-
resolve2({ stdout: stdout.toString(), stderr: stderr.toString() });
|
|
79
|
-
}
|
|
80
|
-
});
|
|
81
|
-
});
|
|
82
|
-
};
|
|
83
|
-
execSync = (file, args, options) => (0, import_node_child_process.execFileSync)(file, args, { maxBuffer: 1024 * 1024 * 10, ...options });
|
|
84
|
-
}
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
// src/cli.ts
|
|
88
|
-
var cli_exports = {};
|
|
89
|
-
__export(cli_exports, {
|
|
90
|
-
run: () => run
|
|
91
|
-
});
|
|
92
|
-
module.exports = __toCommonJS(cli_exports);
|
|
93
|
-
var fs7 = __toESM(require("fs"), 1);
|
|
94
|
-
var import_node_path7 = __toESM(require("path"), 1);
|
|
95
|
-
var import_commander = require("commander");
|
|
96
|
-
|
|
97
|
-
// src/config.ts
|
|
98
|
-
var import_config = require("@releasekit/config");
|
|
99
|
-
|
|
100
|
-
// src/types.ts
|
|
101
|
-
function toVersionConfig(config, gitConfig) {
|
|
102
|
-
if (!config) {
|
|
103
|
-
return {
|
|
104
|
-
tagTemplate: "v{version}",
|
|
105
|
-
packageSpecificTags: false,
|
|
106
|
-
preset: "conventional",
|
|
107
|
-
sync: true,
|
|
108
|
-
packages: [],
|
|
109
|
-
updateInternalDependencies: "minor",
|
|
110
|
-
versionPrefix: "",
|
|
111
|
-
baseBranch: gitConfig?.branch
|
|
112
|
-
};
|
|
113
|
-
}
|
|
114
|
-
return {
|
|
115
|
-
tagTemplate: config.tagTemplate ?? "v{version}",
|
|
116
|
-
packageSpecificTags: config.packageSpecificTags,
|
|
117
|
-
preset: config.preset ?? "conventional",
|
|
118
|
-
sync: config.sync ?? true,
|
|
119
|
-
packages: config.packages ?? [],
|
|
120
|
-
mainPackage: config.mainPackage,
|
|
121
|
-
updateInternalDependencies: config.updateInternalDependencies ?? "minor",
|
|
122
|
-
skip: config.skip,
|
|
123
|
-
commitMessage: config.commitMessage,
|
|
124
|
-
versionStrategy: config.versionStrategy,
|
|
125
|
-
branchPatterns: config.branchPatterns?.map((bp) => ({
|
|
126
|
-
pattern: bp.pattern,
|
|
127
|
-
releaseType: bp.releaseType
|
|
128
|
-
})),
|
|
129
|
-
defaultReleaseType: config.defaultReleaseType,
|
|
130
|
-
mismatchStrategy: config.mismatchStrategy,
|
|
131
|
-
versionPrefix: config.versionPrefix ?? "",
|
|
132
|
-
prereleaseIdentifier: config.prereleaseIdentifier,
|
|
133
|
-
baseBranch: gitConfig?.branch,
|
|
134
|
-
cargo: config.cargo
|
|
135
|
-
};
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
// src/config.ts
|
|
139
|
-
function loadConfig(options) {
|
|
140
|
-
const fullConfig = (0, import_config.loadConfig)(options);
|
|
141
|
-
return toVersionConfig(fullConfig.version, fullConfig.git);
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
// src/core/versionEngine.ts
|
|
145
|
-
var import_node_process2 = require("process");
|
|
146
|
-
var import_get_packages = require("@manypkg/get-packages");
|
|
147
|
-
|
|
148
|
-
// src/errors/gitError.ts
|
|
149
|
-
init_baseError();
|
|
150
|
-
var GitError = class extends BaseVersionError {
|
|
151
|
-
};
|
|
152
|
-
|
|
153
|
-
// src/errors/versionError.ts
|
|
154
|
-
init_baseError();
|
|
155
|
-
var VersionError = class extends BaseVersionError {
|
|
156
|
-
};
|
|
157
|
-
function createVersionError(code, details) {
|
|
158
|
-
const messages = {
|
|
159
|
-
["CONFIG_REQUIRED" /* CONFIG_REQUIRED */]: "Configuration is required",
|
|
160
|
-
["PACKAGES_NOT_FOUND" /* PACKAGES_NOT_FOUND */]: "Failed to get packages information",
|
|
161
|
-
["WORKSPACE_ERROR" /* WORKSPACE_ERROR */]: "Failed to get workspace packages",
|
|
162
|
-
["INVALID_CONFIG" /* INVALID_CONFIG */]: "Invalid configuration",
|
|
163
|
-
["PACKAGE_NOT_FOUND" /* PACKAGE_NOT_FOUND */]: "Package not found",
|
|
164
|
-
["VERSION_CALCULATION_ERROR" /* VERSION_CALCULATION_ERROR */]: "Failed to calculate version"
|
|
165
|
-
};
|
|
166
|
-
const suggestions = {
|
|
167
|
-
["CONFIG_REQUIRED" /* CONFIG_REQUIRED */]: [
|
|
168
|
-
"Create a version.config.json file in your project root",
|
|
169
|
-
"Check the documentation for configuration examples"
|
|
170
|
-
],
|
|
171
|
-
["PACKAGES_NOT_FOUND" /* PACKAGES_NOT_FOUND */]: [
|
|
172
|
-
"Ensure package.json or Cargo.toml files exist in your project",
|
|
173
|
-
"Check workspace configuration (pnpm-workspace.yaml, etc.)",
|
|
174
|
-
"Verify file permissions and paths"
|
|
175
|
-
],
|
|
176
|
-
["WORKSPACE_ERROR" /* WORKSPACE_ERROR */]: [
|
|
177
|
-
"Verify workspace configuration files are valid",
|
|
178
|
-
"Check that workspace packages are accessible",
|
|
179
|
-
"Ensure proper monorepo structure"
|
|
180
|
-
],
|
|
181
|
-
["INVALID_CONFIG" /* INVALID_CONFIG */]: [
|
|
182
|
-
"Validate version.config.json syntax",
|
|
183
|
-
"Check configuration against schema",
|
|
184
|
-
"Review documentation for valid configuration options"
|
|
185
|
-
],
|
|
186
|
-
["PACKAGE_NOT_FOUND" /* PACKAGE_NOT_FOUND */]: [
|
|
187
|
-
"Verify package name spelling and case",
|
|
188
|
-
"Check if package exists in workspace",
|
|
189
|
-
"Review packages configuration in version.config.json"
|
|
190
|
-
],
|
|
191
|
-
["VERSION_CALCULATION_ERROR" /* VERSION_CALCULATION_ERROR */]: [
|
|
192
|
-
"Ensure git repository has commits",
|
|
193
|
-
"Check conventional commit message format",
|
|
194
|
-
"Verify git tags are properly formatted"
|
|
195
|
-
]
|
|
196
|
-
};
|
|
197
|
-
const baseMessage = messages[code];
|
|
198
|
-
const fullMessage = details ? `${baseMessage}: ${details}` : baseMessage;
|
|
199
|
-
return new VersionError(fullMessage, code, suggestions[code]);
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
// src/utils/logging.ts
|
|
203
|
-
var import_chalk = __toESM(require("chalk"), 1);
|
|
204
|
-
var import_figlet = __toESM(require("figlet"), 1);
|
|
205
|
-
|
|
206
|
-
// src/utils/jsonOutput.ts
|
|
207
|
-
var _jsonOutputMode = false;
|
|
208
|
-
var _jsonData = {
|
|
209
|
-
dryRun: false,
|
|
210
|
-
updates: [],
|
|
211
|
-
changelogs: [],
|
|
212
|
-
tags: []
|
|
213
|
-
};
|
|
214
|
-
function enableJsonOutput(dryRun = false) {
|
|
215
|
-
_jsonOutputMode = true;
|
|
216
|
-
_jsonData.dryRun = dryRun;
|
|
217
|
-
_jsonData.updates = [];
|
|
218
|
-
_jsonData.changelogs = [];
|
|
219
|
-
_jsonData.tags = [];
|
|
220
|
-
_jsonData.commitMessage = void 0;
|
|
221
|
-
}
|
|
222
|
-
function isJsonOutputMode() {
|
|
223
|
-
return _jsonOutputMode;
|
|
224
|
-
}
|
|
225
|
-
function addPackageUpdate(packageName, newVersion, filePath) {
|
|
226
|
-
if (!_jsonOutputMode) return;
|
|
227
|
-
_jsonData.updates.push({
|
|
228
|
-
packageName,
|
|
229
|
-
newVersion,
|
|
230
|
-
filePath
|
|
231
|
-
});
|
|
232
|
-
}
|
|
233
|
-
function addChangelogData(data) {
|
|
234
|
-
if (!_jsonOutputMode) return;
|
|
235
|
-
_jsonData.changelogs.push(data);
|
|
236
|
-
}
|
|
237
|
-
function addTag(tag) {
|
|
238
|
-
if (!_jsonOutputMode) return;
|
|
239
|
-
_jsonData.tags.push(tag);
|
|
240
|
-
}
|
|
241
|
-
function setCommitMessage(message) {
|
|
242
|
-
if (!_jsonOutputMode) return;
|
|
243
|
-
_jsonData.commitMessage = message;
|
|
244
|
-
}
|
|
245
|
-
function printJsonOutput() {
|
|
246
|
-
if (_jsonOutputMode) {
|
|
247
|
-
console.log(JSON.stringify(_jsonData, null, 2));
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
// src/utils/logging.ts
|
|
252
|
-
function log(message, level = "info") {
|
|
253
|
-
const showDebug = process.env.DEBUG === "true" || process.env.DEBUG === "1";
|
|
254
|
-
if (level === "debug" && !showDebug) {
|
|
255
|
-
return;
|
|
256
|
-
}
|
|
257
|
-
let chalkFn;
|
|
258
|
-
switch (level) {
|
|
259
|
-
case "success":
|
|
260
|
-
chalkFn = import_chalk.default.green;
|
|
261
|
-
break;
|
|
262
|
-
case "warning":
|
|
263
|
-
chalkFn = import_chalk.default.yellow;
|
|
264
|
-
break;
|
|
265
|
-
case "error":
|
|
266
|
-
chalkFn = import_chalk.default.red;
|
|
267
|
-
break;
|
|
268
|
-
case "debug":
|
|
269
|
-
chalkFn = import_chalk.default.gray;
|
|
270
|
-
break;
|
|
271
|
-
default:
|
|
272
|
-
chalkFn = import_chalk.default.blue;
|
|
273
|
-
}
|
|
274
|
-
const formattedMessage = level === "debug" ? `[DEBUG] ${message}` : message;
|
|
275
|
-
if (isJsonOutputMode()) {
|
|
276
|
-
console.error(chalkFn(formattedMessage));
|
|
277
|
-
return;
|
|
278
|
-
}
|
|
279
|
-
if (level === "error") {
|
|
280
|
-
console.error(chalkFn(formattedMessage));
|
|
281
|
-
} else {
|
|
282
|
-
console.log(chalkFn(formattedMessage));
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
// src/utils/packageFiltering.ts
|
|
287
|
-
var import_node_path = __toESM(require("path"), 1);
|
|
288
|
-
var import_micromatch = __toESM(require("micromatch"), 1);
|
|
289
|
-
function filterPackagesByConfig(packages, configTargets, workspaceRoot) {
|
|
290
|
-
if (configTargets.length === 0) {
|
|
291
|
-
log("No config targets specified, returning all packages", "debug");
|
|
292
|
-
return packages;
|
|
293
|
-
}
|
|
294
|
-
const matchedPackages = /* @__PURE__ */ new Set();
|
|
295
|
-
for (const target of configTargets) {
|
|
296
|
-
const dirMatches = filterByDirectoryPattern(packages, target, workspaceRoot);
|
|
297
|
-
const nameMatches = filterByPackageNamePattern(packages, target);
|
|
298
|
-
for (const pkg of dirMatches) {
|
|
299
|
-
matchedPackages.add(pkg);
|
|
300
|
-
}
|
|
301
|
-
for (const pkg of nameMatches) {
|
|
302
|
-
matchedPackages.add(pkg);
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
return Array.from(matchedPackages);
|
|
306
|
-
}
|
|
307
|
-
function filterByDirectoryPattern(packages, pattern, workspaceRoot) {
|
|
308
|
-
if (pattern === "./" || pattern === ".") {
|
|
309
|
-
return packages.filter((pkg) => pkg.dir === workspaceRoot);
|
|
310
|
-
}
|
|
311
|
-
const normalizedPattern = pattern.replace(/\\/g, "/");
|
|
312
|
-
return packages.filter((pkg) => {
|
|
313
|
-
const relativePath = import_node_path.default.relative(workspaceRoot, pkg.dir);
|
|
314
|
-
const normalizedRelativePath = relativePath.replace(/\\/g, "/");
|
|
315
|
-
if (normalizedPattern === normalizedRelativePath) {
|
|
316
|
-
return true;
|
|
317
|
-
}
|
|
318
|
-
try {
|
|
319
|
-
return import_micromatch.default.isMatch(normalizedRelativePath, normalizedPattern, {
|
|
320
|
-
dot: true,
|
|
321
|
-
noglobstar: false,
|
|
322
|
-
bash: true
|
|
323
|
-
});
|
|
324
|
-
} catch (error) {
|
|
325
|
-
log(
|
|
326
|
-
`Invalid directory pattern "${pattern}": ${error instanceof Error ? error.message : String(error)}`,
|
|
327
|
-
"warning"
|
|
328
|
-
);
|
|
329
|
-
return false;
|
|
330
|
-
}
|
|
331
|
-
});
|
|
332
|
-
}
|
|
333
|
-
function filterByPackageNamePattern(packages, pattern) {
|
|
334
|
-
return packages.filter((pkg) => {
|
|
335
|
-
if (!pkg.packageJson?.name || typeof pkg.packageJson.name !== "string") {
|
|
336
|
-
return false;
|
|
337
|
-
}
|
|
338
|
-
return matchesPackageNamePattern(pkg.packageJson.name, pattern);
|
|
339
|
-
});
|
|
340
|
-
}
|
|
341
|
-
function matchesPackageNamePattern(packageName, pattern) {
|
|
342
|
-
if (packageName === pattern) {
|
|
343
|
-
return true;
|
|
344
|
-
}
|
|
345
|
-
if (pattern.startsWith("@") && pattern.endsWith("/*") && !pattern.includes("**")) {
|
|
346
|
-
const scope = pattern.slice(0, -2);
|
|
347
|
-
return packageName.startsWith(`${scope}/`);
|
|
348
|
-
}
|
|
349
|
-
try {
|
|
350
|
-
return import_micromatch.default.isMatch(packageName, pattern, {
|
|
351
|
-
dot: true,
|
|
352
|
-
contains: false,
|
|
353
|
-
noglobstar: false,
|
|
354
|
-
bash: true
|
|
355
|
-
});
|
|
356
|
-
} catch (error) {
|
|
357
|
-
log(
|
|
358
|
-
`Invalid package name pattern "${pattern}": ${error instanceof Error ? error.message : String(error)}`,
|
|
359
|
-
"warning"
|
|
360
|
-
);
|
|
361
|
-
return false;
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
// src/core/versionStrategies.ts
|
|
366
|
-
var import_node_fs6 = __toESM(require("fs"), 1);
|
|
367
|
-
var path6 = __toESM(require("path"), 1);
|
|
368
|
-
|
|
369
|
-
// src/changelog/commitParser.ts
|
|
370
|
-
init_commandExecutor();
|
|
371
|
-
var CONVENTIONAL_COMMIT_REGEX = /^(\w+)(?:\(([^)]+)\))?(!)?: (.+)(?:\n\n([\s\S]*))?/;
|
|
372
|
-
var BREAKING_CHANGE_REGEX = /BREAKING CHANGE: ([\s\S]+?)(?:\n\n|$)/;
|
|
373
|
-
function extractAllChangelogEntriesWithHash(projectDir, revisionRange) {
|
|
374
|
-
try {
|
|
375
|
-
const args = ["log", revisionRange, "--pretty=format:%H|||%B---COMMIT_DELIMITER---", "--no-merges"];
|
|
376
|
-
const output = execSync("git", args, { cwd: projectDir, encoding: "utf8" }).toString();
|
|
377
|
-
const commits = output.split("---COMMIT_DELIMITER---").filter((commit) => commit.trim() !== "");
|
|
378
|
-
return commits.map((commit) => {
|
|
379
|
-
const [hash, ...messageParts] = commit.split("|||");
|
|
380
|
-
const message = messageParts.join("|||").trim();
|
|
381
|
-
const entry = parseCommitMessage(message);
|
|
382
|
-
if (entry && hash) {
|
|
383
|
-
return { hash: hash.trim(), entry };
|
|
384
|
-
}
|
|
385
|
-
return null;
|
|
386
|
-
}).filter((item) => item !== null);
|
|
387
|
-
} catch (error) {
|
|
388
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
389
|
-
log(`Error extracting all commits with hash: ${errorMessage}`, "error");
|
|
390
|
-
return [];
|
|
391
|
-
}
|
|
392
|
-
}
|
|
393
|
-
function commitTouchesAnyPackage(projectDir, commitHash, packageDirs, sharedPackageDirs = []) {
|
|
394
|
-
try {
|
|
395
|
-
const output = execSync("git", ["diff-tree", "--no-commit-id", "--name-only", "-r", commitHash], {
|
|
396
|
-
cwd: projectDir,
|
|
397
|
-
encoding: "utf8"
|
|
398
|
-
}).toString().trim();
|
|
399
|
-
if (!output) {
|
|
400
|
-
return false;
|
|
401
|
-
}
|
|
402
|
-
const changedFiles = output.split("\n");
|
|
403
|
-
return changedFiles.some((file) => {
|
|
404
|
-
return packageDirs.some((pkgDir) => {
|
|
405
|
-
if (sharedPackageDirs.some((sharedDir) => pkgDir.includes(sharedDir))) {
|
|
406
|
-
return false;
|
|
407
|
-
}
|
|
408
|
-
const normalizedFile = file.replace(/\\/g, "/");
|
|
409
|
-
const normalizedPkgDir = pkgDir.replace(/\\/g, "/").replace(/^\.\//, "");
|
|
410
|
-
return normalizedFile.startsWith(normalizedPkgDir);
|
|
411
|
-
});
|
|
412
|
-
});
|
|
413
|
-
} catch (error) {
|
|
414
|
-
log(
|
|
415
|
-
`Error checking if commit ${commitHash} touches packages: ${error instanceof Error ? error.message : String(error)}`,
|
|
416
|
-
"debug"
|
|
417
|
-
);
|
|
418
|
-
return false;
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
|
-
function extractRepoLevelChangelogEntries(projectDir, revisionRange, packageDirs, sharedPackageDirs = []) {
|
|
422
|
-
try {
|
|
423
|
-
const allCommits = extractAllChangelogEntriesWithHash(projectDir, revisionRange);
|
|
424
|
-
const repoLevelCommits = allCommits.filter((commit) => {
|
|
425
|
-
const touchesPackage = commitTouchesAnyPackage(projectDir, commit.hash, packageDirs, sharedPackageDirs);
|
|
426
|
-
return !touchesPackage;
|
|
427
|
-
});
|
|
428
|
-
if (repoLevelCommits.length > 0) {
|
|
429
|
-
log(
|
|
430
|
-
`Found ${repoLevelCommits.length} repo-level commit(s) (including shared packages: ${sharedPackageDirs.join(", ")})`,
|
|
431
|
-
"debug"
|
|
432
|
-
);
|
|
433
|
-
}
|
|
434
|
-
return repoLevelCommits.map((c) => c.entry);
|
|
435
|
-
} catch (error) {
|
|
436
|
-
log(`Error extracting repo-level commits: ${error instanceof Error ? error.message : String(error)}`, "warning");
|
|
437
|
-
return [];
|
|
438
|
-
}
|
|
439
|
-
}
|
|
440
|
-
function extractChangelogEntriesFromCommits(projectDir, revisionRange) {
|
|
441
|
-
return extractCommitsFromGitLog(projectDir, revisionRange, true);
|
|
442
|
-
}
|
|
443
|
-
function extractCommitsFromGitLog(projectDir, revisionRange, filterToPath) {
|
|
444
|
-
try {
|
|
445
|
-
const args = ["log", revisionRange, "--pretty=format:%B---COMMIT_DELIMITER---", "--no-merges"];
|
|
446
|
-
if (filterToPath) {
|
|
447
|
-
args.push("--", ".");
|
|
448
|
-
}
|
|
449
|
-
const output = execSync("git", args, { cwd: projectDir, encoding: "utf8" }).toString();
|
|
450
|
-
const commits = output.split("---COMMIT_DELIMITER---").filter((commit) => commit.trim() !== "");
|
|
451
|
-
return commits.map((commit) => parseCommitMessage(commit)).filter((entry) => entry !== null);
|
|
452
|
-
} catch (error) {
|
|
453
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
454
|
-
if (errorMessage.includes("ambiguous argument") && errorMessage.includes("unknown revision")) {
|
|
455
|
-
const tagName = revisionRange.split("..")[0] || revisionRange;
|
|
456
|
-
if (tagName.startsWith("v") && !tagName.includes("@")) {
|
|
457
|
-
log(
|
|
458
|
-
`Error: Tag "${tagName}" not found. If you're using package-specific tags (like "package-name@v1.0.0"), you may need to configure "tagTemplate" in your version.config.json to use: \${packageName}@\${prefix}\${version}`,
|
|
459
|
-
"error"
|
|
460
|
-
);
|
|
461
|
-
} else {
|
|
462
|
-
log(
|
|
463
|
-
`Error: Tag or revision "${tagName}" not found in the repository. Please check if this tag exists or if you need to fetch it from the remote.`,
|
|
464
|
-
"error"
|
|
465
|
-
);
|
|
466
|
-
}
|
|
467
|
-
} else {
|
|
468
|
-
log(`Error extracting commits: ${errorMessage}`, "error");
|
|
469
|
-
}
|
|
470
|
-
return [];
|
|
471
|
-
}
|
|
472
|
-
}
|
|
473
|
-
function parseCommitMessage(message) {
|
|
474
|
-
const trimmedMessage = message.trim();
|
|
475
|
-
const match = trimmedMessage.match(CONVENTIONAL_COMMIT_REGEX);
|
|
476
|
-
if (match) {
|
|
477
|
-
const [, type, scope, breakingMark, subject, body = ""] = match;
|
|
478
|
-
const breakingFromMark = breakingMark === "!";
|
|
479
|
-
const breakingChangeMatch = body.match(BREAKING_CHANGE_REGEX);
|
|
480
|
-
const hasBreakingChange = breakingFromMark || breakingChangeMatch !== null;
|
|
481
|
-
const changelogType = mapCommitTypeToChangelogType(type);
|
|
482
|
-
if (!changelogType) {
|
|
483
|
-
return null;
|
|
484
|
-
}
|
|
485
|
-
const issueIds = extractIssueIds(body);
|
|
486
|
-
let description = subject;
|
|
487
|
-
if (hasBreakingChange) {
|
|
488
|
-
description = `**BREAKING** ${description}`;
|
|
489
|
-
}
|
|
490
|
-
return {
|
|
491
|
-
type: changelogType,
|
|
492
|
-
description,
|
|
493
|
-
scope: scope || void 0,
|
|
494
|
-
issueIds: issueIds.length > 0 ? issueIds : void 0,
|
|
495
|
-
originalType: type
|
|
496
|
-
// Store original type for custom formatting
|
|
497
|
-
};
|
|
498
|
-
}
|
|
499
|
-
if (!trimmedMessage.startsWith("Merge") && !trimmedMessage.match(/^v?\d+\.\d+\.\d+/)) {
|
|
500
|
-
const firstLine = trimmedMessage.split("\n")[0].trim();
|
|
501
|
-
return {
|
|
502
|
-
type: "changed",
|
|
503
|
-
description: firstLine
|
|
504
|
-
};
|
|
505
|
-
}
|
|
506
|
-
return null;
|
|
507
|
-
}
|
|
508
|
-
function mapCommitTypeToChangelogType(type) {
|
|
509
|
-
switch (type) {
|
|
510
|
-
case "feat":
|
|
511
|
-
return "added";
|
|
512
|
-
case "fix":
|
|
513
|
-
return "fixed";
|
|
514
|
-
case "docs":
|
|
515
|
-
case "style":
|
|
516
|
-
case "refactor":
|
|
517
|
-
case "perf":
|
|
518
|
-
case "build":
|
|
519
|
-
case "ci":
|
|
520
|
-
return "changed";
|
|
521
|
-
case "revert":
|
|
522
|
-
return "removed";
|
|
523
|
-
case "chore":
|
|
524
|
-
return "changed";
|
|
525
|
-
case "test":
|
|
526
|
-
return null;
|
|
527
|
-
default:
|
|
528
|
-
return "changed";
|
|
529
|
-
}
|
|
530
|
-
}
|
|
531
|
-
function extractIssueIds(body) {
|
|
532
|
-
const issueRegex = /(?:fix|fixes|close|closes|resolve|resolves)\s+#(\d+)/gi;
|
|
533
|
-
const issueIds = [];
|
|
534
|
-
let match = issueRegex.exec(body);
|
|
535
|
-
while (match !== null) {
|
|
536
|
-
issueIds.push(`#${match[1]}`);
|
|
537
|
-
match = issueRegex.exec(body);
|
|
538
|
-
}
|
|
539
|
-
return issueIds;
|
|
540
|
-
}
|
|
541
|
-
|
|
542
|
-
// src/core/versionStrategies.ts
|
|
543
|
-
init_baseError();
|
|
544
|
-
init_commandExecutor();
|
|
545
|
-
|
|
546
|
-
// src/git/tagsAndBranches.ts
|
|
547
|
-
var import_git_semver_tags = require("git-semver-tags");
|
|
548
|
-
var import_semver = __toESM(require("semver"), 1);
|
|
549
|
-
|
|
550
|
-
// src/utils/formatting.ts
|
|
551
|
-
function escapeRegExp(string) {
|
|
552
|
-
return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
553
|
-
}
|
|
554
|
-
function formatVersionPrefix(prefix) {
|
|
555
|
-
return prefix.endsWith("/") ? prefix.slice(0, -1) : prefix;
|
|
556
|
-
}
|
|
557
|
-
function formatTag(version, prefix, packageName, template, packageSpecificTags) {
|
|
558
|
-
if (template?.includes("${packageName}") && !packageName) {
|
|
559
|
-
log(
|
|
560
|
-
`Warning: Your tagTemplate contains \${packageName} but no package name is available.
|
|
561
|
-
This will result in an empty package name in the tag (e.g., "@v1.0.0" instead of "my-package@v1.0.0").
|
|
562
|
-
|
|
563
|
-
To fix this:
|
|
564
|
-
\u2022 If using sync mode: Set "packageSpecificTags": true in your config to enable package names in tags
|
|
565
|
-
\u2022 If you want global tags: Remove \${packageName} from your tagTemplate (e.g., use "\${prefix}\${version}")
|
|
566
|
-
\u2022 If using single/async mode: Ensure your package.json has a valid "name" field`,
|
|
567
|
-
"warning"
|
|
568
|
-
);
|
|
569
|
-
}
|
|
570
|
-
if (template) {
|
|
571
|
-
return template.replace(/\$\{version\}/g, version).replace(/\$\{prefix\}/g, prefix).replace(/\$\{packageName\}/g, packageName || "");
|
|
572
|
-
}
|
|
573
|
-
if (packageSpecificTags && packageName) {
|
|
574
|
-
return `${packageName}@${prefix}${version}`;
|
|
575
|
-
}
|
|
576
|
-
return `${prefix}${version}`;
|
|
577
|
-
}
|
|
578
|
-
function formatCommitMessage(template, version, packageName, additionalContext) {
|
|
579
|
-
if (template.includes("${packageName}") && !packageName) {
|
|
580
|
-
log(
|
|
581
|
-
`Warning: Your commitMessage template contains \${packageName} but no package name is available.
|
|
582
|
-
This will result in an empty package name in the commit message (e.g., "Release @v1.0.0").
|
|
583
|
-
|
|
584
|
-
To fix this:
|
|
585
|
-
\u2022 If using sync mode: Set "packageSpecificTags": true to enable package names in commits
|
|
586
|
-
\u2022 If you want generic commit messages: Remove \${packageName} from your commitMessage template
|
|
587
|
-
\u2022 If using single/async mode: Ensure your package.json has a valid "name" field`,
|
|
588
|
-
"warning"
|
|
589
|
-
);
|
|
590
|
-
}
|
|
591
|
-
let result = template.replace(/\$\{version\}/g, version).replace(/\$\{packageName\}/g, packageName || "");
|
|
592
|
-
if (additionalContext) {
|
|
593
|
-
for (const [key, value] of Object.entries(additionalContext)) {
|
|
594
|
-
const placeholder = `${key ? `\${${key}}` : ""}`;
|
|
595
|
-
result = result.replace(new RegExp(escapeRegExp(placeholder), "g"), value);
|
|
596
|
-
}
|
|
597
|
-
}
|
|
598
|
-
return result;
|
|
599
|
-
}
|
|
600
|
-
|
|
601
|
-
// src/git/tagsAndBranches.ts
|
|
602
|
-
init_commandExecutor();
|
|
603
|
-
function getCommitsLength(pkgRoot, sinceTag) {
|
|
604
|
-
try {
|
|
605
|
-
let amount;
|
|
606
|
-
if (sinceTag && sinceTag.trim() !== "") {
|
|
607
|
-
amount = execSync("git", ["rev-list", "--count", `${sinceTag}..HEAD`, pkgRoot]).toString().trim();
|
|
608
|
-
} else {
|
|
609
|
-
const latestTag = execSync("git", ["describe", "--tags", "--abbrev=0"]).toString().trim();
|
|
610
|
-
amount = execSync("git", ["rev-list", "--count", "HEAD", `^${latestTag}`, pkgRoot]).toString().trim();
|
|
611
|
-
}
|
|
612
|
-
return Number(amount);
|
|
613
|
-
} catch (error) {
|
|
614
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
615
|
-
log(`Failed to get number of commits since last tag: ${errorMessage}`, "error");
|
|
616
|
-
return 0;
|
|
617
|
-
}
|
|
618
|
-
}
|
|
619
|
-
async function getLatestTag(versionPrefix) {
|
|
620
|
-
try {
|
|
621
|
-
const tags = await (0, import_git_semver_tags.getSemverTags)({
|
|
622
|
-
tagPrefix: versionPrefix
|
|
623
|
-
});
|
|
624
|
-
if (tags.length === 0) {
|
|
625
|
-
return "";
|
|
626
|
-
}
|
|
627
|
-
const chronologicalLatest = tags[0];
|
|
628
|
-
const sortedTags = [...tags].sort((a, b) => {
|
|
629
|
-
const versionA = import_semver.default.clean(a) || "0.0.0";
|
|
630
|
-
const versionB = import_semver.default.clean(b) || "0.0.0";
|
|
631
|
-
return import_semver.default.rcompare(versionA, versionB);
|
|
632
|
-
});
|
|
633
|
-
const semanticLatest = sortedTags[0];
|
|
634
|
-
if (semanticLatest !== chronologicalLatest) {
|
|
635
|
-
log(
|
|
636
|
-
`Tag ordering differs: chronological latest is ${chronologicalLatest}, semantic latest is ${semanticLatest}`,
|
|
637
|
-
"debug"
|
|
638
|
-
);
|
|
639
|
-
log(`Using semantic latest (${semanticLatest}) to handle out-of-order tag creation`, "info");
|
|
640
|
-
}
|
|
641
|
-
return semanticLatest;
|
|
642
|
-
} catch (error) {
|
|
643
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
644
|
-
log(`Failed to get latest tag: ${errorMessage}`, "error");
|
|
645
|
-
if (error instanceof Error && error.message.includes("No names found")) {
|
|
646
|
-
log("No tags found in the repository.", "info");
|
|
647
|
-
}
|
|
648
|
-
return "";
|
|
649
|
-
}
|
|
650
|
-
}
|
|
651
|
-
async function lastMergeBranchName(branches, baseBranch) {
|
|
652
|
-
try {
|
|
653
|
-
const escapedBranches = branches.map((branch) => escapeRegExp(branch));
|
|
654
|
-
const branchesRegex = `${escapedBranches.join("/(.*)|")}/(.*)`;
|
|
655
|
-
const { stdout } = await execAsync("git", [
|
|
656
|
-
"for-each-ref",
|
|
657
|
-
"--sort=-committerdate",
|
|
658
|
-
"--format=%(refname:short)",
|
|
659
|
-
"refs/heads",
|
|
660
|
-
`--merged=${baseBranch}`
|
|
661
|
-
]);
|
|
662
|
-
const regex = new RegExp(branchesRegex, "i");
|
|
663
|
-
const matched = stdout.split("\n").map((l) => l.trim()).filter(Boolean).find((b) => regex.test(b));
|
|
664
|
-
return matched ?? null;
|
|
665
|
-
} catch (error) {
|
|
666
|
-
console.error("Error while getting the last branch name:", error instanceof Error ? error.message : String(error));
|
|
667
|
-
return null;
|
|
668
|
-
}
|
|
669
|
-
}
|
|
670
|
-
async function getLatestTagForPackage(packageName, versionPrefix, options) {
|
|
671
|
-
try {
|
|
672
|
-
const tagTemplate = options?.tagTemplate || `\${prefix}\${version}`;
|
|
673
|
-
const packageSpecificTags = options?.packageSpecificTags ?? false;
|
|
674
|
-
const escapedPackageName = escapeRegExp(packageName);
|
|
675
|
-
const escapedPrefix = versionPrefix ? escapeRegExp(versionPrefix) : "";
|
|
676
|
-
log(
|
|
677
|
-
`Looking for tags for package ${packageName} with prefix ${versionPrefix || "none"}, packageSpecificTags: ${packageSpecificTags}`,
|
|
678
|
-
"debug"
|
|
679
|
-
);
|
|
680
|
-
let allTags = [];
|
|
681
|
-
try {
|
|
682
|
-
const { execSync: execSync2 } = await Promise.resolve().then(() => (init_commandExecutor(), commandExecutor_exports));
|
|
683
|
-
const tagsOutput = execSync2("git", ["tag", "-l"], { cwd: process.cwd() });
|
|
684
|
-
allTags = tagsOutput.toString().trim().split("\n").filter((tag) => tag.length > 0);
|
|
685
|
-
} catch (err) {
|
|
686
|
-
log(`Error getting tags: ${err instanceof Error ? err.message : String(err)}`, "error");
|
|
687
|
-
}
|
|
688
|
-
log(`Retrieved ${allTags.length} tags`, "debug");
|
|
689
|
-
if (packageSpecificTags) {
|
|
690
|
-
const packageTagPattern = escapeRegExp(tagTemplate).replace(/\\\$\\\{packageName\\\}/g, `(?:${escapedPackageName})`).replace(/\\\$\\\{prefix\\\}/g, `(?:${escapedPrefix})`).replace(/\\\$\\\{version\\\}/g, "(?:[0-9]+\\.[0-9]+\\.[0-9]+(?:-[a-zA-Z0-9.-]+)?)");
|
|
691
|
-
log(`Using package tag pattern: ${packageTagPattern}`, "debug");
|
|
692
|
-
const packageTagRegex = new RegExp(`^${packageTagPattern}$`);
|
|
693
|
-
let packageTags = allTags.filter((tag) => packageTagRegex.test(tag));
|
|
694
|
-
log(`Found ${packageTags.length} matching tags for ${packageName}`, "debug");
|
|
695
|
-
if (packageTags.length > 0) {
|
|
696
|
-
const chronologicalFirst = packageTags[0];
|
|
697
|
-
void chronologicalFirst;
|
|
698
|
-
const sortedPackageTags2 = [...packageTags].sort((a, b) => {
|
|
699
|
-
let versionA = "";
|
|
700
|
-
let versionB = "";
|
|
701
|
-
if (a.includes("@")) {
|
|
702
|
-
const parts = a.split("@");
|
|
703
|
-
const afterAt = parts[parts.length - 1] || "";
|
|
704
|
-
versionA = afterAt.replace(new RegExp(`^${escapeRegExp(versionPrefix || "")}`), "");
|
|
705
|
-
} else {
|
|
706
|
-
versionA = a.replace(new RegExp(`^${escapeRegExp(packageName)}`), "").replace(new RegExp(`^${escapeRegExp(versionPrefix || "")}`), "");
|
|
707
|
-
}
|
|
708
|
-
if (b.includes("@")) {
|
|
709
|
-
const parts = b.split("@");
|
|
710
|
-
const afterAtB = parts[parts.length - 1] || "";
|
|
711
|
-
versionB = afterAtB.replace(new RegExp(`^${escapeRegExp(versionPrefix || "")}`), "");
|
|
712
|
-
} else {
|
|
713
|
-
versionB = b.replace(new RegExp(`^${escapeRegExp(packageName)}`), "").replace(new RegExp(`^${escapeRegExp(versionPrefix || "")}`), "");
|
|
714
|
-
}
|
|
715
|
-
const cleanVersionA = import_semver.default.clean(versionA) || "0.0.0";
|
|
716
|
-
const cleanVersionB = import_semver.default.clean(versionB) || "0.0.0";
|
|
717
|
-
return import_semver.default.rcompare(cleanVersionA, cleanVersionB);
|
|
718
|
-
});
|
|
719
|
-
log(`Found ${packageTags.length} package tags using configured pattern`, "debug");
|
|
720
|
-
log(`Using semantically latest tag: ${sortedPackageTags2[0]}`, "debug");
|
|
721
|
-
return sortedPackageTags2[0];
|
|
722
|
-
}
|
|
723
|
-
if (versionPrefix) {
|
|
724
|
-
const pattern1 = new RegExp(`^${escapedPackageName}@${escapeRegExp(versionPrefix)}`);
|
|
725
|
-
packageTags = allTags.filter((tag) => pattern1.test(tag));
|
|
726
|
-
if (packageTags.length > 0) {
|
|
727
|
-
const sortedPackageTags2 = [...packageTags].sort((a, b) => {
|
|
728
|
-
const aParts = a.split("@");
|
|
729
|
-
const afterAt = aParts[aParts.length - 1] || "";
|
|
730
|
-
const versionA = afterAt.replace(new RegExp(`^${escapeRegExp(versionPrefix || "")}`), "");
|
|
731
|
-
const bParts = b.split("@");
|
|
732
|
-
const afterAtB = bParts[bParts.length - 1] || "";
|
|
733
|
-
const versionB = afterAtB.replace(new RegExp(`^${escapeRegExp(versionPrefix || "")}`), "");
|
|
734
|
-
const cleanVersionA = import_semver.default.clean(versionA) || "0.0.0";
|
|
735
|
-
const cleanVersionB = import_semver.default.clean(versionB) || "0.0.0";
|
|
736
|
-
return import_semver.default.rcompare(cleanVersionA, cleanVersionB);
|
|
737
|
-
});
|
|
738
|
-
log(`Found ${packageTags.length} package tags using pattern: packageName@${versionPrefix}...`, "debug");
|
|
739
|
-
log(`Using semantically latest tag: ${sortedPackageTags2[0]}`, "debug");
|
|
740
|
-
return sortedPackageTags2[0];
|
|
741
|
-
}
|
|
742
|
-
}
|
|
743
|
-
if (versionPrefix) {
|
|
744
|
-
const pattern2 = new RegExp(`^${escapeRegExp(versionPrefix)}${escapedPackageName}@`);
|
|
745
|
-
packageTags = allTags.filter((tag) => pattern2.test(tag));
|
|
746
|
-
if (packageTags.length > 0) {
|
|
747
|
-
const sortedPackageTags2 = [...packageTags].sort((a, b) => {
|
|
748
|
-
const aParts = a.split("@");
|
|
749
|
-
const versionA = import_semver.default.clean(aParts[aParts.length - 1] || "") || "0.0.0";
|
|
750
|
-
const bParts = b.split("@");
|
|
751
|
-
const versionB = import_semver.default.clean(bParts[bParts.length - 1] || "") || "0.0.0";
|
|
752
|
-
return import_semver.default.rcompare(versionA, versionB);
|
|
753
|
-
});
|
|
754
|
-
log(`Found ${packageTags.length} package tags using pattern: ${versionPrefix}packageName@...`, "debug");
|
|
755
|
-
log(`Using semantically latest tag: ${sortedPackageTags2[0]}`, "debug");
|
|
756
|
-
return sortedPackageTags2[0];
|
|
757
|
-
}
|
|
758
|
-
}
|
|
759
|
-
const pattern3 = new RegExp(`^${escapedPackageName}@`);
|
|
760
|
-
packageTags = allTags.filter((tag) => pattern3.test(tag));
|
|
761
|
-
if (packageTags.length === 0) {
|
|
762
|
-
log("No matching tags found for pattern: packageName@version", "debug");
|
|
763
|
-
if (allTags.length > 0) {
|
|
764
|
-
log(`Available tags: ${allTags.join(", ")}`, "debug");
|
|
765
|
-
} else {
|
|
766
|
-
log("No tags available in the repository", "debug");
|
|
767
|
-
}
|
|
768
|
-
return "";
|
|
769
|
-
}
|
|
770
|
-
const sortedPackageTags = [...packageTags].sort((a, b) => {
|
|
771
|
-
const aParts = a.split("@");
|
|
772
|
-
const versionA = import_semver.default.clean(aParts[aParts.length - 1] || "") || "0.0.0";
|
|
773
|
-
const bParts = b.split("@");
|
|
774
|
-
const versionB = import_semver.default.clean(bParts[bParts.length - 1] || "") || "0.0.0";
|
|
775
|
-
return import_semver.default.rcompare(versionA, versionB);
|
|
776
|
-
});
|
|
777
|
-
log(`Found ${packageTags.length} package tags for ${packageName}`, "debug");
|
|
778
|
-
log(`Using semantically latest tag: ${sortedPackageTags[0]}`, "debug");
|
|
779
|
-
return sortedPackageTags[0];
|
|
780
|
-
}
|
|
781
|
-
log(`Package-specific tags disabled for ${packageName}, falling back to global tags`, "debug");
|
|
782
|
-
return "";
|
|
783
|
-
} catch (error) {
|
|
784
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
785
|
-
log(`Failed to get latest tag for package ${packageName}: ${errorMessage}`, "error");
|
|
786
|
-
if (error instanceof Error && error.message.includes("No names found")) {
|
|
787
|
-
log(`No tags found for package ${packageName}.`, "info");
|
|
788
|
-
}
|
|
789
|
-
return "";
|
|
790
|
-
}
|
|
791
|
-
}
|
|
792
|
-
|
|
793
|
-
// src/package/packageManagement.ts
|
|
794
|
-
var import_node_fs2 = __toESM(require("fs"), 1);
|
|
795
|
-
var import_node_path3 = __toESM(require("path"), 1);
|
|
796
|
-
|
|
797
|
-
// src/cargo/cargoHandler.ts
|
|
798
|
-
var import_node_fs = __toESM(require("fs"), 1);
|
|
799
|
-
var import_node_path2 = __toESM(require("path"), 1);
|
|
800
|
-
var import_config2 = require("@releasekit/config");
|
|
801
|
-
var TOML = __toESM(require("smol-toml"), 1);
|
|
802
|
-
function getCargoInfo(cargoPath) {
|
|
803
|
-
if (!import_node_fs.default.existsSync(cargoPath)) {
|
|
804
|
-
log(`Cargo.toml file not found at: ${cargoPath}`, "error");
|
|
805
|
-
throw new Error(`Cargo.toml file not found at: ${cargoPath}`);
|
|
806
|
-
}
|
|
807
|
-
try {
|
|
808
|
-
const cargo = (0, import_config2.parseCargoToml)(cargoPath);
|
|
809
|
-
if (!cargo.package?.name) {
|
|
810
|
-
log(`Package name not found in: ${cargoPath}`, "error");
|
|
811
|
-
throw new Error(`Package name not found in: ${cargoPath}`);
|
|
812
|
-
}
|
|
813
|
-
return {
|
|
814
|
-
name: cargo.package.name,
|
|
815
|
-
version: cargo.package.version || "0.0.0",
|
|
816
|
-
path: cargoPath,
|
|
817
|
-
dir: import_node_path2.default.dirname(cargoPath),
|
|
818
|
-
content: cargo
|
|
819
|
-
};
|
|
820
|
-
} catch (error) {
|
|
821
|
-
log(`Error reading Cargo.toml: ${cargoPath}`, "error");
|
|
822
|
-
if (error instanceof Error) {
|
|
823
|
-
log(error.message, "error");
|
|
824
|
-
throw error;
|
|
825
|
-
}
|
|
826
|
-
throw new Error(`Failed to process Cargo.toml at ${cargoPath}`);
|
|
827
|
-
}
|
|
828
|
-
}
|
|
829
|
-
function updateCargoVersion(cargoPath, version, dryRun = false) {
|
|
830
|
-
try {
|
|
831
|
-
const cargo = (0, import_config2.parseCargoToml)(cargoPath);
|
|
832
|
-
const packageName = cargo.package?.name;
|
|
833
|
-
if (!packageName) {
|
|
834
|
-
throw new Error(`No package name found in ${cargoPath}`);
|
|
835
|
-
}
|
|
836
|
-
if (!dryRun) {
|
|
837
|
-
if (!cargo.package) {
|
|
838
|
-
cargo.package = { name: packageName, version };
|
|
839
|
-
} else {
|
|
840
|
-
cargo.package.version = version;
|
|
841
|
-
}
|
|
842
|
-
const updatedContent = TOML.stringify(cargo);
|
|
843
|
-
import_node_fs.default.writeFileSync(cargoPath, updatedContent);
|
|
844
|
-
}
|
|
845
|
-
addPackageUpdate(packageName, version, cargoPath);
|
|
846
|
-
log(`${dryRun ? "[DRY RUN] Would update" : "Updated"} Cargo.toml at ${cargoPath} to version ${version}`, "success");
|
|
847
|
-
} catch (error) {
|
|
848
|
-
log(`Failed to update Cargo.toml at ${cargoPath}`, "error");
|
|
849
|
-
if (error instanceof Error) {
|
|
850
|
-
log(error.message, "error");
|
|
851
|
-
}
|
|
852
|
-
throw error;
|
|
853
|
-
}
|
|
854
|
-
}
|
|
855
|
-
|
|
856
|
-
// src/package/packageManagement.ts
|
|
857
|
-
function updatePackageVersion(packagePath, version, dryRun = false) {
|
|
858
|
-
if ((0, import_config2.isCargoToml)(packagePath)) {
|
|
859
|
-
updateCargoVersion(packagePath, version, dryRun);
|
|
860
|
-
return;
|
|
861
|
-
}
|
|
862
|
-
try {
|
|
863
|
-
const packageContent = import_node_fs2.default.readFileSync(packagePath, "utf8");
|
|
864
|
-
const packageJson = JSON.parse(packageContent);
|
|
865
|
-
const packageName = packageJson.name;
|
|
866
|
-
if (!dryRun) {
|
|
867
|
-
packageJson.version = version;
|
|
868
|
-
import_node_fs2.default.writeFileSync(packagePath, `${JSON.stringify(packageJson, null, 2)}
|
|
869
|
-
`);
|
|
870
|
-
}
|
|
871
|
-
addPackageUpdate(packageName, version, packagePath);
|
|
872
|
-
log(
|
|
873
|
-
`${dryRun ? "[DRY RUN] Would update" : "Updated"} package.json at ${packagePath} to version ${version}`,
|
|
874
|
-
"success"
|
|
875
|
-
);
|
|
876
|
-
} catch (error) {
|
|
877
|
-
log(`Failed to update package.json at ${packagePath}`, "error");
|
|
878
|
-
if (error instanceof Error) {
|
|
879
|
-
log(error.message, "error");
|
|
880
|
-
}
|
|
881
|
-
throw error;
|
|
882
|
-
}
|
|
883
|
-
}
|
|
884
|
-
|
|
885
|
-
// src/package/packageProcessor.ts
|
|
886
|
-
var fs5 = __toESM(require("fs"), 1);
|
|
887
|
-
var import_node_path6 = __toESM(require("path"), 1);
|
|
888
|
-
|
|
889
|
-
// src/core/versionCalculator.ts
|
|
890
|
-
var import_node_process = require("process");
|
|
891
|
-
var import_conventional_recommended_bump = require("conventional-recommended-bump");
|
|
892
|
-
var import_semver3 = __toESM(require("semver"), 1);
|
|
893
|
-
|
|
894
|
-
// src/git/repository.ts
|
|
895
|
-
var import_node_fs3 = require("fs");
|
|
896
|
-
var import_node_path4 = require("path");
|
|
897
|
-
init_commandExecutor();
|
|
898
|
-
function getCurrentBranch() {
|
|
899
|
-
const result = execSync("git", ["rev-parse", "--abbrev-ref", "HEAD"]);
|
|
900
|
-
return result.toString().trim();
|
|
901
|
-
}
|
|
902
|
-
|
|
903
|
-
// src/utils/manifestHelpers.ts
|
|
904
|
-
var import_node_fs4 = __toESM(require("fs"), 1);
|
|
905
|
-
var import_node_path5 = __toESM(require("path"), 1);
|
|
906
|
-
function getVersionFromManifests(packageDir) {
|
|
907
|
-
const packageJsonPath = import_node_path5.default.join(packageDir, "package.json");
|
|
908
|
-
const cargoTomlPath = import_node_path5.default.join(packageDir, "Cargo.toml");
|
|
909
|
-
if (import_node_fs4.default.existsSync(packageJsonPath)) {
|
|
910
|
-
try {
|
|
911
|
-
const packageJson = JSON.parse(import_node_fs4.default.readFileSync(packageJsonPath, "utf-8"));
|
|
912
|
-
if (packageJson.version) {
|
|
913
|
-
log(`Found version ${packageJson.version} in package.json`, "debug");
|
|
914
|
-
return {
|
|
915
|
-
version: packageJson.version,
|
|
916
|
-
manifestFound: true,
|
|
917
|
-
manifestPath: packageJsonPath,
|
|
918
|
-
manifestType: "package.json"
|
|
919
|
-
};
|
|
920
|
-
}
|
|
921
|
-
log("No version field found in package.json", "debug");
|
|
922
|
-
} catch (packageJsonError) {
|
|
923
|
-
const errMsg = packageJsonError instanceof Error ? packageJsonError.message : String(packageJsonError);
|
|
924
|
-
log(`Error reading package.json: ${errMsg}`, "warning");
|
|
925
|
-
}
|
|
926
|
-
}
|
|
927
|
-
if (import_node_fs4.default.existsSync(cargoTomlPath)) {
|
|
928
|
-
try {
|
|
929
|
-
const cargoInfo = getCargoInfo(cargoTomlPath);
|
|
930
|
-
if (cargoInfo.version) {
|
|
931
|
-
log(`Found version ${cargoInfo.version} in Cargo.toml`, "debug");
|
|
932
|
-
return {
|
|
933
|
-
version: cargoInfo.version,
|
|
934
|
-
manifestFound: true,
|
|
935
|
-
manifestPath: cargoTomlPath,
|
|
936
|
-
manifestType: "Cargo.toml"
|
|
937
|
-
};
|
|
938
|
-
}
|
|
939
|
-
log("No version field found in Cargo.toml", "debug");
|
|
940
|
-
} catch (cargoTomlError) {
|
|
941
|
-
const errMsg = cargoTomlError instanceof Error ? cargoTomlError.message : String(cargoTomlError);
|
|
942
|
-
log(`Error reading Cargo.toml: ${errMsg}`, "warning");
|
|
943
|
-
}
|
|
944
|
-
}
|
|
945
|
-
return {
|
|
946
|
-
version: null,
|
|
947
|
-
manifestFound: false,
|
|
948
|
-
manifestPath: "",
|
|
949
|
-
manifestType: null
|
|
950
|
-
};
|
|
951
|
-
}
|
|
952
|
-
|
|
953
|
-
// src/utils/versionUtils.ts
|
|
954
|
-
var import_node_fs5 = __toESM(require("fs"), 1);
|
|
955
|
-
var import_config3 = require("@releasekit/config");
|
|
956
|
-
var import_semver2 = __toESM(require("semver"), 1);
|
|
957
|
-
|
|
958
|
-
// src/git/tagVerification.ts
|
|
959
|
-
init_commandExecutor();
|
|
960
|
-
function verifyTag(tagName, cwd3) {
|
|
961
|
-
if (!tagName || tagName.trim() === "") {
|
|
962
|
-
return { exists: false, reachable: false, error: "Empty tag name" };
|
|
963
|
-
}
|
|
964
|
-
try {
|
|
965
|
-
execSync("git", ["rev-parse", "--verify", tagName], {
|
|
966
|
-
cwd: cwd3,
|
|
967
|
-
stdio: "ignore"
|
|
968
|
-
});
|
|
969
|
-
return { exists: true, reachable: true };
|
|
970
|
-
} catch (error) {
|
|
971
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
972
|
-
if (errorMessage.includes("unknown revision") || errorMessage.includes("bad revision") || errorMessage.includes("No such ref")) {
|
|
973
|
-
return {
|
|
974
|
-
exists: false,
|
|
975
|
-
reachable: false,
|
|
976
|
-
error: `Tag '${tagName}' not found in repository`
|
|
977
|
-
};
|
|
978
|
-
}
|
|
979
|
-
return {
|
|
980
|
-
exists: false,
|
|
981
|
-
reachable: false,
|
|
982
|
-
error: `Git error: ${errorMessage}`
|
|
983
|
-
};
|
|
984
|
-
}
|
|
985
|
-
}
|
|
986
|
-
|
|
987
|
-
// src/utils/versionUtils.ts
|
|
988
|
-
var STANDARD_BUMP_TYPES = ["major", "minor", "patch"];
|
|
989
|
-
function normalizePrereleaseIdentifier(prereleaseIdentifier, config) {
|
|
990
|
-
if (prereleaseIdentifier === true) {
|
|
991
|
-
return config?.prereleaseIdentifier || "next";
|
|
992
|
-
}
|
|
993
|
-
if (typeof prereleaseIdentifier === "string") {
|
|
994
|
-
return prereleaseIdentifier;
|
|
995
|
-
}
|
|
996
|
-
return void 0;
|
|
997
|
-
}
|
|
998
|
-
function bumpVersion(currentVersion, bumpType, prereleaseIdentifier) {
|
|
999
|
-
if (prereleaseIdentifier && STANDARD_BUMP_TYPES.includes(bumpType) && !import_semver2.default.prerelease(currentVersion)) {
|
|
1000
|
-
const preBumpType = `pre${bumpType}`;
|
|
1001
|
-
log(`Creating prerelease version with identifier '${prereleaseIdentifier}' using ${preBumpType}`, "debug");
|
|
1002
|
-
return import_semver2.default.inc(currentVersion, preBumpType, prereleaseIdentifier) || "";
|
|
1003
|
-
}
|
|
1004
|
-
if (import_semver2.default.prerelease(currentVersion) && STANDARD_BUMP_TYPES.includes(bumpType)) {
|
|
1005
|
-
const parsed = import_semver2.default.parse(currentVersion);
|
|
1006
|
-
if (!parsed) {
|
|
1007
|
-
return import_semver2.default.inc(currentVersion, bumpType) || "";
|
|
1008
|
-
}
|
|
1009
|
-
if (bumpType === "major" && parsed.minor === 0 && parsed.patch === 0 || bumpType === "minor" && parsed.patch === 0 || bumpType === "patch") {
|
|
1010
|
-
log(`Cleaning prerelease identifier from ${currentVersion} for ${bumpType} bump`, "debug");
|
|
1011
|
-
return `${parsed.major}.${parsed.minor}.${parsed.patch}`;
|
|
1012
|
-
}
|
|
1013
|
-
log(`Standard increment for ${currentVersion} with ${bumpType} bump`, "debug");
|
|
1014
|
-
return import_semver2.default.inc(currentVersion, bumpType) || "";
|
|
1015
|
-
}
|
|
1016
|
-
if (prereleaseIdentifier) {
|
|
1017
|
-
return import_semver2.default.inc(currentVersion, bumpType, prereleaseIdentifier) || "";
|
|
1018
|
-
}
|
|
1019
|
-
return import_semver2.default.inc(currentVersion, bumpType) || "";
|
|
1020
|
-
}
|
|
1021
|
-
function detectVersionMismatch(tagVersion, packageVersion) {
|
|
1022
|
-
const tagIsPrerelease = import_semver2.default.prerelease(tagVersion) !== null;
|
|
1023
|
-
const packageIsPrerelease = import_semver2.default.prerelease(packageVersion) !== null;
|
|
1024
|
-
const tagParsed = import_semver2.default.parse(tagVersion);
|
|
1025
|
-
const packageParsed = import_semver2.default.parse(packageVersion);
|
|
1026
|
-
if (!tagParsed || !packageParsed) {
|
|
1027
|
-
return { isMismatch: false, severity: "minor", message: "" };
|
|
1028
|
-
}
|
|
1029
|
-
if (!tagIsPrerelease && packageIsPrerelease && tagParsed.major === packageParsed.major) {
|
|
1030
|
-
return {
|
|
1031
|
-
isMismatch: true,
|
|
1032
|
-
severity: "major",
|
|
1033
|
-
message: `Git tag ${tagVersion} (stable) is ahead of package ${packageVersion} (prerelease). This may indicate a reverted release. Consider deleting tag ${tagVersion} or updating package.json.`
|
|
1034
|
-
};
|
|
1035
|
-
}
|
|
1036
|
-
const tagHigher = import_semver2.default.gt(tagVersion, packageVersion);
|
|
1037
|
-
if (tagHigher) {
|
|
1038
|
-
const diff = import_semver2.default.diff(packageVersion, tagVersion);
|
|
1039
|
-
if (diff === "major" || diff === "minor") {
|
|
1040
|
-
return {
|
|
1041
|
-
isMismatch: true,
|
|
1042
|
-
severity: "major",
|
|
1043
|
-
message: `Git tag ${tagVersion} is significantly ahead (${diff}) of package ${packageVersion}. This may cause unexpected version bumps.`
|
|
1044
|
-
};
|
|
1045
|
-
}
|
|
1046
|
-
}
|
|
1047
|
-
if (tagIsPrerelease && !packageIsPrerelease) {
|
|
1048
|
-
return {
|
|
1049
|
-
isMismatch: true,
|
|
1050
|
-
severity: "minor",
|
|
1051
|
-
message: `Git tag ${tagVersion} is a prerelease but package ${packageVersion} is stable. Consider aligning your versioning.`
|
|
1052
|
-
};
|
|
1053
|
-
}
|
|
1054
|
-
return { isMismatch: false, severity: "minor", message: "" };
|
|
1055
|
-
}
|
|
1056
|
-
var VersionMismatchError = class extends Error {
|
|
1057
|
-
constructor(message, severity) {
|
|
1058
|
-
super(message);
|
|
1059
|
-
this.severity = severity;
|
|
1060
|
-
this.name = "VersionMismatchError";
|
|
1061
|
-
}
|
|
1062
|
-
};
|
|
1063
|
-
async function getBestVersionSource(tagName, packageVersion, cwd3, mismatchStrategy = "error", strictReachable = false) {
|
|
1064
|
-
if (!tagName?.trim()) {
|
|
1065
|
-
return packageVersion ? { source: "package", version: packageVersion, reason: "No git tag provided" } : { source: "initial", version: "0.1.0", reason: "No git tag or package version available" };
|
|
1066
|
-
}
|
|
1067
|
-
const verification = verifyTag(tagName, cwd3);
|
|
1068
|
-
if (!verification.exists || !verification.reachable) {
|
|
1069
|
-
if (strictReachable) {
|
|
1070
|
-
throw new Error(
|
|
1071
|
-
`Git tag '${tagName}' is not reachable from the current commit. The tag exists but cannot be reached from HEAD, which usually means you're on a different branch or the tag is orphaned. To allow fallback to package version, set strictReachable to false in your configuration.`
|
|
1072
|
-
);
|
|
1073
|
-
}
|
|
1074
|
-
if (packageVersion) {
|
|
1075
|
-
log(
|
|
1076
|
-
`Git tag '${tagName}' unreachable (${verification.error}), using package version: ${packageVersion}`,
|
|
1077
|
-
"warning"
|
|
1078
|
-
);
|
|
1079
|
-
return { source: "package", version: packageVersion, reason: "Git tag unreachable" };
|
|
1080
|
-
}
|
|
1081
|
-
log(`Git tag '${tagName}' unreachable and no package version available, using initial version`, "warning");
|
|
1082
|
-
return {
|
|
1083
|
-
source: "initial",
|
|
1084
|
-
version: "0.1.0",
|
|
1085
|
-
reason: "Git tag unreachable, no package version"
|
|
1086
|
-
};
|
|
1087
|
-
}
|
|
1088
|
-
if (!packageVersion) {
|
|
1089
|
-
return {
|
|
1090
|
-
source: "git",
|
|
1091
|
-
version: tagName,
|
|
1092
|
-
reason: "Git tag exists, no package version to compare"
|
|
1093
|
-
};
|
|
1094
|
-
}
|
|
1095
|
-
try {
|
|
1096
|
-
const cleanTagVersion = tagName.replace(/^.*?([0-9])/, "$1");
|
|
1097
|
-
const cleanPackageVersion = packageVersion;
|
|
1098
|
-
const mismatch = detectVersionMismatch(cleanTagVersion, cleanPackageVersion);
|
|
1099
|
-
const mismatchInfo = mismatch.isMismatch ? { detected: true, severity: mismatch.severity, message: mismatch.message } : void 0;
|
|
1100
|
-
if (mismatch.isMismatch) {
|
|
1101
|
-
switch (mismatchStrategy) {
|
|
1102
|
-
case "error":
|
|
1103
|
-
throw new VersionMismatchError(
|
|
1104
|
-
`Version mismatch detected: ${mismatch.message}
|
|
1105
|
-
To resolve: delete the conflicting tag, update package.json, or change mismatchStrategy to 'warn' or 'ignore'`,
|
|
1106
|
-
mismatch.severity
|
|
1107
|
-
);
|
|
1108
|
-
case "warn":
|
|
1109
|
-
log(mismatch.message, "warning");
|
|
1110
|
-
log(
|
|
1111
|
-
`Continuing with git tag ${tagName}. To use package version instead, set mismatchStrategy to 'prefer-package'`,
|
|
1112
|
-
"warning"
|
|
1113
|
-
);
|
|
1114
|
-
break;
|
|
1115
|
-
case "ignore":
|
|
1116
|
-
break;
|
|
1117
|
-
case "prefer-package":
|
|
1118
|
-
log(mismatch.message, "warning");
|
|
1119
|
-
log(`Using package version ${packageVersion} due to mismatchStrategy='prefer-package'`, "info");
|
|
1120
|
-
return {
|
|
1121
|
-
source: "package",
|
|
1122
|
-
version: packageVersion,
|
|
1123
|
-
reason: "Mismatch detected, using package version per strategy",
|
|
1124
|
-
mismatch: mismatchInfo
|
|
1125
|
-
};
|
|
1126
|
-
case "prefer-git":
|
|
1127
|
-
log(mismatch.message, "warning");
|
|
1128
|
-
log(`Using git tag ${tagName} due to mismatchStrategy='prefer-git'`, "info");
|
|
1129
|
-
return {
|
|
1130
|
-
source: "git",
|
|
1131
|
-
version: tagName,
|
|
1132
|
-
reason: "Mismatch detected, using git tag per strategy",
|
|
1133
|
-
mismatch: mismatchInfo
|
|
1134
|
-
};
|
|
1135
|
-
}
|
|
1136
|
-
}
|
|
1137
|
-
if (import_semver2.default.gt(cleanPackageVersion, cleanTagVersion)) {
|
|
1138
|
-
log(`Package version ${packageVersion} is newer than git tag ${tagName}, using package version`, "info");
|
|
1139
|
-
return {
|
|
1140
|
-
source: "package",
|
|
1141
|
-
version: packageVersion,
|
|
1142
|
-
reason: "Package version is newer",
|
|
1143
|
-
mismatch: mismatchInfo
|
|
1144
|
-
};
|
|
1145
|
-
}
|
|
1146
|
-
if (import_semver2.default.gt(cleanTagVersion, cleanPackageVersion)) {
|
|
1147
|
-
log(`Git tag ${tagName} is newer than package version ${packageVersion}, using git tag`, "info");
|
|
1148
|
-
return {
|
|
1149
|
-
source: "git",
|
|
1150
|
-
version: tagName,
|
|
1151
|
-
reason: "Git tag is newer",
|
|
1152
|
-
mismatch: mismatchInfo
|
|
1153
|
-
};
|
|
1154
|
-
}
|
|
1155
|
-
return {
|
|
1156
|
-
source: "git",
|
|
1157
|
-
version: tagName,
|
|
1158
|
-
reason: "Versions equal, using git tag",
|
|
1159
|
-
mismatch: mismatchInfo
|
|
1160
|
-
};
|
|
1161
|
-
} catch (error) {
|
|
1162
|
-
if (error instanceof VersionMismatchError) {
|
|
1163
|
-
throw error;
|
|
1164
|
-
}
|
|
1165
|
-
log(`Failed to compare versions, defaulting to git tag: ${error}`, "warning");
|
|
1166
|
-
return { source: "git", version: tagName, reason: "Version comparison failed" };
|
|
1167
|
-
}
|
|
1168
|
-
}
|
|
1169
|
-
|
|
1170
|
-
// src/core/versionCalculator.ts
|
|
1171
|
-
async function calculateVersion(config, options) {
|
|
1172
|
-
const {
|
|
1173
|
-
type: configType,
|
|
1174
|
-
preset = "angular",
|
|
1175
|
-
versionPrefix,
|
|
1176
|
-
prereleaseIdentifier: configPrereleaseIdentifier,
|
|
1177
|
-
branchPattern,
|
|
1178
|
-
baseBranch,
|
|
1179
|
-
mismatchStrategy,
|
|
1180
|
-
strictReachable
|
|
1181
|
-
} = config;
|
|
1182
|
-
const {
|
|
1183
|
-
latestTag,
|
|
1184
|
-
name,
|
|
1185
|
-
path: pkgPath,
|
|
1186
|
-
type: optionsType,
|
|
1187
|
-
prereleaseIdentifier: optionsPrereleaseIdentifier
|
|
1188
|
-
} = options;
|
|
1189
|
-
const type = optionsType || configType;
|
|
1190
|
-
const prereleaseIdentifier = optionsPrereleaseIdentifier || configPrereleaseIdentifier;
|
|
1191
|
-
const initialVersion = "0.1.0";
|
|
1192
|
-
const hasNoTags = !latestTag || latestTag.trim() === "";
|
|
1193
|
-
const normalizedPrereleaseId = normalizePrereleaseIdentifier(prereleaseIdentifier, config);
|
|
1194
|
-
try {
|
|
1195
|
-
let determineTagSearchPattern2 = function(packageName, prefix) {
|
|
1196
|
-
if (!packageName) {
|
|
1197
|
-
return prefix;
|
|
1198
|
-
}
|
|
1199
|
-
return `${packageName}@${prefix}`;
|
|
1200
|
-
}, escapeRegExp3 = function(string) {
|
|
1201
|
-
return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
1202
|
-
}, getCurrentVersionFromSource2 = function() {
|
|
1203
|
-
if (!versionSource) {
|
|
1204
|
-
if (hasNoTags) {
|
|
1205
|
-
return initialVersion;
|
|
1206
|
-
}
|
|
1207
|
-
const cleanedTag = import_semver3.default.clean(latestTag) || latestTag;
|
|
1208
|
-
return import_semver3.default.clean(cleanedTag.replace(new RegExp(`^${escapedTagPattern}`), "")) || "0.0.0";
|
|
1209
|
-
}
|
|
1210
|
-
if (versionSource.source === "git") {
|
|
1211
|
-
const cleanedTag = import_semver3.default.clean(versionSource.version) || versionSource.version;
|
|
1212
|
-
return import_semver3.default.clean(cleanedTag.replace(new RegExp(`^${escapedTagPattern}`), "")) || "0.0.0";
|
|
1213
|
-
}
|
|
1214
|
-
return versionSource.version;
|
|
1215
|
-
};
|
|
1216
|
-
var determineTagSearchPattern = determineTagSearchPattern2, escapeRegExp2 = escapeRegExp3, getCurrentVersionFromSource = getCurrentVersionFromSource2;
|
|
1217
|
-
const originalPrefix = versionPrefix || "";
|
|
1218
|
-
const tagSearchPattern = determineTagSearchPattern2(name, originalPrefix);
|
|
1219
|
-
const escapedTagPattern = escapeRegExp3(tagSearchPattern);
|
|
1220
|
-
let versionSource;
|
|
1221
|
-
if (pkgPath) {
|
|
1222
|
-
const packageDir = pkgPath || (0, import_node_process.cwd)();
|
|
1223
|
-
const manifestResult = getVersionFromManifests(packageDir);
|
|
1224
|
-
const packageVersion = manifestResult.manifestFound && manifestResult.version ? manifestResult.version : void 0;
|
|
1225
|
-
versionSource = await getBestVersionSource(
|
|
1226
|
-
latestTag,
|
|
1227
|
-
packageVersion,
|
|
1228
|
-
packageDir,
|
|
1229
|
-
mismatchStrategy,
|
|
1230
|
-
strictReachable
|
|
1231
|
-
);
|
|
1232
|
-
log(`Using version source: ${versionSource.source} (${versionSource.reason})`, "info");
|
|
1233
|
-
}
|
|
1234
|
-
const specifiedType = type;
|
|
1235
|
-
if (specifiedType) {
|
|
1236
|
-
const currentVersion = getCurrentVersionFromSource2();
|
|
1237
|
-
const isCurrentPrerelease = import_semver3.default.prerelease(currentVersion);
|
|
1238
|
-
const explicitlyRequestedPrerelease = config.isPrerelease;
|
|
1239
|
-
if (STANDARD_BUMP_TYPES.includes(specifiedType) && (isCurrentPrerelease || explicitlyRequestedPrerelease)) {
|
|
1240
|
-
const prereleaseId2 = explicitlyRequestedPrerelease || isCurrentPrerelease ? normalizedPrereleaseId : void 0;
|
|
1241
|
-
log(
|
|
1242
|
-
explicitlyRequestedPrerelease ? `Creating prerelease version with identifier '${prereleaseId2}' using ${specifiedType}` : `Cleaning prerelease identifier from ${currentVersion} for ${specifiedType} bump`,
|
|
1243
|
-
"debug"
|
|
1244
|
-
);
|
|
1245
|
-
return bumpVersion(currentVersion, specifiedType, prereleaseId2);
|
|
1246
|
-
}
|
|
1247
|
-
const isPrereleaseBumpType = ["prerelease", "premajor", "preminor", "prepatch"].includes(specifiedType);
|
|
1248
|
-
const prereleaseId = config.isPrerelease || isPrereleaseBumpType ? normalizedPrereleaseId : void 0;
|
|
1249
|
-
return bumpVersion(currentVersion, specifiedType, prereleaseId);
|
|
1250
|
-
}
|
|
1251
|
-
if (branchPattern && branchPattern.length > 0) {
|
|
1252
|
-
const currentBranch = getCurrentBranch();
|
|
1253
|
-
if (baseBranch) {
|
|
1254
|
-
lastMergeBranchName(branchPattern, baseBranch);
|
|
1255
|
-
}
|
|
1256
|
-
const branchToCheck = currentBranch;
|
|
1257
|
-
let branchVersionType;
|
|
1258
|
-
for (const pattern of branchPattern) {
|
|
1259
|
-
if (!pattern.includes(":")) {
|
|
1260
|
-
log(`Invalid branch pattern "${pattern}" - missing colon. Skipping.`, "warning");
|
|
1261
|
-
continue;
|
|
1262
|
-
}
|
|
1263
|
-
const [patternRegex, releaseType] = pattern.split(":");
|
|
1264
|
-
if (new RegExp(patternRegex).test(branchToCheck)) {
|
|
1265
|
-
branchVersionType = releaseType;
|
|
1266
|
-
log(`Using branch pattern ${patternRegex} for version type ${releaseType}`, "debug");
|
|
1267
|
-
break;
|
|
1268
|
-
}
|
|
1269
|
-
}
|
|
1270
|
-
if (branchVersionType) {
|
|
1271
|
-
const currentVersion = getCurrentVersionFromSource2();
|
|
1272
|
-
log(`Applying ${branchVersionType} bump based on branch pattern`, "debug");
|
|
1273
|
-
const isPrereleaseBumpType = ["prerelease", "premajor", "preminor", "prepatch"].includes(branchVersionType);
|
|
1274
|
-
const prereleaseId = config.isPrerelease || isPrereleaseBumpType ? normalizedPrereleaseId : void 0;
|
|
1275
|
-
return bumpVersion(currentVersion, branchVersionType, prereleaseId);
|
|
1276
|
-
}
|
|
1277
|
-
}
|
|
1278
|
-
try {
|
|
1279
|
-
const bumper = new import_conventional_recommended_bump.Bumper();
|
|
1280
|
-
bumper.loadPreset(preset);
|
|
1281
|
-
const recommendedBump = await bumper.bump();
|
|
1282
|
-
const releaseTypeFromCommits = recommendedBump && "releaseType" in recommendedBump ? recommendedBump.releaseType : void 0;
|
|
1283
|
-
const currentVersion = getCurrentVersionFromSource2();
|
|
1284
|
-
if (versionSource && versionSource.source === "git") {
|
|
1285
|
-
const checkPath = pkgPath || (0, import_node_process.cwd)();
|
|
1286
|
-
const commitsLength = getCommitsLength(checkPath, versionSource.version);
|
|
1287
|
-
if (commitsLength === 0) {
|
|
1288
|
-
log(
|
|
1289
|
-
`No new commits found for ${name || "project"} since ${versionSource.version}, skipping version bump`,
|
|
1290
|
-
"info"
|
|
1291
|
-
);
|
|
1292
|
-
return "";
|
|
1293
|
-
}
|
|
1294
|
-
} else if (versionSource && versionSource.source === "package") {
|
|
1295
|
-
log(
|
|
1296
|
-
`Using package version ${versionSource.version} as base, letting conventional commits determine bump necessity`,
|
|
1297
|
-
"debug"
|
|
1298
|
-
);
|
|
1299
|
-
}
|
|
1300
|
-
if (!releaseTypeFromCommits) {
|
|
1301
|
-
if (latestTag && latestTag.trim() !== "") {
|
|
1302
|
-
log(`No relevant commits found for ${name || "project"} since ${latestTag}, skipping version bump`, "info");
|
|
1303
|
-
} else {
|
|
1304
|
-
log(`No relevant commits found for ${name || "project"}, skipping version bump`, "info");
|
|
1305
|
-
}
|
|
1306
|
-
return "";
|
|
1307
|
-
}
|
|
1308
|
-
const isPrereleaseBumpType = ["prerelease", "premajor", "preminor", "prepatch"].includes(releaseTypeFromCommits);
|
|
1309
|
-
const prereleaseId = config.isPrerelease || isPrereleaseBumpType ? normalizedPrereleaseId : void 0;
|
|
1310
|
-
return bumpVersion(currentVersion, releaseTypeFromCommits, prereleaseId);
|
|
1311
|
-
} catch (error) {
|
|
1312
|
-
log(`Failed to calculate version for ${name || "project"}`, "error");
|
|
1313
|
-
console.error(error);
|
|
1314
|
-
if (error instanceof Error && error.message.includes("No names found")) {
|
|
1315
|
-
log("No tags found, proceeding with initial version calculation (if applicable).", "info");
|
|
1316
|
-
return initialVersion;
|
|
1317
|
-
}
|
|
1318
|
-
throw error;
|
|
1319
|
-
}
|
|
1320
|
-
} catch (error) {
|
|
1321
|
-
log(`Failed to calculate version for ${name || "project"}`, "error");
|
|
1322
|
-
console.error(error);
|
|
1323
|
-
if (error instanceof Error && error.message.includes("No names found")) {
|
|
1324
|
-
log("No tags found, proceeding with initial version calculation (if applicable).", "info");
|
|
1325
|
-
return initialVersion;
|
|
1326
|
-
}
|
|
1327
|
-
throw error;
|
|
1328
|
-
}
|
|
1329
|
-
}
|
|
1330
|
-
|
|
1331
|
-
// src/utils/packageMatching.ts
|
|
1332
|
-
var import_micromatch2 = __toESM(require("micromatch"), 1);
|
|
1333
|
-
function matchesPackageTarget(packageName, target) {
|
|
1334
|
-
if (packageName === target) {
|
|
1335
|
-
return true;
|
|
1336
|
-
}
|
|
1337
|
-
if (target.startsWith("@") && target.endsWith("/*") && !target.includes("**")) {
|
|
1338
|
-
const scope = target.slice(0, -2);
|
|
1339
|
-
return packageName.startsWith(`${scope}/`);
|
|
1340
|
-
}
|
|
1341
|
-
try {
|
|
1342
|
-
return import_micromatch2.default.isMatch(packageName, target, {
|
|
1343
|
-
dot: true,
|
|
1344
|
-
contains: false,
|
|
1345
|
-
// Changed to false to ensure full pattern matching
|
|
1346
|
-
noglobstar: false,
|
|
1347
|
-
bash: true
|
|
1348
|
-
});
|
|
1349
|
-
} catch (error) {
|
|
1350
|
-
log(`Invalid pattern "${target}": ${error instanceof Error ? error.message : String(error)}`, "warning");
|
|
1351
|
-
return false;
|
|
1352
|
-
}
|
|
1353
|
-
}
|
|
1354
|
-
function shouldMatchPackageTargets(packageName, targets) {
|
|
1355
|
-
return targets.some((target) => matchesPackageTarget(packageName, target));
|
|
1356
|
-
}
|
|
1357
|
-
function shouldProcessPackage(packageName, skip = []) {
|
|
1358
|
-
if (skip.length === 0) {
|
|
1359
|
-
return true;
|
|
1360
|
-
}
|
|
1361
|
-
return !shouldMatchPackageTargets(packageName, skip);
|
|
1362
|
-
}
|
|
1363
|
-
|
|
1364
|
-
// src/package/packageProcessor.ts
|
|
1365
|
-
var PackageProcessor = class {
|
|
1366
|
-
skip;
|
|
1367
|
-
versionPrefix;
|
|
1368
|
-
tagTemplate;
|
|
1369
|
-
commitMessageTemplate;
|
|
1370
|
-
dryRun;
|
|
1371
|
-
getLatestTag;
|
|
1372
|
-
config;
|
|
1373
|
-
// Config for version calculation
|
|
1374
|
-
fullConfig;
|
|
1375
|
-
constructor(options) {
|
|
1376
|
-
this.skip = options.skip || [];
|
|
1377
|
-
this.versionPrefix = options.versionPrefix || "v";
|
|
1378
|
-
this.tagTemplate = options.tagTemplate;
|
|
1379
|
-
this.commitMessageTemplate = options.commitMessageTemplate || "";
|
|
1380
|
-
this.dryRun = options.dryRun || false;
|
|
1381
|
-
this.getLatestTag = options.getLatestTag;
|
|
1382
|
-
this.config = options.config;
|
|
1383
|
-
this.fullConfig = options.fullConfig;
|
|
1384
|
-
}
|
|
1385
|
-
/**
|
|
1386
|
-
* Process packages based on skip list only (targeting handled at discovery time)
|
|
1387
|
-
*/
|
|
1388
|
-
async processPackages(packages) {
|
|
1389
|
-
const tags = [];
|
|
1390
|
-
const updatedPackagesInfo = [];
|
|
1391
|
-
if (!packages || !Array.isArray(packages)) {
|
|
1392
|
-
log("Invalid packages data provided. Expected array of packages.", "error");
|
|
1393
|
-
return { updatedPackages: [], tags: [] };
|
|
1394
|
-
}
|
|
1395
|
-
const pkgsToConsider = packages.filter((pkg) => {
|
|
1396
|
-
const pkgName = pkg.packageJson.name;
|
|
1397
|
-
const shouldProcess = shouldProcessPackage(pkgName, this.skip);
|
|
1398
|
-
if (!shouldProcess) {
|
|
1399
|
-
log(`Skipping package ${pkgName} as it's in the skip list.`, "info");
|
|
1400
|
-
}
|
|
1401
|
-
return shouldProcess;
|
|
1402
|
-
});
|
|
1403
|
-
log(`Found ${pkgsToConsider.length} package(s) to process after filtering.`, "info");
|
|
1404
|
-
if (pkgsToConsider.length === 0) {
|
|
1405
|
-
log("No packages found to process.", "info");
|
|
1406
|
-
return { updatedPackages: [], tags: [] };
|
|
1407
|
-
}
|
|
1408
|
-
for (const pkg of pkgsToConsider) {
|
|
1409
|
-
const name = pkg.packageJson.name;
|
|
1410
|
-
const pkgPath = pkg.dir;
|
|
1411
|
-
log(`Processing package ${name} at path: ${pkgPath}`, "info");
|
|
1412
|
-
const formattedPrefix = formatVersionPrefix(this.versionPrefix);
|
|
1413
|
-
let latestTagResult = "";
|
|
1414
|
-
try {
|
|
1415
|
-
latestTagResult = await getLatestTagForPackage(name, this.versionPrefix, {
|
|
1416
|
-
tagTemplate: this.tagTemplate,
|
|
1417
|
-
packageSpecificTags: this.fullConfig.packageSpecificTags
|
|
1418
|
-
});
|
|
1419
|
-
} catch (error) {
|
|
1420
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
1421
|
-
log(`Error getting package-specific tag for ${name}, falling back to global tag: ${errorMessage}`, "warning");
|
|
1422
|
-
}
|
|
1423
|
-
if (!latestTagResult) {
|
|
1424
|
-
try {
|
|
1425
|
-
const packageDir = pkgPath;
|
|
1426
|
-
let manifestFallbackUsed = false;
|
|
1427
|
-
const manifestResult = getVersionFromManifests(packageDir);
|
|
1428
|
-
if (manifestResult.manifestFound && manifestResult.version) {
|
|
1429
|
-
log(
|
|
1430
|
-
`Using ${manifestResult.manifestType} version ${manifestResult.version} for ${name} as no package-specific tags found`,
|
|
1431
|
-
"info"
|
|
1432
|
-
);
|
|
1433
|
-
log(`FALLBACK: Using package version from ${manifestResult.manifestType} instead of global tag`, "debug");
|
|
1434
|
-
latestTagResult = `${this.versionPrefix || ""}${manifestResult.version}`;
|
|
1435
|
-
manifestFallbackUsed = true;
|
|
1436
|
-
}
|
|
1437
|
-
if (!manifestFallbackUsed) {
|
|
1438
|
-
const globalTagResult = await this.getLatestTag();
|
|
1439
|
-
if (globalTagResult) {
|
|
1440
|
-
latestTagResult = globalTagResult;
|
|
1441
|
-
log(`Using global tag ${globalTagResult} as fallback for package ${name}`, "info");
|
|
1442
|
-
}
|
|
1443
|
-
}
|
|
1444
|
-
} catch (error) {
|
|
1445
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
1446
|
-
log(`Error getting fallback version, using empty tag value: ${errorMessage}`, "warning");
|
|
1447
|
-
}
|
|
1448
|
-
}
|
|
1449
|
-
const latestTag = latestTagResult;
|
|
1450
|
-
const nextVersion = await calculateVersion(this.fullConfig, {
|
|
1451
|
-
latestTag,
|
|
1452
|
-
versionPrefix: formattedPrefix,
|
|
1453
|
-
path: pkgPath,
|
|
1454
|
-
name,
|
|
1455
|
-
branchPattern: this.config.branchPattern,
|
|
1456
|
-
baseBranch: this.config.baseBranch,
|
|
1457
|
-
prereleaseIdentifier: this.config.prereleaseIdentifier,
|
|
1458
|
-
type: this.config.type
|
|
1459
|
-
});
|
|
1460
|
-
if (!nextVersion) {
|
|
1461
|
-
continue;
|
|
1462
|
-
}
|
|
1463
|
-
let changelogEntries = [];
|
|
1464
|
-
let revisionRange = "HEAD";
|
|
1465
|
-
try {
|
|
1466
|
-
if (latestTag) {
|
|
1467
|
-
const verification = verifyTag(latestTag, pkgPath);
|
|
1468
|
-
if (verification.exists && verification.reachable) {
|
|
1469
|
-
revisionRange = `${latestTag}..HEAD`;
|
|
1470
|
-
} else {
|
|
1471
|
-
if (this.config.strictReachable) {
|
|
1472
|
-
throw new Error(
|
|
1473
|
-
`Cannot generate changelog: tag '${latestTag}' is not reachable from the current commit. When strictReachable is enabled, all tags must be reachable. To allow fallback to all commits, set strictReachable to false.`
|
|
1474
|
-
);
|
|
1475
|
-
}
|
|
1476
|
-
log(`Tag ${latestTag} is unreachable (${verification.error}), using all commits for changelog`, "debug");
|
|
1477
|
-
revisionRange = "HEAD";
|
|
1478
|
-
}
|
|
1479
|
-
} else {
|
|
1480
|
-
revisionRange = "HEAD";
|
|
1481
|
-
}
|
|
1482
|
-
changelogEntries = extractChangelogEntriesFromCommits(pkgPath, revisionRange);
|
|
1483
|
-
const allPackageDirs = packages.map((p) => p.dir);
|
|
1484
|
-
const sharedPackageNames = ["config", "core", "@releasekit/config", "@releasekit/core"];
|
|
1485
|
-
const sharedPackageDirs = packages.filter((p) => sharedPackageNames.includes(p.packageJson.name)).map((p) => p.dir);
|
|
1486
|
-
const repoLevelEntries = extractRepoLevelChangelogEntries(
|
|
1487
|
-
pkgPath,
|
|
1488
|
-
revisionRange,
|
|
1489
|
-
allPackageDirs,
|
|
1490
|
-
sharedPackageDirs
|
|
1491
|
-
);
|
|
1492
|
-
if (repoLevelEntries.length > 0) {
|
|
1493
|
-
log(`Adding ${repoLevelEntries.length} repo-level commit(s) to ${name} changelog`, "debug");
|
|
1494
|
-
changelogEntries = [...repoLevelEntries, ...changelogEntries];
|
|
1495
|
-
}
|
|
1496
|
-
if (changelogEntries.length === 0) {
|
|
1497
|
-
changelogEntries = [
|
|
1498
|
-
{
|
|
1499
|
-
type: "changed",
|
|
1500
|
-
description: `Update version to ${nextVersion}`
|
|
1501
|
-
}
|
|
1502
|
-
];
|
|
1503
|
-
}
|
|
1504
|
-
} catch (error) {
|
|
1505
|
-
log(`Error extracting changelog entries: ${error instanceof Error ? error.message : String(error)}`, "warning");
|
|
1506
|
-
changelogEntries = [
|
|
1507
|
-
{
|
|
1508
|
-
type: "changed",
|
|
1509
|
-
description: `Update version to ${nextVersion}`
|
|
1510
|
-
}
|
|
1511
|
-
];
|
|
1512
|
-
}
|
|
1513
|
-
let repoUrl;
|
|
1514
|
-
try {
|
|
1515
|
-
const packageJsonPath2 = import_node_path6.default.join(pkgPath, "package.json");
|
|
1516
|
-
if (fs5.existsSync(packageJsonPath2)) {
|
|
1517
|
-
const packageJson = JSON.parse(fs5.readFileSync(packageJsonPath2, "utf8"));
|
|
1518
|
-
if (packageJson.repository) {
|
|
1519
|
-
if (typeof packageJson.repository === "string") {
|
|
1520
|
-
repoUrl = packageJson.repository;
|
|
1521
|
-
} else if (packageJson.repository.url) {
|
|
1522
|
-
repoUrl = packageJson.repository.url;
|
|
1523
|
-
}
|
|
1524
|
-
if (repoUrl?.startsWith("git+") && repoUrl?.endsWith(".git")) {
|
|
1525
|
-
repoUrl = repoUrl.substring(4, repoUrl.length - 4);
|
|
1526
|
-
}
|
|
1527
|
-
}
|
|
1528
|
-
}
|
|
1529
|
-
} catch (error) {
|
|
1530
|
-
log(
|
|
1531
|
-
`Could not determine repository URL for changelog links: ${error instanceof Error ? error.message : String(error)}`,
|
|
1532
|
-
"warning"
|
|
1533
|
-
);
|
|
1534
|
-
}
|
|
1535
|
-
addChangelogData({
|
|
1536
|
-
packageName: name,
|
|
1537
|
-
version: nextVersion,
|
|
1538
|
-
previousVersion: latestTag || null,
|
|
1539
|
-
revisionRange,
|
|
1540
|
-
repoUrl: repoUrl || null,
|
|
1541
|
-
entries: changelogEntries
|
|
1542
|
-
});
|
|
1543
|
-
const packageJsonPath = import_node_path6.default.join(pkgPath, "package.json");
|
|
1544
|
-
if (fs5.existsSync(packageJsonPath)) {
|
|
1545
|
-
updatePackageVersion(packageJsonPath, nextVersion, this.dryRun);
|
|
1546
|
-
}
|
|
1547
|
-
const cargoEnabled = this.fullConfig.cargo?.enabled !== false;
|
|
1548
|
-
log(`Cargo enabled for ${name}: ${cargoEnabled}, config: ${JSON.stringify(this.fullConfig.cargo)}`, "debug");
|
|
1549
|
-
if (cargoEnabled) {
|
|
1550
|
-
const cargoPaths = this.fullConfig.cargo?.paths;
|
|
1551
|
-
log(`Cargo paths config for ${name}: ${JSON.stringify(cargoPaths)}`, "debug");
|
|
1552
|
-
if (cargoPaths && cargoPaths.length > 0) {
|
|
1553
|
-
for (const cargoPath of cargoPaths) {
|
|
1554
|
-
const resolvedCargoPath = import_node_path6.default.resolve(pkgPath, cargoPath, "Cargo.toml");
|
|
1555
|
-
log(`Checking cargo path for ${name}: ${resolvedCargoPath}`, "debug");
|
|
1556
|
-
if (fs5.existsSync(resolvedCargoPath)) {
|
|
1557
|
-
log(`Found Cargo.toml for ${name} at ${resolvedCargoPath}, updating...`, "debug");
|
|
1558
|
-
updatePackageVersion(resolvedCargoPath, nextVersion, this.dryRun);
|
|
1559
|
-
} else {
|
|
1560
|
-
log(`Cargo.toml not found at ${resolvedCargoPath}`, "debug");
|
|
1561
|
-
}
|
|
1562
|
-
}
|
|
1563
|
-
} else {
|
|
1564
|
-
const cargoTomlPath = import_node_path6.default.join(pkgPath, "Cargo.toml");
|
|
1565
|
-
log(`Checking default cargo path for ${name}: ${cargoTomlPath}`, "debug");
|
|
1566
|
-
if (fs5.existsSync(cargoTomlPath)) {
|
|
1567
|
-
log(`Found Cargo.toml for ${name} at ${cargoTomlPath}, updating...`, "debug");
|
|
1568
|
-
updatePackageVersion(cargoTomlPath, nextVersion, this.dryRun);
|
|
1569
|
-
} else {
|
|
1570
|
-
log(`Cargo.toml not found for ${name} at ${cargoTomlPath}`, "debug");
|
|
1571
|
-
}
|
|
1572
|
-
}
|
|
1573
|
-
} else {
|
|
1574
|
-
log(`Cargo disabled for ${name}`, "debug");
|
|
1575
|
-
}
|
|
1576
|
-
const packageTag = formatTag(
|
|
1577
|
-
nextVersion,
|
|
1578
|
-
this.versionPrefix,
|
|
1579
|
-
name,
|
|
1580
|
-
this.tagTemplate,
|
|
1581
|
-
this.fullConfig.packageSpecificTags
|
|
1582
|
-
);
|
|
1583
|
-
addTag(packageTag);
|
|
1584
|
-
tags.push(packageTag);
|
|
1585
|
-
if (this.dryRun) {
|
|
1586
|
-
log(`[DRY RUN] Would create tag: ${packageTag}`, "info");
|
|
1587
|
-
} else {
|
|
1588
|
-
log(`Version ${nextVersion} prepared (tag: ${packageTag})`, "success");
|
|
1589
|
-
}
|
|
1590
|
-
updatedPackagesInfo.push({ name, version: nextVersion, path: pkgPath });
|
|
1591
|
-
}
|
|
1592
|
-
if (updatedPackagesInfo.length === 0) {
|
|
1593
|
-
log("No packages required a version update.", "info");
|
|
1594
|
-
return { updatedPackages: [], tags };
|
|
1595
|
-
}
|
|
1596
|
-
const packageNames = updatedPackagesInfo.map((p) => p.name).join(", ");
|
|
1597
|
-
const representativeVersion = updatedPackagesInfo[0]?.version || "multiple";
|
|
1598
|
-
let commitMessage = this.commitMessageTemplate || "chore(release): publish packages";
|
|
1599
|
-
const MAX_COMMIT_MSG_LENGTH = 1e4;
|
|
1600
|
-
if (commitMessage.length > MAX_COMMIT_MSG_LENGTH) {
|
|
1601
|
-
log("Commit message template too long, truncating", "warning");
|
|
1602
|
-
commitMessage = commitMessage.slice(0, MAX_COMMIT_MSG_LENGTH);
|
|
1603
|
-
}
|
|
1604
|
-
const placeholderRegex = /\$\{[^{}$]{1,1000}\}/;
|
|
1605
|
-
if (updatedPackagesInfo.length === 1 && placeholderRegex.test(commitMessage)) {
|
|
1606
|
-
const packageName = updatedPackagesInfo[0].name;
|
|
1607
|
-
commitMessage = formatCommitMessage(commitMessage, representativeVersion, packageName);
|
|
1608
|
-
} else {
|
|
1609
|
-
commitMessage = `chore(release): ${packageNames} ${representativeVersion}`;
|
|
1610
|
-
}
|
|
1611
|
-
setCommitMessage(commitMessage);
|
|
1612
|
-
if (this.dryRun) {
|
|
1613
|
-
log(`[DRY RUN] Would commit with message: "${commitMessage}"`, "info");
|
|
1614
|
-
}
|
|
1615
|
-
return {
|
|
1616
|
-
updatedPackages: updatedPackagesInfo,
|
|
1617
|
-
commitMessage,
|
|
1618
|
-
tags
|
|
1619
|
-
};
|
|
1620
|
-
}
|
|
1621
|
-
};
|
|
1622
|
-
|
|
1623
|
-
// src/core/versionStrategies.ts
|
|
1624
|
-
function shouldProcessPackage2(pkg, config) {
|
|
1625
|
-
const pkgName = pkg.packageJson.name;
|
|
1626
|
-
return shouldProcessPackage(pkgName, config.skip);
|
|
1627
|
-
}
|
|
1628
|
-
function updateCargoFiles(packageDir, version, cargoConfig, dryRun = false) {
|
|
1629
|
-
const updatedFiles = [];
|
|
1630
|
-
const cargoEnabled = cargoConfig?.enabled !== false;
|
|
1631
|
-
if (!cargoEnabled) {
|
|
1632
|
-
return updatedFiles;
|
|
1633
|
-
}
|
|
1634
|
-
const cargoPaths = cargoConfig?.paths;
|
|
1635
|
-
if (cargoPaths && cargoPaths.length > 0) {
|
|
1636
|
-
for (const cargoPath of cargoPaths) {
|
|
1637
|
-
const resolvedCargoPath = path6.resolve(packageDir, cargoPath, "Cargo.toml");
|
|
1638
|
-
if (import_node_fs6.default.existsSync(resolvedCargoPath)) {
|
|
1639
|
-
updatePackageVersion(resolvedCargoPath, version, dryRun);
|
|
1640
|
-
updatedFiles.push(resolvedCargoPath);
|
|
1641
|
-
}
|
|
1642
|
-
}
|
|
1643
|
-
} else {
|
|
1644
|
-
const cargoTomlPath = path6.join(packageDir, "Cargo.toml");
|
|
1645
|
-
if (import_node_fs6.default.existsSync(cargoTomlPath)) {
|
|
1646
|
-
updatePackageVersion(cargoTomlPath, version, dryRun);
|
|
1647
|
-
updatedFiles.push(cargoTomlPath);
|
|
1648
|
-
}
|
|
1649
|
-
}
|
|
1650
|
-
return updatedFiles;
|
|
1651
|
-
}
|
|
1652
|
-
function createSyncStrategy(config) {
|
|
1653
|
-
return async (packages) => {
|
|
1654
|
-
try {
|
|
1655
|
-
const {
|
|
1656
|
-
versionPrefix,
|
|
1657
|
-
tagTemplate,
|
|
1658
|
-
baseBranch,
|
|
1659
|
-
branchPattern,
|
|
1660
|
-
commitMessage = `chore(release): v\${version}`,
|
|
1661
|
-
prereleaseIdentifier,
|
|
1662
|
-
dryRun,
|
|
1663
|
-
mainPackage
|
|
1664
|
-
} = config;
|
|
1665
|
-
const formattedPrefix = formatVersionPrefix(versionPrefix || "v");
|
|
1666
|
-
let latestTag = await getLatestTag();
|
|
1667
|
-
let mainPkgPath = packages.root;
|
|
1668
|
-
let mainPkgName;
|
|
1669
|
-
if (mainPackage) {
|
|
1670
|
-
const mainPkg = packages.packages.find((p) => p.packageJson.name === mainPackage);
|
|
1671
|
-
if (mainPkg) {
|
|
1672
|
-
mainPkgPath = mainPkg.dir;
|
|
1673
|
-
mainPkgName = mainPkg.packageJson.name;
|
|
1674
|
-
log(`Using ${mainPkgName} as primary package for version determination`, "info");
|
|
1675
|
-
} else {
|
|
1676
|
-
log(`Main package '${mainPackage}' not found. Using root package for version determination.`, "warning");
|
|
1677
|
-
}
|
|
1678
|
-
}
|
|
1679
|
-
if (!mainPkgPath) {
|
|
1680
|
-
mainPkgPath = process.cwd();
|
|
1681
|
-
log(`No valid package path found, using current working directory: ${mainPkgPath}`, "warning");
|
|
1682
|
-
}
|
|
1683
|
-
if (mainPkgName) {
|
|
1684
|
-
const packageSpecificTag = await getLatestTagForPackage(mainPkgName, formattedPrefix, {
|
|
1685
|
-
tagTemplate,
|
|
1686
|
-
packageSpecificTags: config.packageSpecificTags
|
|
1687
|
-
});
|
|
1688
|
-
if (packageSpecificTag) {
|
|
1689
|
-
latestTag = packageSpecificTag;
|
|
1690
|
-
log(`Using package-specific tag for ${mainPkgName}: ${latestTag}`, "debug");
|
|
1691
|
-
} else {
|
|
1692
|
-
log(`No package-specific tag found for ${mainPkgName}, using global tag: ${latestTag}`, "debug");
|
|
1693
|
-
}
|
|
1694
|
-
}
|
|
1695
|
-
const nextVersion = await calculateVersion(config, {
|
|
1696
|
-
latestTag,
|
|
1697
|
-
versionPrefix: formattedPrefix,
|
|
1698
|
-
branchPattern,
|
|
1699
|
-
baseBranch,
|
|
1700
|
-
prereleaseIdentifier,
|
|
1701
|
-
path: mainPkgPath,
|
|
1702
|
-
name: mainPkgName,
|
|
1703
|
-
type: config.type
|
|
1704
|
-
});
|
|
1705
|
-
if (!nextVersion) {
|
|
1706
|
-
const msg = mainPkgName ? `No version change needed for ${mainPkgName}` : "No version change needed";
|
|
1707
|
-
log(msg, "info");
|
|
1708
|
-
return;
|
|
1709
|
-
}
|
|
1710
|
-
const files = [];
|
|
1711
|
-
const updatedPackages = [];
|
|
1712
|
-
const processedPaths = /* @__PURE__ */ new Set();
|
|
1713
|
-
try {
|
|
1714
|
-
if (packages.root) {
|
|
1715
|
-
const rootPkgPath = path6.join(packages.root, "package.json");
|
|
1716
|
-
if (import_node_fs6.default.existsSync(rootPkgPath)) {
|
|
1717
|
-
updatePackageVersion(rootPkgPath, nextVersion, dryRun);
|
|
1718
|
-
files.push(rootPkgPath);
|
|
1719
|
-
updatedPackages.push("root");
|
|
1720
|
-
processedPaths.add(rootPkgPath);
|
|
1721
|
-
const rootCargoFiles = updateCargoFiles(packages.root, nextVersion, config.cargo, dryRun);
|
|
1722
|
-
files.push(...rootCargoFiles);
|
|
1723
|
-
}
|
|
1724
|
-
} else {
|
|
1725
|
-
log("Root package path is undefined, skipping root package.json update", "warning");
|
|
1726
|
-
}
|
|
1727
|
-
} catch (error) {
|
|
1728
|
-
const errMessage = error instanceof Error ? error.message : String(error);
|
|
1729
|
-
log(`Failed to update root package.json: ${errMessage}`, "error");
|
|
1730
|
-
}
|
|
1731
|
-
for (const pkg of packages.packages) {
|
|
1732
|
-
if (!shouldProcessPackage2(pkg, config)) {
|
|
1733
|
-
continue;
|
|
1734
|
-
}
|
|
1735
|
-
const packageJsonPath = path6.join(pkg.dir, "package.json");
|
|
1736
|
-
if (processedPaths.has(packageJsonPath)) {
|
|
1737
|
-
continue;
|
|
1738
|
-
}
|
|
1739
|
-
updatePackageVersion(packageJsonPath, nextVersion, dryRun);
|
|
1740
|
-
files.push(packageJsonPath);
|
|
1741
|
-
updatedPackages.push(pkg.packageJson.name);
|
|
1742
|
-
processedPaths.add(packageJsonPath);
|
|
1743
|
-
const pkgCargoFiles = updateCargoFiles(pkg.dir, nextVersion, config.cargo, dryRun);
|
|
1744
|
-
files.push(...pkgCargoFiles);
|
|
1745
|
-
}
|
|
1746
|
-
if (updatedPackages.length > 0) {
|
|
1747
|
-
log(`Updated ${updatedPackages.length} package(s) to version ${nextVersion}`, "success");
|
|
1748
|
-
} else {
|
|
1749
|
-
log("No packages were updated", "warning");
|
|
1750
|
-
return;
|
|
1751
|
-
}
|
|
1752
|
-
let changelogEntries = [];
|
|
1753
|
-
let revisionRange = "HEAD";
|
|
1754
|
-
try {
|
|
1755
|
-
if (latestTag) {
|
|
1756
|
-
try {
|
|
1757
|
-
execSync("git", ["rev-parse", "--verify", latestTag], {
|
|
1758
|
-
cwd: mainPkgPath,
|
|
1759
|
-
stdio: "ignore"
|
|
1760
|
-
});
|
|
1761
|
-
revisionRange = `${latestTag}..HEAD`;
|
|
1762
|
-
} catch {
|
|
1763
|
-
if (config.strictReachable) {
|
|
1764
|
-
throw new Error(
|
|
1765
|
-
`Cannot generate changelog: tag '${latestTag}' is not reachable from the current commit. When strictReachable is enabled, all tags must be reachable. To allow fallback to all commits, set strictReachable to false.`
|
|
1766
|
-
);
|
|
1767
|
-
}
|
|
1768
|
-
log(`Tag ${latestTag} doesn't exist, using all commits for changelog`, "debug");
|
|
1769
|
-
revisionRange = "HEAD";
|
|
1770
|
-
}
|
|
1771
|
-
}
|
|
1772
|
-
changelogEntries = extractChangelogEntriesFromCommits(mainPkgPath, revisionRange);
|
|
1773
|
-
if (changelogEntries.length === 0) {
|
|
1774
|
-
changelogEntries = [
|
|
1775
|
-
{
|
|
1776
|
-
type: "changed",
|
|
1777
|
-
description: `Update version to ${nextVersion}`
|
|
1778
|
-
}
|
|
1779
|
-
];
|
|
1780
|
-
}
|
|
1781
|
-
} catch (error) {
|
|
1782
|
-
log(`Error extracting changelog entries: ${error instanceof Error ? error.message : String(error)}`, "warning");
|
|
1783
|
-
changelogEntries = [
|
|
1784
|
-
{
|
|
1785
|
-
type: "changed",
|
|
1786
|
-
description: `Update version to ${nextVersion}`
|
|
1787
|
-
}
|
|
1788
|
-
];
|
|
1789
|
-
}
|
|
1790
|
-
addChangelogData({
|
|
1791
|
-
packageName: mainPkgName || "monorepo",
|
|
1792
|
-
version: nextVersion,
|
|
1793
|
-
previousVersion: latestTag || null,
|
|
1794
|
-
revisionRange,
|
|
1795
|
-
repoUrl: null,
|
|
1796
|
-
entries: changelogEntries
|
|
1797
|
-
});
|
|
1798
|
-
let tagPackageName = null;
|
|
1799
|
-
let commitPackageName;
|
|
1800
|
-
if (config.packageSpecificTags && packages.packages.length === 1) {
|
|
1801
|
-
tagPackageName = packages.packages[0].packageJson.name;
|
|
1802
|
-
commitPackageName = packages.packages[0].packageJson.name;
|
|
1803
|
-
}
|
|
1804
|
-
const nextTag = formatTag(
|
|
1805
|
-
nextVersion,
|
|
1806
|
-
formattedPrefix,
|
|
1807
|
-
tagPackageName,
|
|
1808
|
-
tagTemplate,
|
|
1809
|
-
config.packageSpecificTags || false
|
|
1810
|
-
);
|
|
1811
|
-
const formattedCommitMessage = formatCommitMessage(commitMessage, nextVersion, commitPackageName, void 0);
|
|
1812
|
-
addTag(nextTag);
|
|
1813
|
-
setCommitMessage(formattedCommitMessage);
|
|
1814
|
-
if (!dryRun) {
|
|
1815
|
-
log(`Version ${nextVersion} prepared (tag: ${nextTag})`, "success");
|
|
1816
|
-
} else {
|
|
1817
|
-
log(`Would create tag: ${nextTag}`, "info");
|
|
1818
|
-
}
|
|
1819
|
-
} catch (error) {
|
|
1820
|
-
if (BaseVersionError.isVersionError(error)) {
|
|
1821
|
-
log(`Synced Strategy failed: ${error.message} (${error.code})`, "error");
|
|
1822
|
-
} else {
|
|
1823
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
1824
|
-
log(`Synced Strategy failed: ${errorMessage}`, "error");
|
|
1825
|
-
}
|
|
1826
|
-
throw error;
|
|
1827
|
-
}
|
|
1828
|
-
};
|
|
1829
|
-
}
|
|
1830
|
-
function createSingleStrategy(config) {
|
|
1831
|
-
return async (packages) => {
|
|
1832
|
-
try {
|
|
1833
|
-
const { mainPackage, versionPrefix, tagTemplate, commitMessage = `chore(release): \${version}`, dryRun } = config;
|
|
1834
|
-
let packageName;
|
|
1835
|
-
if (mainPackage) {
|
|
1836
|
-
packageName = mainPackage;
|
|
1837
|
-
} else if (packages.packages.length === 1) {
|
|
1838
|
-
packageName = packages.packages[0].packageJson.name;
|
|
1839
|
-
} else {
|
|
1840
|
-
throw createVersionError(
|
|
1841
|
-
"INVALID_CONFIG" /* INVALID_CONFIG */,
|
|
1842
|
-
"Single mode requires either mainPackage or exactly one resolved package"
|
|
1843
|
-
);
|
|
1844
|
-
}
|
|
1845
|
-
const pkg = packages.packages.find((p) => p.packageJson.name === packageName);
|
|
1846
|
-
if (!pkg) {
|
|
1847
|
-
throw createVersionError("PACKAGE_NOT_FOUND" /* PACKAGE_NOT_FOUND */, packageName);
|
|
1848
|
-
}
|
|
1849
|
-
const pkgPath = pkg.dir;
|
|
1850
|
-
const formattedPrefix = formatVersionPrefix(versionPrefix || "v");
|
|
1851
|
-
let latestTagResult = await getLatestTagForPackage(packageName, formattedPrefix, {
|
|
1852
|
-
tagTemplate,
|
|
1853
|
-
packageSpecificTags: config.packageSpecificTags
|
|
1854
|
-
});
|
|
1855
|
-
if (!latestTagResult) {
|
|
1856
|
-
const globalTagResult = await getLatestTag();
|
|
1857
|
-
latestTagResult = globalTagResult || "";
|
|
1858
|
-
}
|
|
1859
|
-
const latestTag = latestTagResult;
|
|
1860
|
-
let nextVersion;
|
|
1861
|
-
nextVersion = await calculateVersion(config, {
|
|
1862
|
-
latestTag,
|
|
1863
|
-
versionPrefix: formattedPrefix,
|
|
1864
|
-
branchPattern: config.branchPattern,
|
|
1865
|
-
baseBranch: config.baseBranch,
|
|
1866
|
-
prereleaseIdentifier: config.prereleaseIdentifier,
|
|
1867
|
-
path: pkgPath,
|
|
1868
|
-
name: packageName,
|
|
1869
|
-
type: config.type
|
|
1870
|
-
});
|
|
1871
|
-
if (!nextVersion) {
|
|
1872
|
-
log(`No version change needed for ${packageName}`, "info");
|
|
1873
|
-
return;
|
|
1874
|
-
}
|
|
1875
|
-
let changelogEntries = [];
|
|
1876
|
-
let revisionRange = "HEAD";
|
|
1877
|
-
try {
|
|
1878
|
-
if (latestTag) {
|
|
1879
|
-
try {
|
|
1880
|
-
execSync("git", ["rev-parse", "--verify", latestTag], {
|
|
1881
|
-
cwd: pkgPath,
|
|
1882
|
-
stdio: "ignore"
|
|
1883
|
-
});
|
|
1884
|
-
revisionRange = `${latestTag}..HEAD`;
|
|
1885
|
-
} catch {
|
|
1886
|
-
if (config.strictReachable) {
|
|
1887
|
-
throw new Error(
|
|
1888
|
-
`Cannot generate changelog: tag '${latestTag}' is not reachable from the current commit. When strictReachable is enabled, all tags must be reachable. To allow fallback to all commits, set strictReachable to false.`
|
|
1889
|
-
);
|
|
1890
|
-
}
|
|
1891
|
-
log(`Tag ${latestTag} doesn't exist, using all commits for changelog`, "debug");
|
|
1892
|
-
revisionRange = "HEAD";
|
|
1893
|
-
}
|
|
1894
|
-
} else {
|
|
1895
|
-
revisionRange = "HEAD";
|
|
1896
|
-
}
|
|
1897
|
-
changelogEntries = extractChangelogEntriesFromCommits(pkgPath, revisionRange);
|
|
1898
|
-
if (changelogEntries.length === 0) {
|
|
1899
|
-
changelogEntries = [
|
|
1900
|
-
{
|
|
1901
|
-
type: "changed",
|
|
1902
|
-
description: `Update version to ${nextVersion}`
|
|
1903
|
-
}
|
|
1904
|
-
];
|
|
1905
|
-
}
|
|
1906
|
-
} catch (error) {
|
|
1907
|
-
log(`Error extracting changelog entries: ${error instanceof Error ? error.message : String(error)}`, "warning");
|
|
1908
|
-
changelogEntries = [
|
|
1909
|
-
{
|
|
1910
|
-
type: "changed",
|
|
1911
|
-
description: `Update version to ${nextVersion}`
|
|
1912
|
-
}
|
|
1913
|
-
];
|
|
1914
|
-
}
|
|
1915
|
-
let repoUrl;
|
|
1916
|
-
try {
|
|
1917
|
-
const packageJsonPath2 = path6.join(pkgPath, "package.json");
|
|
1918
|
-
if (import_node_fs6.default.existsSync(packageJsonPath2)) {
|
|
1919
|
-
const packageJson = JSON.parse(import_node_fs6.default.readFileSync(packageJsonPath2, "utf8"));
|
|
1920
|
-
if (packageJson.repository) {
|
|
1921
|
-
if (typeof packageJson.repository === "string") {
|
|
1922
|
-
repoUrl = packageJson.repository;
|
|
1923
|
-
} else if (packageJson.repository.url) {
|
|
1924
|
-
repoUrl = packageJson.repository.url;
|
|
1925
|
-
}
|
|
1926
|
-
if (repoUrl?.startsWith("git+") && repoUrl?.endsWith(".git")) {
|
|
1927
|
-
repoUrl = repoUrl.substring(4, repoUrl.length - 4);
|
|
1928
|
-
}
|
|
1929
|
-
}
|
|
1930
|
-
}
|
|
1931
|
-
} catch (error) {
|
|
1932
|
-
log(
|
|
1933
|
-
`Could not determine repository URL for changelog links: ${error instanceof Error ? error.message : String(error)}`,
|
|
1934
|
-
"warning"
|
|
1935
|
-
);
|
|
1936
|
-
}
|
|
1937
|
-
addChangelogData({
|
|
1938
|
-
packageName,
|
|
1939
|
-
version: nextVersion,
|
|
1940
|
-
previousVersion: latestTag || null,
|
|
1941
|
-
revisionRange,
|
|
1942
|
-
repoUrl: repoUrl || null,
|
|
1943
|
-
entries: changelogEntries
|
|
1944
|
-
});
|
|
1945
|
-
const packageJsonPath = path6.join(pkgPath, "package.json");
|
|
1946
|
-
updatePackageVersion(packageJsonPath, nextVersion, dryRun);
|
|
1947
|
-
const filesToCommit = [packageJsonPath];
|
|
1948
|
-
const cargoFiles = updateCargoFiles(pkgPath, nextVersion, config.cargo, dryRun);
|
|
1949
|
-
filesToCommit.push(...cargoFiles);
|
|
1950
|
-
log(`Updated package ${packageName} to version ${nextVersion}`, "success");
|
|
1951
|
-
const tagName = formatTag(nextVersion, formattedPrefix, packageName, tagTemplate, config.packageSpecificTags);
|
|
1952
|
-
const commitMsg = formatCommitMessage(commitMessage, nextVersion, packageName);
|
|
1953
|
-
addTag(tagName);
|
|
1954
|
-
setCommitMessage(commitMsg);
|
|
1955
|
-
if (!dryRun) {
|
|
1956
|
-
log(`Version ${nextVersion} prepared (tag: ${tagName})`, "success");
|
|
1957
|
-
} else {
|
|
1958
|
-
log(`Would create tag: ${tagName}`, "info");
|
|
1959
|
-
}
|
|
1960
|
-
} catch (error) {
|
|
1961
|
-
if (BaseVersionError.isVersionError(error)) {
|
|
1962
|
-
log(`Single Strategy failed: ${error.message} (${error.code})`, "error");
|
|
1963
|
-
} else {
|
|
1964
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
1965
|
-
log(`Single Strategy failed: ${errorMessage}`, "error");
|
|
1966
|
-
}
|
|
1967
|
-
throw error;
|
|
1968
|
-
}
|
|
1969
|
-
};
|
|
1970
|
-
}
|
|
1971
|
-
function createAsyncStrategy(config) {
|
|
1972
|
-
const dependencies = {
|
|
1973
|
-
getLatestTag
|
|
1974
|
-
};
|
|
1975
|
-
const processorOptions = {
|
|
1976
|
-
skip: config.skip || [],
|
|
1977
|
-
versionPrefix: config.versionPrefix || "v",
|
|
1978
|
-
tagTemplate: config.tagTemplate,
|
|
1979
|
-
commitMessageTemplate: config.commitMessage || "",
|
|
1980
|
-
dryRun: config.dryRun || false,
|
|
1981
|
-
getLatestTag: dependencies.getLatestTag,
|
|
1982
|
-
fullConfig: config,
|
|
1983
|
-
// Extract common version configuration properties
|
|
1984
|
-
config: {
|
|
1985
|
-
branchPattern: config.branchPattern || [],
|
|
1986
|
-
baseBranch: config.baseBranch || "main",
|
|
1987
|
-
prereleaseIdentifier: config.prereleaseIdentifier,
|
|
1988
|
-
type: config.type
|
|
1989
|
-
}
|
|
1990
|
-
};
|
|
1991
|
-
const packageProcessor = new PackageProcessor(processorOptions);
|
|
1992
|
-
return async (packages, targets = []) => {
|
|
1993
|
-
try {
|
|
1994
|
-
let packagesToProcess = packages.packages;
|
|
1995
|
-
if (targets.length > 0) {
|
|
1996
|
-
const beforeCount = packagesToProcess.length;
|
|
1997
|
-
packagesToProcess = packagesToProcess.filter((pkg) => targets.includes(pkg.packageJson.name));
|
|
1998
|
-
log(
|
|
1999
|
-
`Runtime targets filter: ${beforeCount} \u2192 ${packagesToProcess.length} packages (${targets.join(", ")})`,
|
|
2000
|
-
"info"
|
|
2001
|
-
);
|
|
2002
|
-
}
|
|
2003
|
-
log(`Processing ${packagesToProcess.length} packages`, "info");
|
|
2004
|
-
const result = await packageProcessor.processPackages(packagesToProcess);
|
|
2005
|
-
if (result.updatedPackages.length === 0) {
|
|
2006
|
-
log("No packages required a version update.", "info");
|
|
2007
|
-
} else {
|
|
2008
|
-
const packageNames = result.updatedPackages.map((p) => p.name).join(", ");
|
|
2009
|
-
log(`Updated ${result.updatedPackages.length} package(s): ${packageNames}`, "success");
|
|
2010
|
-
if (result.tags.length > 0) {
|
|
2011
|
-
log(`Created ${result.tags.length} tag(s): ${result.tags.join(", ")}`, "success");
|
|
2012
|
-
}
|
|
2013
|
-
if (result.commitMessage) {
|
|
2014
|
-
log(`Created commit with message: "${result.commitMessage}"`, "success");
|
|
2015
|
-
}
|
|
2016
|
-
}
|
|
2017
|
-
} catch (error) {
|
|
2018
|
-
if (BaseVersionError.isVersionError(error)) {
|
|
2019
|
-
log(`Async Strategy failed: ${error.message} (${error.code})`, "error");
|
|
2020
|
-
} else {
|
|
2021
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
2022
|
-
log(`Async Strategy failed: ${errorMessage}`, "error");
|
|
2023
|
-
}
|
|
2024
|
-
throw error;
|
|
2025
|
-
}
|
|
2026
|
-
};
|
|
2027
|
-
}
|
|
2028
|
-
function createStrategy(config) {
|
|
2029
|
-
if (config.sync) {
|
|
2030
|
-
return createSyncStrategy(config);
|
|
2031
|
-
}
|
|
2032
|
-
return createAsyncStrategy(config);
|
|
2033
|
-
}
|
|
2034
|
-
function createStrategyMap(config) {
|
|
2035
|
-
return {
|
|
2036
|
-
sync: createSyncStrategy(config),
|
|
2037
|
-
single: createSingleStrategy(config),
|
|
2038
|
-
async: createAsyncStrategy(config)
|
|
2039
|
-
};
|
|
2040
|
-
}
|
|
2041
|
-
|
|
2042
|
-
// src/core/versionEngine.ts
|
|
2043
|
-
var VersionEngine = class {
|
|
2044
|
-
config;
|
|
2045
|
-
workspaceCache = null;
|
|
2046
|
-
strategies;
|
|
2047
|
-
currentStrategy;
|
|
2048
|
-
constructor(config, _jsonMode = false) {
|
|
2049
|
-
if (!config) {
|
|
2050
|
-
throw createVersionError("CONFIG_REQUIRED" /* CONFIG_REQUIRED */);
|
|
2051
|
-
}
|
|
2052
|
-
if (!config.preset) {
|
|
2053
|
-
config.preset = "conventional-commits";
|
|
2054
|
-
log("No preset specified, using default: conventional-commits", "warning");
|
|
2055
|
-
}
|
|
2056
|
-
this.config = config;
|
|
2057
|
-
this.strategies = createStrategyMap(config);
|
|
2058
|
-
this.currentStrategy = createStrategy(config);
|
|
2059
|
-
}
|
|
2060
|
-
/**
|
|
2061
|
-
* Get workspace packages information - with caching for performance
|
|
2062
|
-
*/
|
|
2063
|
-
async getWorkspacePackages() {
|
|
2064
|
-
try {
|
|
2065
|
-
if (this.workspaceCache) {
|
|
2066
|
-
return this.workspaceCache;
|
|
2067
|
-
}
|
|
2068
|
-
const pkgsResult = (0, import_get_packages.getPackagesSync)((0, import_node_process2.cwd)());
|
|
2069
|
-
if (!pkgsResult || !pkgsResult.packages) {
|
|
2070
|
-
throw createVersionError("PACKAGES_NOT_FOUND" /* PACKAGES_NOT_FOUND */);
|
|
2071
|
-
}
|
|
2072
|
-
if (!pkgsResult.root) {
|
|
2073
|
-
log("Root path is undefined in packages result, setting to current working directory", "warning");
|
|
2074
|
-
pkgsResult.root = (0, import_node_process2.cwd)();
|
|
2075
|
-
}
|
|
2076
|
-
if (this.config.packages && this.config.packages.length > 0) {
|
|
2077
|
-
const originalCount = pkgsResult.packages.length;
|
|
2078
|
-
const filteredPackages = filterPackagesByConfig(pkgsResult.packages, this.config.packages, pkgsResult.root);
|
|
2079
|
-
pkgsResult.packages = filteredPackages;
|
|
2080
|
-
log(
|
|
2081
|
-
`Filtered ${originalCount} workspace packages to ${filteredPackages.length} based on packages config`,
|
|
2082
|
-
"info"
|
|
2083
|
-
);
|
|
2084
|
-
if (filteredPackages.length === 0) {
|
|
2085
|
-
log("Warning: No packages matched the specified patterns in config.packages", "warning");
|
|
2086
|
-
}
|
|
2087
|
-
}
|
|
2088
|
-
this.workspaceCache = pkgsResult;
|
|
2089
|
-
return pkgsResult;
|
|
2090
|
-
} catch (error) {
|
|
2091
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
2092
|
-
log(`Failed to get packages information: ${errorMessage}`, "error");
|
|
2093
|
-
console.error(error);
|
|
2094
|
-
throw createVersionError("WORKSPACE_ERROR" /* WORKSPACE_ERROR */, errorMessage);
|
|
2095
|
-
}
|
|
2096
|
-
}
|
|
2097
|
-
/**
|
|
2098
|
-
* Run the current strategy
|
|
2099
|
-
* @param packages Workspace packages to process
|
|
2100
|
-
* @param targets Optional package targets to process (only used by async strategy)
|
|
2101
|
-
*/
|
|
2102
|
-
async run(packages, targets = []) {
|
|
2103
|
-
try {
|
|
2104
|
-
return this.currentStrategy(packages, targets);
|
|
2105
|
-
} catch (error) {
|
|
2106
|
-
if (error instanceof VersionError || error instanceof GitError) {
|
|
2107
|
-
log(`Version engine failed: ${error.message} (${error.code || "UNKNOWN"})`, "error");
|
|
2108
|
-
if (error instanceof GitError) {
|
|
2109
|
-
console.error("Git error details:");
|
|
2110
|
-
if (error.message.includes("Command failed:")) {
|
|
2111
|
-
const cmdOutput = error.message.split("Command failed:")[1];
|
|
2112
|
-
if (cmdOutput) {
|
|
2113
|
-
console.error("Command output:", cmdOutput.trim());
|
|
2114
|
-
}
|
|
2115
|
-
}
|
|
2116
|
-
}
|
|
2117
|
-
} else {
|
|
2118
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
2119
|
-
log(`Version engine failed: ${errorMessage}`, "error");
|
|
2120
|
-
if (error instanceof Error && error.stack) {
|
|
2121
|
-
console.error("Error stack trace:");
|
|
2122
|
-
console.error(error.stack);
|
|
2123
|
-
}
|
|
2124
|
-
}
|
|
2125
|
-
throw error;
|
|
2126
|
-
}
|
|
2127
|
-
}
|
|
2128
|
-
/**
|
|
2129
|
-
* Change the current strategy
|
|
2130
|
-
* @param strategyType The strategy type to use: 'sync', 'single', or 'async'
|
|
2131
|
-
*/
|
|
2132
|
-
setStrategy(strategyType) {
|
|
2133
|
-
this.currentStrategy = this.strategies[strategyType];
|
|
2134
|
-
}
|
|
2135
|
-
};
|
|
2136
|
-
|
|
2137
|
-
// src/cli.ts
|
|
2138
|
-
var import_meta = {};
|
|
2139
|
-
function getPackageVersion() {
|
|
2140
|
-
try {
|
|
2141
|
-
const packageJsonPath = import_node_path7.default.resolve(import_node_path7.default.dirname(import_meta.url.replace("file:", "")), "../package.json");
|
|
2142
|
-
const packageJsonContent = fs7.readFileSync(packageJsonPath, "utf-8");
|
|
2143
|
-
const packageJson = JSON.parse(packageJsonContent);
|
|
2144
|
-
return packageJson.version || "0.0.0";
|
|
2145
|
-
} catch (error) {
|
|
2146
|
-
console.error("Failed to read package version:", error);
|
|
2147
|
-
return "0.0.0";
|
|
2148
|
-
}
|
|
2149
|
-
}
|
|
2150
|
-
async function main() {
|
|
2151
|
-
const program = new import_commander.Command();
|
|
2152
|
-
program.name("releasekit-version").description("Version a package or packages based on conventional commits").version(getPackageVersion()).command("version", { isDefault: true }).description("Version a package or packages based on configuration").option("-c, --config <path>", "Path to config file (defaults to releasekit.config.json in current directory)").option("-d, --dry-run", "Dry run (no changes made)", false).option("-b, --bump <type>", "Specify bump type (patch|minor|major)").option("-p, --prerelease [identifier]", "Create prerelease version").option("-s, --sync", "Use synchronized versioning across all packages").option("-j, --json", "Output results as JSON", false).option("-t, --target <packages>", "Comma-delimited list of package names to target").option("--project-dir <path>", "Project directory to run commands in", process.cwd()).action(async (options) => {
|
|
2153
|
-
if (options.json) {
|
|
2154
|
-
enableJsonOutput(options.dryRun);
|
|
2155
|
-
}
|
|
2156
|
-
try {
|
|
2157
|
-
const originalCwd = process.cwd();
|
|
2158
|
-
if (options.projectDir && options.projectDir !== originalCwd) {
|
|
2159
|
-
try {
|
|
2160
|
-
process.chdir(options.projectDir);
|
|
2161
|
-
log(`Changed working directory to: ${options.projectDir}`, "debug");
|
|
2162
|
-
} catch (error) {
|
|
2163
|
-
throw new Error(
|
|
2164
|
-
`Failed to change to directory "${options.projectDir}": ${error instanceof Error ? error.message : String(error)}`
|
|
2165
|
-
);
|
|
2166
|
-
}
|
|
2167
|
-
}
|
|
2168
|
-
const config = loadConfig({ cwd: options.projectDir, configPath: options.config });
|
|
2169
|
-
log(`Loaded configuration from ${options.config || "releasekit.config.json"}`, "info");
|
|
2170
|
-
if (options.dryRun) config.dryRun = true;
|
|
2171
|
-
if (options.sync) config.sync = true;
|
|
2172
|
-
if (options.bump) config.type = options.bump;
|
|
2173
|
-
if (options.prerelease) {
|
|
2174
|
-
config.prereleaseIdentifier = options.prerelease === true ? "next" : options.prerelease;
|
|
2175
|
-
config.isPrerelease = true;
|
|
2176
|
-
}
|
|
2177
|
-
const cliTargets = options.target ? options.target.split(",").map((t) => t.trim()) : [];
|
|
2178
|
-
if (cliTargets.length > 0) {
|
|
2179
|
-
config.packages = cliTargets;
|
|
2180
|
-
log(`CLI targets specified: ${cliTargets.join(", ")}`, "info");
|
|
2181
|
-
}
|
|
2182
|
-
const engine = new VersionEngine(config, !!options.json);
|
|
2183
|
-
const pkgsResult = await engine.getWorkspacePackages();
|
|
2184
|
-
const resolvedCount = pkgsResult.packages.length;
|
|
2185
|
-
log(`Resolved ${resolvedCount} packages from workspace`, "debug");
|
|
2186
|
-
log(`Config packages: ${JSON.stringify(config.packages)}`, "debug");
|
|
2187
|
-
log(`Config sync: ${config.sync}`, "debug");
|
|
2188
|
-
if (config.sync) {
|
|
2189
|
-
log("Using sync versioning strategy.", "info");
|
|
2190
|
-
engine.setStrategy("sync");
|
|
2191
|
-
await engine.run(pkgsResult);
|
|
2192
|
-
} else if (resolvedCount === 1) {
|
|
2193
|
-
log("Using single package versioning strategy.", "info");
|
|
2194
|
-
if (cliTargets.length > 0) {
|
|
2195
|
-
log("--target flag is ignored for single package strategy.", "warning");
|
|
2196
|
-
}
|
|
2197
|
-
engine.setStrategy("single");
|
|
2198
|
-
await engine.run(pkgsResult);
|
|
2199
|
-
} else if (resolvedCount === 0) {
|
|
2200
|
-
throw new Error("No packages found in workspace");
|
|
2201
|
-
} else {
|
|
2202
|
-
log("Using async versioning strategy.", "info");
|
|
2203
|
-
if (cliTargets.length > 0) {
|
|
2204
|
-
log(`Targeting specific packages: ${cliTargets.join(", ")}`, "info");
|
|
2205
|
-
}
|
|
2206
|
-
engine.setStrategy("async");
|
|
2207
|
-
await engine.run(pkgsResult, cliTargets);
|
|
2208
|
-
}
|
|
2209
|
-
log("Versioning process completed.", "success");
|
|
2210
|
-
printJsonOutput();
|
|
2211
|
-
} catch (error) {
|
|
2212
|
-
const { BaseVersionError: BaseVersionError2 } = await Promise.resolve().then(() => (init_baseError(), baseError_exports));
|
|
2213
|
-
if (BaseVersionError2.isVersionError(error)) {
|
|
2214
|
-
error.logError();
|
|
2215
|
-
} else {
|
|
2216
|
-
log(`Error: ${error instanceof Error ? error.message : String(error)}`, "error");
|
|
2217
|
-
}
|
|
2218
|
-
process.exit(1);
|
|
2219
|
-
}
|
|
2220
|
-
});
|
|
2221
|
-
program.parse();
|
|
2222
|
-
}
|
|
2223
|
-
async function run() {
|
|
2224
|
-
await main();
|
|
2225
|
-
}
|
|
2226
|
-
main();
|
|
2227
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
2228
|
-
0 && (module.exports = {
|
|
2229
|
-
run
|
|
2230
|
-
});
|