@williamthorsen/release-kit 4.6.0 → 4.7.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/CHANGELOG.md +8 -0
- package/cliff.toml.template +21 -19
- package/dist/esm/.cache +1 -1
- package/dist/esm/createGithubRelease.js +6 -0
- package/dist/esm/parseCommitMessage.js +1 -1
- package/dist/esm/version.d.ts +1 -1
- package/dist/esm/version.js +1 -1
- package/package.json +1 -1
- package/dist/esm/init/prompt.d.ts +0 -4
- package/dist/esm/init/prompt.js +0 -19
- package/dist/esm/runReleasePrepare.d.ts +0 -10
- package/dist/esm/runReleasePrepare.js +0 -125
- package/dist/esm/sync-labels/scaffold.d.ts +0 -6
- package/dist/esm/sync-labels/scaffold.js +0 -25
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-v4.7.0] - 2026-04-16
|
|
6
|
+
|
|
7
|
+
### Features
|
|
8
|
+
|
|
9
|
+
- Support ## as synthetic ticket prefix in changelogs
|
|
10
|
+
|
|
11
|
+
Commits prefixed with `##` are now included in changelogs without requiring a ticket ID. This supports ad-hoc changes made during interactive sessions where creating a ticket and PR adds undesired overhead.
|
|
12
|
+
|
|
5
13
|
## [release-kit-v4.6.0] - 2026-04-15
|
|
6
14
|
|
|
7
15
|
### Features
|
package/cliff.toml.template
CHANGED
|
@@ -5,9 +5,11 @@
|
|
|
5
5
|
# Examples:
|
|
6
6
|
# #19 rdy|feat: Add utility functions for common check patterns (#26)
|
|
7
7
|
# AFG-42 panel|fix: Fix button layout (#73)
|
|
8
|
+
# ## feat: Quick utility added during interactive session
|
|
8
9
|
#
|
|
9
|
-
# Only ticketed commits (leading #NN
|
|
10
|
+
# Only ticketed commits (leading #NN, PROJ-NN, or ##) are included.
|
|
10
11
|
# Unticketed maintenance commits (deps upgrades, tooling tweaks) are skipped.
|
|
12
|
+
# Use ## as a synthetic ticket prefix for ad-hoc commits that belong in the changelog.
|
|
11
13
|
|
|
12
14
|
[changelog]
|
|
13
15
|
header = """
|
|
@@ -55,27 +57,27 @@ filter_unconventional = false
|
|
|
55
57
|
split_commits = false
|
|
56
58
|
commit_preprocessors = []
|
|
57
59
|
# Require a ticket-ID prefix for inclusion.
|
|
58
|
-
# Supported prefixes: "#123 ", "#123-1 ", "#123.1 ", "TOOL-123 "
|
|
60
|
+
# Supported prefixes: "#123 ", "#123-1 ", "#123.1 ", "TOOL-123 ", "## "
|
|
59
61
|
commit_parsers = [
|
|
60
62
|
{ message = "^release:", skip = true },
|
|
61
63
|
{ message = "^Merge", skip = true },
|
|
62
|
-
{ message = "^(\\#\\d+([.\\-]\\d+)
|
|
63
|
-
{ message = "^(\\#\\d+([.\\-]\\d+)
|
|
64
|
-
{ message = "^(\\#\\d+([.\\-]\\d+)
|
|
65
|
-
{ message = "^(\\#\\d+([.\\-]\\d+)
|
|
66
|
-
{ message = "^(\\#\\d+([.\\-]\\d+)
|
|
67
|
-
{ message = "^(\\#\\d+([.\\-]\\d+)
|
|
68
|
-
{ message = "^(\\#\\d+([.\\-]\\d+)
|
|
69
|
-
{ message = "^(\\#\\d+([.\\-]\\d+)
|
|
70
|
-
{ message = "^(\\#\\d+([.\\-]\\d+)
|
|
71
|
-
{ message = "^(\\#\\d+([.\\-]\\d+)
|
|
72
|
-
{ message = "^(\\#\\d+([.\\-]\\d+)
|
|
73
|
-
{ message = "^(\\#\\d+([.\\-]\\d+)
|
|
74
|
-
{ message = "^(\\#\\d+([.\\-]\\d+)
|
|
75
|
-
{ message = "^(\\#\\d+([.\\-]\\d+)
|
|
76
|
-
{ message = "^(\\#\\d+([.\\-]\\d+)
|
|
77
|
-
{ message = "^(\\#\\d+([.\\-]\\d+)
|
|
78
|
-
{ message = "^(\\#\\d+([.\\-]\\d+)
|
|
64
|
+
{ message = "^(\\#\\d+([.\\-]\\d+)?|\\#\\#|[A-Z]+-\\d+)\\s+([\\w-]+\\|)?bugfix(!)?:", group = "Bug fixes" },
|
|
65
|
+
{ message = "^(\\#\\d+([.\\-]\\d+)?|\\#\\#|[A-Z]+-\\d+)\\s+([\\w-]+\\|)?ci(!)?:", group = "CI" },
|
|
66
|
+
{ message = "^(\\#\\d+([.\\-]\\d+)?|\\#\\#|[A-Z]+-\\d+)\\s+([\\w-]+\\|)?deprecate(!)?:", group = "Deprecated" },
|
|
67
|
+
{ message = "^(\\#\\d+([.\\-]\\d+)?|\\#\\#|[A-Z]+-\\d+)\\s+([\\w-]+\\|)?deps?(!)?:", group = "Dependencies" },
|
|
68
|
+
{ message = "^(\\#\\d+([.\\-]\\d+)?|\\#\\#|[A-Z]+-\\d+)\\s+([\\w-]+\\|)?docs?(!)?:", group = "Documentation" },
|
|
69
|
+
{ message = "^(\\#\\d+([.\\-]\\d+)?|\\#\\#|[A-Z]+-\\d+)\\s+([\\w-]+\\|)?feat(!)?:", group = "Features" },
|
|
70
|
+
{ message = "^(\\#\\d+([.\\-]\\d+)?|\\#\\#|[A-Z]+-\\d+)\\s+([\\w-]+\\|)?feature(!)?:", group = "Features" },
|
|
71
|
+
{ message = "^(\\#\\d+([.\\-]\\d+)?|\\#\\#|[A-Z]+-\\d+)\\s+([\\w-]+\\|)?fix(!)?:", group = "Bug fixes" },
|
|
72
|
+
{ message = "^(\\#\\d+([.\\-]\\d+)?|\\#\\#|[A-Z]+-\\d+)\\s+([\\w-]+\\|)?fmt(!)?:", group = "Formatting" },
|
|
73
|
+
{ message = "^(\\#\\d+([.\\-]\\d+)?|\\#\\#|[A-Z]+-\\d+)\\s+([\\w-]+\\|)?internal(!)?:", group = "Internal" },
|
|
74
|
+
{ message = "^(\\#\\d+([.\\-]\\d+)?|\\#\\#|[A-Z]+-\\d+)\\s+([\\w-]+\\|)?perf(!)?:", group = "Performance" },
|
|
75
|
+
{ message = "^(\\#\\d+([.\\-]\\d+)?|\\#\\#|[A-Z]+-\\d+)\\s+([\\w-]+\\|)?performance(!)?:", group = "Performance" },
|
|
76
|
+
{ message = "^(\\#\\d+([.\\-]\\d+)?|\\#\\#|[A-Z]+-\\d+)\\s+([\\w-]+\\|)?refactor(!)?:", group = "Refactoring" },
|
|
77
|
+
{ message = "^(\\#\\d+([.\\-]\\d+)?|\\#\\#|[A-Z]+-\\d+)\\s+([\\w-]+\\|)?sec(!)?:", group = "Security" },
|
|
78
|
+
{ message = "^(\\#\\d+([.\\-]\\d+)?|\\#\\#|[A-Z]+-\\d+)\\s+([\\w-]+\\|)?security(!)?:", group = "Security" },
|
|
79
|
+
{ message = "^(\\#\\d+([.\\-]\\d+)?|\\#\\#|[A-Z]+-\\d+)\\s+([\\w-]+\\|)?tests?(!)?:", group = "Tests" },
|
|
80
|
+
{ message = "^(\\#\\d+([.\\-]\\d+)?|\\#\\#|[A-Z]+-\\d+)\\s+([\\w-]+\\|)?tooling(!)?:", group = "Tooling" },
|
|
79
81
|
# Skip unticketed commits (maintenance, deps, initial scaffolding, etc.)
|
|
80
82
|
{ message = ".*", skip = true },
|
|
81
83
|
]
|
package/dist/esm/.cache
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
d3e4e5bacab96fdfcab4ae55b07b4830280060f0bc39bbada29fa8f08e2c9381
|
|
@@ -20,10 +20,16 @@ function createGithubRelease(options) {
|
|
|
20
20
|
console.warn(`Warning: no changelog entry for version ${version}; skipping GitHub Release creation`);
|
|
21
21
|
return false;
|
|
22
22
|
}
|
|
23
|
+
if (!entry.sections.some(matchesAudience("all"))) {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
23
26
|
const body = renderReleaseNotesSingle(entry, {
|
|
24
27
|
filter: matchesAudience("all"),
|
|
25
28
|
includeHeading: false
|
|
26
29
|
});
|
|
30
|
+
if (body.trim() === "") {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
27
33
|
const args = ["release", "create", tag, "--title", tag, "--notes", body];
|
|
28
34
|
if (dryRun) {
|
|
29
35
|
console.info(`[dry-run] Would run: gh ${args.join(" ")}`);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const COMMIT_PREPROCESSOR_PATTERNS = [/^#\d+([.-]\d+)?\s+/, /^[A-Z]+-\d+\s+/];
|
|
1
|
+
const COMMIT_PREPROCESSOR_PATTERNS = [/^##\s+/, /^#\d+([.-]\d+)?\s+/, /^[A-Z]+-\d+\s+/];
|
|
2
2
|
function parseCommitMessage(message, hash, workTypes, scopeAliases) {
|
|
3
3
|
const stripped = stripTicketPrefix(message);
|
|
4
4
|
const match = stripped.match(/^(?:([^|]+)\|)?(\w+)(?:\(([^)]+)\))?(!)?:\s*(.*)$/);
|
package/dist/esm/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const VERSION = "4.
|
|
1
|
+
export declare const VERSION = "4.7.0";
|
package/dist/esm/version.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@williamthorsen/release-kit",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.7.0",
|
|
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",
|
package/dist/esm/init/prompt.js
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
function printStep(message) {
|
|
2
|
-
console.info(`
|
|
3
|
-
> ${message}`);
|
|
4
|
-
}
|
|
5
|
-
function printSuccess(message) {
|
|
6
|
-
console.info(` \u2705 ${message}`);
|
|
7
|
-
}
|
|
8
|
-
function printSkip(message) {
|
|
9
|
-
console.info(` \u26A0\uFE0F ${message}`);
|
|
10
|
-
}
|
|
11
|
-
function printError(message) {
|
|
12
|
-
console.error(` \u274C ${message}`);
|
|
13
|
-
}
|
|
14
|
-
export {
|
|
15
|
-
printError,
|
|
16
|
-
printSkip,
|
|
17
|
-
printStep,
|
|
18
|
-
printSuccess
|
|
19
|
-
};
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import type { MonorepoReleaseConfig, ReleaseConfig, ReleaseType } from './types.ts';
|
|
2
|
-
export declare const RELEASE_TAGS_FILE = "tmp/.release-tags";
|
|
3
|
-
export declare function parseArgs(argv: string[]): {
|
|
4
|
-
dryRun: boolean;
|
|
5
|
-
force: boolean;
|
|
6
|
-
bumpOverride: ReleaseType | undefined;
|
|
7
|
-
only: string[] | undefined;
|
|
8
|
-
};
|
|
9
|
-
export declare function runReleasePrepare(config: MonorepoReleaseConfig | ReleaseConfig): void;
|
|
10
|
-
export declare function writeReleaseTags(tags: string[], dryRun: boolean): void;
|
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
import { mkdirSync, writeFileSync } from "node:fs";
|
|
2
|
-
import { dirname } from "node:path";
|
|
3
|
-
import { dim } from "./format.js";
|
|
4
|
-
import { releasePrepare } from "./releasePrepare.js";
|
|
5
|
-
import { releasePrepareMono } from "./releasePrepareMono.js";
|
|
6
|
-
const RELEASE_TAGS_FILE = "tmp/.release-tags";
|
|
7
|
-
const VALID_BUMP_TYPES = ["major", "minor", "patch"];
|
|
8
|
-
function isReleaseType(value) {
|
|
9
|
-
return VALID_BUMP_TYPES.includes(value);
|
|
10
|
-
}
|
|
11
|
-
function isMonorepoConfig(config) {
|
|
12
|
-
return "components" in config;
|
|
13
|
-
}
|
|
14
|
-
function showHelp() {
|
|
15
|
-
console.info(`
|
|
16
|
-
Usage: runReleasePrepare [options]
|
|
17
|
-
|
|
18
|
-
Legacy entry point for release preparation. Prefer the CLI:
|
|
19
|
-
npx @williamthorsen/release-kit prepare
|
|
20
|
-
|
|
21
|
-
Options:
|
|
22
|
-
--dry-run Run without modifying any files
|
|
23
|
-
--bump=major|minor|patch Override the bump type for all components
|
|
24
|
-
--force Bypass the "no commits since last tag" check (monorepo only, requires --bump)
|
|
25
|
-
--only=name1,name2 Only process the named components (comma-separated, monorepo only)
|
|
26
|
-
--help Show this help message
|
|
27
|
-
`);
|
|
28
|
-
}
|
|
29
|
-
function parseArgs(argv) {
|
|
30
|
-
let dryRun = false;
|
|
31
|
-
let force = false;
|
|
32
|
-
let bumpOverride;
|
|
33
|
-
let only;
|
|
34
|
-
for (const arg of argv) {
|
|
35
|
-
if (arg === "--dry-run") {
|
|
36
|
-
dryRun = true;
|
|
37
|
-
} else if (arg === "--force") {
|
|
38
|
-
force = true;
|
|
39
|
-
} else if (arg.startsWith("--bump=")) {
|
|
40
|
-
const value = arg.slice("--bump=".length);
|
|
41
|
-
if (!isReleaseType(value)) {
|
|
42
|
-
console.error(`Error: Invalid bump type "${value}". Must be one of: ${VALID_BUMP_TYPES.join(", ")}`);
|
|
43
|
-
process.exit(1);
|
|
44
|
-
}
|
|
45
|
-
bumpOverride = value;
|
|
46
|
-
} else if (arg.startsWith("--only=")) {
|
|
47
|
-
const value = arg.slice("--only=".length);
|
|
48
|
-
if (!value) {
|
|
49
|
-
console.error("Error: --only requires a comma-separated list of component names");
|
|
50
|
-
process.exit(1);
|
|
51
|
-
}
|
|
52
|
-
only = value.split(",");
|
|
53
|
-
} else if (arg === "--help" || arg === "-h") {
|
|
54
|
-
showHelp();
|
|
55
|
-
process.exit(0);
|
|
56
|
-
} else {
|
|
57
|
-
console.error(`Error: Unknown argument: ${arg}`);
|
|
58
|
-
process.exit(1);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
if (force && bumpOverride === void 0) {
|
|
62
|
-
console.error("Error: --force requires --bump to specify the version bump type");
|
|
63
|
-
process.exit(1);
|
|
64
|
-
}
|
|
65
|
-
return { dryRun, force, bumpOverride, only };
|
|
66
|
-
}
|
|
67
|
-
function runReleasePrepare(config) {
|
|
68
|
-
const { dryRun, force, bumpOverride, only } = parseArgs(process.argv.slice(2));
|
|
69
|
-
const options = {
|
|
70
|
-
dryRun,
|
|
71
|
-
force,
|
|
72
|
-
...bumpOverride === void 0 ? {} : { bumpOverride }
|
|
73
|
-
};
|
|
74
|
-
if (!isMonorepoConfig(config)) {
|
|
75
|
-
if (only !== void 0) {
|
|
76
|
-
console.error("Error: --only is only supported for monorepo configurations");
|
|
77
|
-
process.exit(1);
|
|
78
|
-
}
|
|
79
|
-
try {
|
|
80
|
-
const tags = releasePrepare(config, options);
|
|
81
|
-
writeReleaseTags(tags, dryRun);
|
|
82
|
-
} catch (error) {
|
|
83
|
-
console.error("Error preparing release:", error instanceof Error ? error.message : String(error));
|
|
84
|
-
process.exit(1);
|
|
85
|
-
}
|
|
86
|
-
return;
|
|
87
|
-
}
|
|
88
|
-
let effectiveConfig = config;
|
|
89
|
-
if (only !== void 0) {
|
|
90
|
-
const knownNames = config.components.map((c) => c.dir);
|
|
91
|
-
for (const name of only) {
|
|
92
|
-
if (!knownNames.includes(name)) {
|
|
93
|
-
console.error(`Error: Unknown component "${name}". Known components: ${knownNames.join(", ")}`);
|
|
94
|
-
process.exit(1);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
const filtered = config.components.filter((c) => only.includes(c.dir));
|
|
98
|
-
effectiveConfig = { ...config, components: filtered };
|
|
99
|
-
}
|
|
100
|
-
try {
|
|
101
|
-
const tags = releasePrepareMono(effectiveConfig, options);
|
|
102
|
-
writeReleaseTags(tags, dryRun);
|
|
103
|
-
} catch (error) {
|
|
104
|
-
console.error("Error preparing release:", error instanceof Error ? error.message : String(error));
|
|
105
|
-
process.exit(1);
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
function writeReleaseTags(tags, dryRun) {
|
|
109
|
-
if (tags.length === 0) {
|
|
110
|
-
return;
|
|
111
|
-
}
|
|
112
|
-
if (dryRun) {
|
|
113
|
-
console.info(dim(` [dry-run] Would write ${RELEASE_TAGS_FILE}: ${tags.join(" ")}`));
|
|
114
|
-
return;
|
|
115
|
-
}
|
|
116
|
-
mkdirSync(dirname(RELEASE_TAGS_FILE), { recursive: true });
|
|
117
|
-
writeFileSync(RELEASE_TAGS_FILE, tags.join("\n"), "utf8");
|
|
118
|
-
console.info(dim(` Wrote ${RELEASE_TAGS_FILE}: ${tags.join(" ")}`));
|
|
119
|
-
}
|
|
120
|
-
export {
|
|
121
|
-
RELEASE_TAGS_FILE,
|
|
122
|
-
parseArgs,
|
|
123
|
-
runReleasePrepare,
|
|
124
|
-
writeReleaseTags
|
|
125
|
-
};
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { existsSync, mkdirSync, writeFileSync } from "node:fs";
|
|
2
|
-
import { dirname } from "node:path";
|
|
3
|
-
function writeIfAbsent(filePath, content, dryRun, overwrite) {
|
|
4
|
-
if (existsSync(filePath) && !overwrite) {
|
|
5
|
-
console.info(` Skipped ${filePath} (already exists)`);
|
|
6
|
-
return { action: "skipped", filePath };
|
|
7
|
-
}
|
|
8
|
-
if (dryRun) {
|
|
9
|
-
console.info(` [dry-run] Would create ${filePath}`);
|
|
10
|
-
return { action: "dry-run", filePath };
|
|
11
|
-
}
|
|
12
|
-
try {
|
|
13
|
-
mkdirSync(dirname(filePath), { recursive: true });
|
|
14
|
-
writeFileSync(filePath, content, "utf8");
|
|
15
|
-
} catch (error) {
|
|
16
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
17
|
-
console.error(` Failed to write ${filePath}: ${message}`);
|
|
18
|
-
return { action: "failed", filePath };
|
|
19
|
-
}
|
|
20
|
-
console.info(` Created ${filePath}`);
|
|
21
|
-
return { action: "created", filePath };
|
|
22
|
-
}
|
|
23
|
-
export {
|
|
24
|
-
writeIfAbsent
|
|
25
|
-
};
|