@williamthorsen/release-kit 2.3.0 → 2.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/cliff.toml.template +3 -1
- package/dist/esm/.cache +1 -1
- package/dist/esm/determineBumpFromCommits.d.ts +7 -0
- package/dist/esm/determineBumpFromCommits.js +26 -0
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/index.js +2 -1
- package/dist/esm/parseCommitMessage.d.ts +1 -0
- package/dist/esm/parseCommitMessage.js +11 -1
- package/dist/esm/releasePrepare.js +9 -6
- package/dist/esm/releasePrepareMono.js +9 -6
- package/dist/esm/reportPrepare.js +17 -0
- package/dist/esm/types.d.ts +1 -0
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [release-kit-v2.3.2] - 2026-03-28
|
|
6
|
+
|
|
7
|
+
### Bug fixes
|
|
8
|
+
|
|
9
|
+
- #71 release-kit|fix: Prevent unparseable commits from being silently dropped (#76)
|
|
10
|
+
|
|
11
|
+
Prevents `releasePrepareMono` and `releasePrepare` from silently skipping components whose commits have unparseable messages. Adds ticket-prefix stripping to `parseCommitMessage` (mirroring cliff.toml's `commit_preprocessors`), a patch-floor safety net when commits exist but none parse, and unparseable-commit reporting in `reportPrepare`.
|
|
12
|
+
|
|
5
13
|
## [release-kit-v2.3.0] - 2026-03-28
|
|
6
14
|
|
|
7
15
|
### Features
|
package/cliff.toml.template
CHANGED
|
@@ -39,7 +39,9 @@ filter_unconventional = false
|
|
|
39
39
|
split_commits = false
|
|
40
40
|
# regex for preprocessing the commit messages
|
|
41
41
|
commit_preprocessors = [
|
|
42
|
-
# Strip
|
|
42
|
+
# Strip GitHub-style issue prefixes like "#8 " or "#123 "
|
|
43
|
+
{ pattern = '^#\d+\s+', replace = "" },
|
|
44
|
+
# Strip Jira-style ticket prefixes like "TOOL-123 " or "AFG-456 "
|
|
43
45
|
{ pattern = '^[A-Z]+-\d+\s+', replace = "" },
|
|
44
46
|
]
|
|
45
47
|
# regex for parsing and grouping commits
|
package/dist/esm/.cache
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
894421aa6cf2eb13518310f0bb75d5751a6a68ae1fcb068600b25ed30eea9b67
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Commit, ReleaseType, VersionPatterns, WorkTypeConfig } from './types.ts';
|
|
2
|
+
export interface BumpDetermination {
|
|
3
|
+
releaseType: ReleaseType | undefined;
|
|
4
|
+
parsedCommitCount: number;
|
|
5
|
+
unparseableCommits: Commit[] | undefined;
|
|
6
|
+
}
|
|
7
|
+
export declare function determineBumpFromCommits(commits: Commit[], workTypes: Record<string, WorkTypeConfig>, versionPatterns: VersionPatterns, workspaceAliases: Record<string, string> | undefined): BumpDetermination;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { determineBumpType } from "./determineBumpType.js";
|
|
2
|
+
import { parseCommitMessage } from "./parseCommitMessage.js";
|
|
3
|
+
function determineBumpFromCommits(commits, workTypes, versionPatterns, workspaceAliases) {
|
|
4
|
+
const parsedCommits = [];
|
|
5
|
+
const unparseable = [];
|
|
6
|
+
for (const commit of commits) {
|
|
7
|
+
const parsed = parseCommitMessage(commit.message, commit.hash, workTypes, workspaceAliases);
|
|
8
|
+
if (parsed === void 0) {
|
|
9
|
+
unparseable.push(commit);
|
|
10
|
+
} else {
|
|
11
|
+
parsedCommits.push(parsed);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
let releaseType = determineBumpType(parsedCommits, workTypes, versionPatterns);
|
|
15
|
+
if (releaseType === void 0 && commits.length > 0) {
|
|
16
|
+
releaseType = "patch";
|
|
17
|
+
}
|
|
18
|
+
return {
|
|
19
|
+
releaseType,
|
|
20
|
+
parsedCommitCount: parsedCommits.length,
|
|
21
|
+
unparseableCommits: unparseable.length > 0 ? unparseable : void 0
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
export {
|
|
25
|
+
determineBumpFromCommits
|
|
26
|
+
};
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -16,7 +16,7 @@ export { determineBumpType } from './determineBumpType.ts';
|
|
|
16
16
|
export { discoverWorkspaces } from './discoverWorkspaces.ts';
|
|
17
17
|
export { generateChangelog, generateChangelogs } from './generateChangelogs.ts';
|
|
18
18
|
export { getCommitsSinceTarget } from './getCommitsSinceTarget.ts';
|
|
19
|
-
export { parseCommitMessage } from './parseCommitMessage.ts';
|
|
19
|
+
export { COMMIT_PREPROCESSOR_PATTERNS, parseCommitMessage } from './parseCommitMessage.ts';
|
|
20
20
|
export { RELEASE_TAGS_FILE, writeReleaseTags } from './prepareCommand.ts';
|
|
21
21
|
export { publish } from './publish.ts';
|
|
22
22
|
export { releasePrepare } from './releasePrepare.ts';
|
package/dist/esm/index.js
CHANGED
|
@@ -8,7 +8,7 @@ import { determineBumpType } from "./determineBumpType.js";
|
|
|
8
8
|
import { discoverWorkspaces } from "./discoverWorkspaces.js";
|
|
9
9
|
import { generateChangelog, generateChangelogs } from "./generateChangelogs.js";
|
|
10
10
|
import { getCommitsSinceTarget } from "./getCommitsSinceTarget.js";
|
|
11
|
-
import { parseCommitMessage } from "./parseCommitMessage.js";
|
|
11
|
+
import { COMMIT_PREPROCESSOR_PATTERNS, parseCommitMessage } from "./parseCommitMessage.js";
|
|
12
12
|
import { RELEASE_TAGS_FILE, writeReleaseTags } from "./prepareCommand.js";
|
|
13
13
|
import { publish } from "./publish.js";
|
|
14
14
|
import { releasePrepare } from "./releasePrepare.js";
|
|
@@ -16,6 +16,7 @@ import { releasePrepareMono } from "./releasePrepareMono.js";
|
|
|
16
16
|
import { reportPrepare } from "./reportPrepare.js";
|
|
17
17
|
import { resolveReleaseTags } from "./resolveReleaseTags.js";
|
|
18
18
|
export {
|
|
19
|
+
COMMIT_PREPROCESSOR_PATTERNS,
|
|
19
20
|
DEFAULT_VERSION_PATTERNS,
|
|
20
21
|
DEFAULT_WORK_TYPES,
|
|
21
22
|
RELEASE_TAGS_FILE,
|
|
@@ -1,2 +1,3 @@
|
|
|
1
1
|
import type { ParsedCommit, WorkTypeConfig } from './types.ts';
|
|
2
|
+
export declare const COMMIT_PREPROCESSOR_PATTERNS: readonly RegExp[];
|
|
2
3
|
export declare function parseCommitMessage(message: string, hash: string, workTypes: Record<string, WorkTypeConfig>, workspaceAliases?: Record<string, string>): ParsedCommit | undefined;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
const COMMIT_PREPROCESSOR_PATTERNS = [/^#\d+\s+/, /^[A-Z]+-\d+\s+/];
|
|
1
2
|
function parseCommitMessage(message, hash, workTypes, workspaceAliases) {
|
|
2
|
-
const
|
|
3
|
+
const stripped = stripTicketPrefix(message);
|
|
4
|
+
const match = stripped.match(/^(?:([^|]+)\|)?(\w+)(!)?:\s*(.*)$/);
|
|
3
5
|
if (!match) {
|
|
4
6
|
return void 0;
|
|
5
7
|
}
|
|
@@ -41,6 +43,14 @@ function resolveType(rawType, workTypes) {
|
|
|
41
43
|
}
|
|
42
44
|
return void 0;
|
|
43
45
|
}
|
|
46
|
+
function stripTicketPrefix(message) {
|
|
47
|
+
let result = message;
|
|
48
|
+
for (const pattern of COMMIT_PREPROCESSOR_PATTERNS) {
|
|
49
|
+
result = result.replace(pattern, "");
|
|
50
|
+
}
|
|
51
|
+
return result;
|
|
52
|
+
}
|
|
44
53
|
export {
|
|
54
|
+
COMMIT_PREPROCESSOR_PATTERNS,
|
|
45
55
|
parseCommitMessage
|
|
46
56
|
};
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { execSync } from "node:child_process";
|
|
2
2
|
import { bumpAllVersions } from "./bumpAllVersions.js";
|
|
3
3
|
import { DEFAULT_VERSION_PATTERNS, DEFAULT_WORK_TYPES } from "./defaults.js";
|
|
4
|
-
import {
|
|
4
|
+
import { determineBumpFromCommits } from "./determineBumpFromCommits.js";
|
|
5
5
|
import { generateChangelogs } from "./generateChangelogs.js";
|
|
6
6
|
import { getCommitsSinceTarget } from "./getCommitsSinceTarget.js";
|
|
7
7
|
import { hasPrettierConfig } from "./hasPrettierConfig.js";
|
|
8
|
-
import { parseCommitMessage } from "./parseCommitMessage.js";
|
|
9
8
|
function releasePrepare(config, options) {
|
|
10
9
|
const { dryRun, bumpOverride } = options;
|
|
11
10
|
const workTypes = config.workTypes ?? { ...DEFAULT_WORK_TYPES };
|
|
@@ -13,10 +12,12 @@ function releasePrepare(config, options) {
|
|
|
13
12
|
const { tag, commits } = getCommitsSinceTarget(config.tagPrefix);
|
|
14
13
|
let releaseType;
|
|
15
14
|
let parsedCommitCount;
|
|
15
|
+
let unparseableCommits;
|
|
16
16
|
if (bumpOverride === void 0) {
|
|
17
|
-
const
|
|
18
|
-
parsedCommitCount =
|
|
19
|
-
|
|
17
|
+
const determination = determineBumpFromCommits(commits, workTypes, versionPatterns, config.workspaceAliases);
|
|
18
|
+
parsedCommitCount = determination.parsedCommitCount;
|
|
19
|
+
unparseableCommits = determination.unparseableCommits;
|
|
20
|
+
releaseType = determination.releaseType;
|
|
20
21
|
} else {
|
|
21
22
|
releaseType = bumpOverride;
|
|
22
23
|
}
|
|
@@ -28,6 +29,7 @@ function releasePrepare(config, options) {
|
|
|
28
29
|
previousTag: tag,
|
|
29
30
|
commitCount: commits.length,
|
|
30
31
|
parsedCommitCount,
|
|
32
|
+
unparseableCommits,
|
|
31
33
|
bumpedFiles: [],
|
|
32
34
|
changelogFiles: [],
|
|
33
35
|
skipReason: "No release-worthy changes found. Skipping."
|
|
@@ -70,7 +72,8 @@ function releasePrepare(config, options) {
|
|
|
70
72
|
newVersion: bump.newVersion,
|
|
71
73
|
tag: newTag,
|
|
72
74
|
bumpedFiles: bump.files,
|
|
73
|
-
changelogFiles
|
|
75
|
+
changelogFiles,
|
|
76
|
+
unparseableCommits
|
|
74
77
|
}
|
|
75
78
|
],
|
|
76
79
|
tags: [newTag],
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { execSync } from "node:child_process";
|
|
2
2
|
import { bumpAllVersions } from "./bumpAllVersions.js";
|
|
3
3
|
import { DEFAULT_VERSION_PATTERNS, DEFAULT_WORK_TYPES } from "./defaults.js";
|
|
4
|
-
import {
|
|
4
|
+
import { determineBumpFromCommits } from "./determineBumpFromCommits.js";
|
|
5
5
|
import { generateChangelog } from "./generateChangelogs.js";
|
|
6
6
|
import { getCommitsSinceTarget } from "./getCommitsSinceTarget.js";
|
|
7
7
|
import { hasPrettierConfig } from "./hasPrettierConfig.js";
|
|
8
|
-
import { parseCommitMessage } from "./parseCommitMessage.js";
|
|
9
8
|
function releasePrepareMono(config, options) {
|
|
10
9
|
const { dryRun, force, bumpOverride } = options;
|
|
11
10
|
const workTypes = config.workTypes ?? { ...DEFAULT_WORK_TYPES };
|
|
@@ -31,10 +30,12 @@ function releasePrepareMono(config, options) {
|
|
|
31
30
|
}
|
|
32
31
|
let releaseType;
|
|
33
32
|
let parsedCommitCount;
|
|
33
|
+
let unparseableCommits;
|
|
34
34
|
if (bumpOverride === void 0) {
|
|
35
|
-
const
|
|
36
|
-
parsedCommitCount =
|
|
37
|
-
|
|
35
|
+
const determination = determineBumpFromCommits(commits, workTypes, versionPatterns, config.workspaceAliases);
|
|
36
|
+
parsedCommitCount = determination.parsedCommitCount;
|
|
37
|
+
unparseableCommits = determination.unparseableCommits;
|
|
38
|
+
releaseType = determination.releaseType;
|
|
38
39
|
} else {
|
|
39
40
|
releaseType = bumpOverride;
|
|
40
41
|
}
|
|
@@ -45,6 +46,7 @@ function releasePrepareMono(config, options) {
|
|
|
45
46
|
previousTag: tag,
|
|
46
47
|
commitCount: commits.length,
|
|
47
48
|
parsedCommitCount,
|
|
49
|
+
unparseableCommits,
|
|
48
50
|
bumpedFiles: [],
|
|
49
51
|
changelogFiles: [],
|
|
50
52
|
skipReason: `No release-worthy changes for ${name} ${since}. Skipping.`
|
|
@@ -72,7 +74,8 @@ function releasePrepareMono(config, options) {
|
|
|
72
74
|
newVersion: bump.newVersion,
|
|
73
75
|
tag: newTag,
|
|
74
76
|
bumpedFiles: bump.files,
|
|
75
|
-
changelogFiles
|
|
77
|
+
changelogFiles,
|
|
78
|
+
unparseableCommits
|
|
76
79
|
});
|
|
77
80
|
}
|
|
78
81
|
const formatCommandStr = config.formatCommand ?? (hasPrettierConfig() ? "npx prettier --write" : void 0);
|
|
@@ -17,6 +17,7 @@ function formatSingleComponent(result) {
|
|
|
17
17
|
if (component.parsedCommitCount !== void 0) {
|
|
18
18
|
lines.push(dim(` Parsed ${component.parsedCommitCount} typed commits`));
|
|
19
19
|
}
|
|
20
|
+
formatUnparseableWarning(lines, component);
|
|
20
21
|
if (component.status === "skipped") {
|
|
21
22
|
lines.push(`\u23ED\uFE0F ${component.skipReason ?? "Skipped"}`);
|
|
22
23
|
return lines.join("\n");
|
|
@@ -56,6 +57,7 @@ ${sectionHeader(component.name)}`);
|
|
|
56
57
|
if (component.parsedCommitCount !== void 0) {
|
|
57
58
|
lines.push(dim(` Parsed ${component.parsedCommitCount} typed commits`));
|
|
58
59
|
}
|
|
60
|
+
formatUnparseableWarning(lines, component, " ");
|
|
59
61
|
if (component.parsedCommitCount === void 0 && component.releaseType !== void 0) {
|
|
60
62
|
lines.push(` Using bump override: ${component.releaseType}`);
|
|
61
63
|
}
|
|
@@ -103,6 +105,21 @@ function formatChangelogFiles(lines, component, dryRun, indent = "") {
|
|
|
103
105
|
}
|
|
104
106
|
}
|
|
105
107
|
}
|
|
108
|
+
function formatUnparseableWarning(lines, component, indent = "") {
|
|
109
|
+
const unparseable = component.unparseableCommits;
|
|
110
|
+
if (unparseable === void 0 || unparseable.length === 0) {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
const count = unparseable.length;
|
|
114
|
+
const isPatchFloor = component.parsedCommitCount === 0;
|
|
115
|
+
const suffix = isPatchFloor ? " (defaulting to patch bump)" : "";
|
|
116
|
+
lines.push(`${indent} \u26A0\uFE0F ${count} commit${count === 1 ? "" : "s"} could not be parsed${suffix}`);
|
|
117
|
+
for (const commit of unparseable) {
|
|
118
|
+
const shortHash = commit.hash.slice(0, 7);
|
|
119
|
+
const truncatedMessage = commit.message.length > 72 ? `${commit.message.slice(0, 69)}...` : commit.message;
|
|
120
|
+
lines.push(`${indent} \xB7 ${shortHash} ${truncatedMessage}`);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
106
123
|
function formatFormatCommand(lines, result) {
|
|
107
124
|
if (result.formatCommand === void 0) {
|
|
108
125
|
return;
|
package/dist/esm/types.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@williamthorsen/release-kit",
|
|
3
|
-
"version": "2.3.
|
|
3
|
+
"version": "2.3.2",
|
|
4
4
|
"description": "Version-bumping and changelog-generation toolkit for release workflows",
|
|
5
5
|
"keywords": [],
|
|
6
6
|
"homepage": "https://github.com/williamthorsen/node-monorepo-tools/tree/main/packages/release-kit#readme",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"glob": "13.0.6",
|
|
35
35
|
"jiti": "2.6.1",
|
|
36
36
|
"js-yaml": "4.1.1",
|
|
37
|
-
"@williamthorsen/node-monorepo-core": "0.2.
|
|
37
|
+
"@williamthorsen/node-monorepo-core": "0.2.1"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@types/js-yaml": "4.0.9",
|