@releasekit/version 0.4.0 → 0.5.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.
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  BaseVersionError
3
- } from "./chunk-2MN2VLZF.js";
3
+ } from "./chunk-Q3FHZORY.js";
4
4
  export {
5
5
  BaseVersionError
6
6
  };
@@ -1,7 +1,8 @@
1
1
  import {
2
2
  BaseVersionError,
3
- ReleaseKitError
4
- } from "./chunk-2MN2VLZF.js";
3
+ ReleaseKitError,
4
+ sanitizePackageName
5
+ } from "./chunk-Q3FHZORY.js";
5
6
  import {
6
7
  execAsync,
7
8
  execSync
@@ -129,7 +130,13 @@ var GitHubReleaseConfigSchema = z.object({
129
130
  * - 'generated': Use GitHub's auto-generated notes.
130
131
  * - 'none': No body.
131
132
  */
132
- body: z.enum(["auto", "releaseNotes", "changelog", "generated", "none"]).default("auto")
133
+ body: z.enum(["auto", "releaseNotes", "changelog", "generated", "none"]).default("auto"),
134
+ /**
135
+ * Template string for the GitHub release title when a package name is resolved.
136
+ * Available variables: ${packageName} (original scoped name), ${version} (e.g. "v1.0.0").
137
+ * Version-only tags (e.g. "v1.0.0") always use the tag as-is.
138
+ */
139
+ titleTemplate: z.string().default("${packageName}: ${version}")
133
140
  });
134
141
  var VerifyRegistryConfigSchema = z.object({
135
142
  enabled: z.boolean().default(true),
@@ -173,7 +180,8 @@ var PublishConfigSchema = z.object({
173
180
  draft: true,
174
181
  perPackage: true,
175
182
  prerelease: "auto",
176
- body: "auto"
183
+ body: "auto",
184
+ titleTemplate: "${packageName}: ${version}"
177
185
  }),
178
186
  verify: VerifyConfigSchema.default({
179
187
  npm: {
@@ -466,7 +474,7 @@ function createVersionError(code, details) {
466
474
  };
467
475
  const suggestions = {
468
476
  ["CONFIG_REQUIRED" /* CONFIG_REQUIRED */]: [
469
- "Create a version.config.json file in your project root",
477
+ "Create a releasekit.config.json file in your project root",
470
478
  "Check the documentation for configuration examples"
471
479
  ],
472
480
  ["PACKAGES_NOT_FOUND" /* PACKAGES_NOT_FOUND */]: [
@@ -480,14 +488,14 @@ function createVersionError(code, details) {
480
488
  "Ensure proper monorepo structure"
481
489
  ],
482
490
  ["INVALID_CONFIG" /* INVALID_CONFIG */]: [
483
- "Validate version.config.json syntax",
491
+ "Validate releasekit.config.json syntax",
484
492
  "Check configuration against schema",
485
493
  "Review documentation for valid configuration options"
486
494
  ],
487
495
  ["PACKAGE_NOT_FOUND" /* PACKAGE_NOT_FOUND */]: [
488
496
  "Verify package name spelling and case",
489
497
  "Check if package exists in workspace",
490
- "Review packages configuration in version.config.json"
498
+ "Review packages configuration in releasekit.config.json"
491
499
  ],
492
500
  ["VERSION_CALCULATION_ERROR" /* VERSION_CALCULATION_ERROR */]: [
493
501
  "Ensure git repository has commits",
@@ -632,7 +640,7 @@ function formatVersionPrefix(prefix) {
632
640
  return prefix.endsWith("/") ? prefix.slice(0, -1) : prefix;
633
641
  }
634
642
  function formatTag(version, prefix, packageName, template, packageSpecificTags) {
635
- const sanitizedPackageName = packageName?.startsWith("@") ? packageName.slice(1).replace(/\//g, "-") : packageName;
643
+ const sanitizedPackageName = packageName ? sanitizePackageName(packageName) : packageName;
636
644
  if (template?.includes("${packageName}") && !packageName) {
637
645
  log(
638
646
  `Warning: Your tagTemplate contains \${packageName} but no package name is available.
@@ -1147,13 +1155,12 @@ async function calculateVersion(config, options) {
1147
1155
  const hasNoTags = !latestTag || latestTag.trim() === "";
1148
1156
  const normalizedPrereleaseId = normalizePrereleaseIdentifier(prereleaseIdentifier, config);
1149
1157
  try {
1150
- let determineTagSearchPattern2 = function(packageName, prefix) {
1151
- if (!packageName) {
1152
- return prefix;
1153
- }
1154
- return `${packageName}@${prefix}`;
1155
- }, escapeRegExp3 = function(string) {
1156
- return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1158
+ let buildTagStripPattern2 = function(packageName, prefix) {
1159
+ if (!packageName) return escapeRegExp(prefix);
1160
+ const sanitized = sanitizePackageName(packageName);
1161
+ const escapedRaw = escapeRegExp(`${packageName}@${prefix}`);
1162
+ const escapedDash = escapeRegExp(`${sanitized}-${prefix}`);
1163
+ return `(?:${escapedRaw}|${escapedDash})`;
1157
1164
  }, getCurrentVersionFromSource2 = function() {
1158
1165
  if (!versionSource) {
1159
1166
  if (hasNoTags) {
@@ -1168,10 +1175,9 @@ async function calculateVersion(config, options) {
1168
1175
  }
1169
1176
  return versionSource.version;
1170
1177
  };
1171
- var determineTagSearchPattern = determineTagSearchPattern2, escapeRegExp2 = escapeRegExp3, getCurrentVersionFromSource = getCurrentVersionFromSource2;
1178
+ var buildTagStripPattern = buildTagStripPattern2, getCurrentVersionFromSource = getCurrentVersionFromSource2;
1172
1179
  const originalPrefix = versionPrefix || "";
1173
- const tagSearchPattern = determineTagSearchPattern2(name, originalPrefix);
1174
- const escapedTagPattern = escapeRegExp3(tagSearchPattern);
1180
+ const escapedTagPattern = buildTagStripPattern2(name, originalPrefix);
1175
1181
  let versionSource;
1176
1182
  if (pkgPath) {
1177
1183
  const packageDir = pkgPath || cwd();
@@ -1375,7 +1381,7 @@ function extractCommitsFromGitLog(projectDir, revisionRange, filterToPath) {
1375
1381
  const tagName = revisionRange.split("..")[0] || revisionRange;
1376
1382
  if (tagName.startsWith("v") && !tagName.includes("@")) {
1377
1383
  log(
1378
- `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}`,
1384
+ `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 releasekit.config.json to use: \${packageName}@\${prefix}\${version}`,
1379
1385
  "error"
1380
1386
  );
1381
1387
  } else {
@@ -1972,30 +1978,30 @@ function createSyncStrategy(config) {
1972
1978
  }
1973
1979
  ];
1974
1980
  }
1975
- addChangelogData({
1976
- packageName: mainPkgName || "monorepo",
1977
- version: nextVersion,
1978
- previousVersion: latestTag || null,
1979
- revisionRange,
1980
- repoUrl: null,
1981
- entries: changelogEntries
1982
- });
1983
- let tagPackageName = null;
1984
- if (config.packageSpecificTags && packages.packages.length === 1) {
1985
- tagPackageName = packages.packages[0].packageJson.name;
1986
- }
1987
1981
  const workspaceNames = updatedPackages.filter((n) => n !== "root");
1982
+ if (config.packageSpecificTags && workspaceNames.length > 0) {
1983
+ for (const pkgName of workspaceNames) {
1984
+ addChangelogData({
1985
+ packageName: pkgName,
1986
+ version: nextVersion,
1987
+ previousVersion: latestTag || null,
1988
+ revisionRange,
1989
+ repoUrl: null,
1990
+ entries: changelogEntries
1991
+ });
1992
+ }
1993
+ } else {
1994
+ addChangelogData({
1995
+ packageName: mainPkgName || "monorepo",
1996
+ version: nextVersion,
1997
+ previousVersion: latestTag || null,
1998
+ revisionRange,
1999
+ repoUrl: null,
2000
+ entries: changelogEntries
2001
+ });
2002
+ }
1988
2003
  const commitPackageName = workspaceNames.length > 0 ? workspaceNames.join(", ") : void 0;
1989
- const nextTag = formatTag(
1990
- nextVersion,
1991
- formattedPrefix,
1992
- tagPackageName,
1993
- // Only pass tagTemplate when we have a package name to substitute into it.
1994
- // In multi-package sync mode tagPackageName is null, so omit the template to
1995
- // avoid a spurious ${packageName} warning and a malformed tag like "-v1.0.0".
1996
- tagPackageName ? tagTemplate : void 0,
1997
- config.packageSpecificTags || false
1998
- );
2004
+ const nextTags = config.packageSpecificTags && workspaceNames.length > 0 ? workspaceNames.map((pkgName) => formatTag(nextVersion, formattedPrefix, pkgName, tagTemplate, true)) : [formatTag(nextVersion, formattedPrefix, null, void 0, false)];
1999
2005
  let formattedCommitMessage;
2000
2006
  const hasPackageNamePlaceholder = commitMessage.includes("${packageName}");
2001
2007
  if (commitPackageName === void 0 && !hasPackageNamePlaceholder) {
@@ -2006,12 +2012,14 @@ function createSyncStrategy(config) {
2006
2012
  formattedCommitMessage = formatCommitMessage(commitMessage, nextVersion, commitPackageName, void 0);
2007
2013
  }
2008
2014
  formattedCommitMessage = formattedCommitMessage.replace(/\s{2,}/g, " ").trim();
2009
- addTag(nextTag);
2015
+ for (const tag of nextTags) {
2016
+ addTag(tag);
2017
+ }
2010
2018
  setCommitMessage(formattedCommitMessage);
2011
2019
  if (!dryRun) {
2012
- log(`Version ${nextVersion} prepared (tag: ${nextTag})`, "success");
2020
+ log(`Version ${nextVersion} prepared (tags: ${nextTags.join(", ")})`, "success");
2013
2021
  } else {
2014
- log(`Would create tag: ${nextTag}`, "info");
2022
+ log(`Would create tags: ${nextTags.join(", ")}`, "info");
2015
2023
  }
2016
2024
  } catch (error) {
2017
2025
  if (BaseVersionError.isVersionError(error)) {
@@ -63,6 +63,9 @@ var ReleaseKitError = class _ReleaseKitError extends Error {
63
63
  return error2 instanceof _ReleaseKitError;
64
64
  }
65
65
  };
66
+ function sanitizePackageName(name) {
67
+ return name.startsWith("@") ? name.slice(1).replace(/\//g, "-") : name;
68
+ }
66
69
 
67
70
  // src/errors/baseError.ts
68
71
  var BaseVersionError = class _BaseVersionError extends ReleaseKitError {
@@ -81,5 +84,6 @@ var BaseVersionError = class _BaseVersionError extends ReleaseKitError {
81
84
  export {
82
85
  readPackageVersion,
83
86
  ReleaseKitError,
87
+ sanitizePackageName,
84
88
  BaseVersionError
85
89
  };
package/dist/cli.js CHANGED
@@ -5,10 +5,10 @@ import {
5
5
  loadConfig,
6
6
  log,
7
7
  printJsonOutput
8
- } from "./chunk-ZTFI7TXV.js";
8
+ } from "./chunk-MRXNAFME.js";
9
9
  import {
10
10
  readPackageVersion
11
- } from "./chunk-2MN2VLZF.js";
11
+ } from "./chunk-Q3FHZORY.js";
12
12
  import "./chunk-LMPZV35Z.js";
13
13
 
14
14
  // src/cli.ts
@@ -76,7 +76,7 @@ function createVersionCommand() {
76
76
  log("Versioning process completed.", "success");
77
77
  printJsonOutput();
78
78
  } catch (error) {
79
- const { BaseVersionError } = await import("./baseError-FARJUY5U.js");
79
+ const { BaseVersionError } = await import("./baseError-DQHIJACF.js");
80
80
  if (BaseVersionError.isVersionError(error)) {
81
81
  error.logError();
82
82
  } else {
package/dist/index.js CHANGED
@@ -11,10 +11,10 @@ import {
11
11
  flushPendingWrites,
12
12
  getJsonData,
13
13
  loadConfig
14
- } from "./chunk-ZTFI7TXV.js";
14
+ } from "./chunk-MRXNAFME.js";
15
15
  import {
16
16
  BaseVersionError
17
- } from "./chunk-2MN2VLZF.js";
17
+ } from "./chunk-Q3FHZORY.js";
18
18
  import "./chunk-LMPZV35Z.js";
19
19
  export {
20
20
  BaseVersionError,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@releasekit/version",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "Semantic versioning based on Git history and conventional commits",
5
5
  "type": "module",
6
6
  "module": "./dist/index.js",
@@ -41,7 +41,8 @@
41
41
  "files": [
42
42
  "dist",
43
43
  "docs",
44
- "version.schema.json"
44
+ "README.md",
45
+ "LICENSE"
45
46
  ],
46
47
  "publishConfig": {
47
48
  "access": "public"
@@ -72,8 +73,8 @@
72
73
  "tsup": "^8.5.1",
73
74
  "typescript": "^5.9.3",
74
75
  "vitest": "^4.1.0",
75
- "@releasekit/core": "0.0.0",
76
- "@releasekit/config": "0.0.0"
76
+ "@releasekit/config": "0.0.0",
77
+ "@releasekit/core": "0.0.0"
77
78
  },
78
79
  "engines": {
79
80
  "node": ">=20"
@@ -84,6 +85,7 @@
84
85
  "clean": "rm -rf dist coverage .turbo",
85
86
  "test": "vitest run --dir test/unit",
86
87
  "test:unit": "vitest run --coverage --dir test/unit",
88
+ "test:integration": "VITEST_INTEGRATION=true vitest run --dir test/integration",
87
89
  "test:coverage": "vitest run --coverage --dir test/unit",
88
90
  "lint": "biome check .",
89
91
  "typecheck": "tsc --noEmit"
@@ -1,148 +0,0 @@
1
- {
2
- "$schema": "http://json-schema.org/draft-07/schema#",
3
- "type": "object",
4
- "properties": {
5
- "$schema": {
6
- "type": "string",
7
- "description": "JSON schema reference"
8
- },
9
- "versionPrefix": {
10
- "type": "string",
11
- "minLength": 1,
12
- "description": "The prefix used for Git tags",
13
- "default": "v"
14
- },
15
- "tagTemplate": {
16
- "type": "string",
17
- "minLength": 1,
18
- "default": "${prefix}${version}",
19
- "description": "Template for formatting Git tags"
20
- },
21
- "packageSpecificTags": {
22
- "type": "boolean",
23
- "default": false,
24
- "description": "Whether to enable package-specific tagging behaviour"
25
- },
26
- "preset": {
27
- "type": "string",
28
- "enum": ["angular", "conventional"],
29
- "default": "angular",
30
- "description": "The commit message convention preset"
31
- },
32
- "changelogFormat": {
33
- "type": "string",
34
- "enum": ["keep-a-changelog", "angular"],
35
- "default": "keep-a-changelog",
36
- "description": "The format to use for generating changelogs"
37
- },
38
- "baseBranch": {
39
- "type": "string",
40
- "minLength": 1,
41
- "description": "The main branch for versioning",
42
- "default": "main"
43
- },
44
- "sync": {
45
- "type": "boolean",
46
- "default": false,
47
- "description": "Whether packages should be versioned together"
48
- },
49
- "packages": {
50
- "type": "array",
51
- "items": {
52
- "type": "string",
53
- "minLength": 1
54
- },
55
- "default": [],
56
- "description": "Array of package names or patterns that determines which packages will be processed for versioning. When specified, only packages matching these patterns will be versioned. When empty or not specified, all workspace packages will be processed. Supports exact names (e.g., '@scope/package-a'), scope wildcards (e.g., '@scope/*'), path patterns (e.g., 'packages/**/*', 'examples/**'), and global wildcards (e.g., '*')."
57
- },
58
- "mainPackage": {
59
- "type": "string",
60
- "minLength": 1,
61
- "description": "The package to use for version determination"
62
- },
63
- "versionStrategy": {
64
- "type": "string",
65
- "enum": ["branchPattern", "commitMessage"],
66
- "default": "commitMessage",
67
- "description": "How to determine version changes"
68
- },
69
- "branchPattern": {
70
- "type": "array",
71
- "items": {
72
- "type": "string",
73
- "minLength": 1
74
- },
75
- "default": ["major:", "minor:", "patch:"],
76
- "description": "Patterns to match against branch names"
77
- },
78
- "updateInternalDependencies": {
79
- "type": "string",
80
- "enum": ["major", "minor", "patch", "no-internal-update"],
81
- "default": "patch",
82
- "description": "How to update dependencies between packages"
83
- },
84
- "skip": {
85
- "type": "array",
86
- "items": {
87
- "type": "string",
88
- "minLength": 1
89
- },
90
- "default": [],
91
- "description": "Packages to exclude from versioning. Supports exact package names (e.g., '@internal/docs'), scope wildcards (e.g., '@internal/*'), and path patterns (e.g., 'packages/**/test-*', 'examples/**/*')"
92
- },
93
- "commitMessage": {
94
- "type": "string",
95
- "minLength": 1,
96
- "default": "chore: release ${packageName} v${version}",
97
- "description": "Template for commit messages. Available variables: ${version}, ${packageName}, ${scope}"
98
- },
99
- "prereleaseIdentifier": {
100
- "type": "string",
101
- "minLength": 1,
102
- "description": "Identifier for prerelease versions"
103
- },
104
- "skipHooks": {
105
- "type": "boolean",
106
- "default": false,
107
- "description": "Whether to skip Git hooks"
108
- },
109
- "writeChangelog": {
110
- "type": "boolean",
111
- "default": true,
112
- "description": "Whether to write changelog files to disk"
113
- },
114
- "strictReachable": {
115
- "type": "boolean",
116
- "default": false,
117
- "description": "Only use reachable tags (no fallback to unreachable tags)"
118
- },
119
- "mismatchStrategy": {
120
- "type": "string",
121
- "enum": ["error", "warn", "ignore", "prefer-package", "prefer-git"],
122
- "default": "error",
123
- "description": "How to handle version mismatches between git tags and package.json. 'error' throws and stops execution (default), 'warn' logs a warning but continues, 'prefer-package' uses package.json version, 'prefer-git' uses git tag, 'ignore' silently continues."
124
- },
125
- "cargo": {
126
- "type": "object",
127
- "properties": {
128
- "enabled": {
129
- "type": "boolean",
130
- "default": true,
131
- "description": "Whether to enable Cargo.toml version handling"
132
- },
133
- "paths": {
134
- "type": "array",
135
- "items": {
136
- "type": "string",
137
- "minLength": 1
138
- },
139
- "description": "Specify directories to search for Cargo.toml files"
140
- }
141
- },
142
- "additionalProperties": false,
143
- "description": "Configuration options for Rust/Cargo support"
144
- }
145
- },
146
- "required": ["versionPrefix", "preset", "updateInternalDependencies"],
147
- "additionalProperties": false
148
- }