@williamthorsen/release-kit 10.6.0 â 10.8.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/.meta/changelog.json +96 -0
- package/.readyup/kits/default.js +17 -3
- package/.readyup/kits/npm-auto-publish.js +87 -23
- package/.readyup/manifest.json +9 -9
- package/CHANGELOG.md +61 -0
- package/README.md +53 -1010
- package/dist/esm/bin/release-kit.js +7 -6
- package/dist/esm/buildChangelogEntries.d.ts +1 -1
- package/dist/esm/buildChangelogEntries.js +14 -5
- package/dist/esm/buildDependencyGraph.d.ts +6 -5
- package/dist/esm/buildDependencyGraph.js +5 -1
- package/dist/esm/checkWorkTypesDrift.d.ts +2 -3
- package/dist/esm/checkWorkTypesDrift.js +1 -1
- package/dist/esm/init/scaffold.js +14 -6
- package/dist/esm/parseCommitMessage.d.ts +4 -5
- package/dist/esm/planVersionBump.d.ts +2 -1
- package/dist/esm/planVersionBump.js +4 -0
- package/dist/esm/propagateBumps.d.ts +1 -3
- package/dist/esm/propagateBumps.js +2 -2
- package/dist/esm/releasePrepare.js +0 -13
- package/dist/esm/releasePrepareMono.js +3 -20
- package/dist/esm/sync-labels/resolveLabels.d.ts +5 -3
- package/dist/esm/sync-labels/resolveLabels.js +21 -6
- package/dist/esm/types.d.ts +12 -9
- package/dist/esm/validateConfig.js +1 -1
- package/dist/esm/work-types.json +68 -52
- package/dist/esm/work-types.schema.json +12 -2
- package/dist/esm/workTypesData.d.ts +10 -9
- package/dist/esm/workTypesData.js +97 -11
- package/docs/api.md +73 -0
- package/docs/changelogs.md +70 -0
- package/docs/configuration.md +105 -0
- package/docs/editorial-overrides.md +144 -0
- package/docs/labels.md +83 -0
- package/docs/project-releases.md +74 -0
- package/docs/publishing.md +30 -0
- package/docs/readiness-checks.md +18 -0
- package/docs/releasing.md +108 -0
- package/docs/work-types.md +116 -0
- package/package.json +7 -4
- package/dist/esm/readCurrentVersion.d.ts +0 -2
- package/dist/esm/readCurrentVersion.js +0 -18
package/dist/esm/work-types.json
CHANGED
|
@@ -1,133 +1,149 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "./work-types.schema.json",
|
|
3
|
+
"markers": {
|
|
4
|
+
"breaking": {
|
|
5
|
+
"emoji": "ðĻ",
|
|
6
|
+
"label": "Breaking"
|
|
7
|
+
}
|
|
8
|
+
},
|
|
3
9
|
"tiers": ["public", "internal", "process"],
|
|
4
10
|
"types": [
|
|
5
11
|
{
|
|
6
|
-
"tier": "public",
|
|
7
|
-
"key": "feat",
|
|
8
12
|
"aliases": ["feature"],
|
|
13
|
+
"breakingPolicy": "optional",
|
|
14
|
+
"description": "A change that gives consumers a new capability or extends an existing one.",
|
|
9
15
|
"emoji": "ð",
|
|
16
|
+
"key": "feat",
|
|
10
17
|
"label": "Features",
|
|
11
|
-
"
|
|
18
|
+
"tier": "public"
|
|
12
19
|
},
|
|
13
20
|
{
|
|
14
|
-
"tier": "public",
|
|
15
|
-
"key": "drop",
|
|
16
21
|
"aliases": [],
|
|
22
|
+
"breakingPolicy": "required",
|
|
23
|
+
"description": "A change that removes a capability or surface on which consumers depend.",
|
|
17
24
|
"emoji": "ðŠĶ",
|
|
25
|
+
"key": "drop",
|
|
18
26
|
"label": "Removed",
|
|
19
|
-
"
|
|
27
|
+
"tier": "public"
|
|
20
28
|
},
|
|
21
29
|
{
|
|
22
|
-
"tier": "public",
|
|
23
|
-
"key": "deprecate",
|
|
24
30
|
"aliases": [],
|
|
31
|
+
"breakingPolicy": "forbidden",
|
|
32
|
+
"description": "A change that marks a capability or surface for removal while the capability or surface keeps working.",
|
|
25
33
|
"emoji": "ðïļ",
|
|
34
|
+
"key": "deprecate",
|
|
26
35
|
"label": "Deprecated",
|
|
27
|
-
"
|
|
36
|
+
"tier": "public"
|
|
28
37
|
},
|
|
29
38
|
{
|
|
30
|
-
"tier": "public",
|
|
31
|
-
"key": "fix",
|
|
32
39
|
"aliases": ["bugfix"],
|
|
40
|
+
"breakingPolicy": "optional",
|
|
41
|
+
"description": "A change that corrects behavior that consumers meet and that differs from what was intended.",
|
|
33
42
|
"emoji": "ð",
|
|
43
|
+
"key": "fix",
|
|
34
44
|
"label": "Bug fixes",
|
|
35
|
-
"
|
|
45
|
+
"tier": "public"
|
|
36
46
|
},
|
|
37
47
|
{
|
|
38
|
-
"tier": "public",
|
|
39
|
-
"key": "sec",
|
|
40
48
|
"aliases": ["security"],
|
|
49
|
+
"breakingPolicy": "optional",
|
|
50
|
+
"description": "A change that closes a vulnerability or hardens a consumer-facing surface against attack.",
|
|
41
51
|
"emoji": "ð",
|
|
52
|
+
"key": "sec",
|
|
42
53
|
"label": "Security",
|
|
43
|
-
"
|
|
54
|
+
"tier": "public"
|
|
44
55
|
},
|
|
45
56
|
{
|
|
46
|
-
"tier": "public",
|
|
47
|
-
"key": "perf",
|
|
48
57
|
"aliases": ["performance"],
|
|
58
|
+
"breakingPolicy": "optional",
|
|
59
|
+
"description": "A change that reduces the time, memory, or other resources that consumer-facing work uses, without changing its result.",
|
|
49
60
|
"emoji": "âĄ",
|
|
61
|
+
"key": "perf",
|
|
50
62
|
"label": "Performance",
|
|
51
|
-
"
|
|
63
|
+
"tier": "public"
|
|
52
64
|
},
|
|
53
65
|
{
|
|
54
|
-
"tier": "internal",
|
|
55
|
-
"key": "internal",
|
|
56
66
|
"aliases": ["utility"],
|
|
67
|
+
"breakingPolicy": "forbidden",
|
|
68
|
+
"description": "A change that adds or extends a capability that consumers do not use directly, such as a helper or an internal module.",
|
|
57
69
|
"emoji": "ðïļ",
|
|
70
|
+
"key": "internal",
|
|
58
71
|
"label": "Internal features",
|
|
59
|
-
"
|
|
72
|
+
"tier": "internal"
|
|
60
73
|
},
|
|
61
74
|
{
|
|
62
|
-
"tier": "internal",
|
|
63
|
-
"key": "refactor",
|
|
64
75
|
"aliases": [],
|
|
76
|
+
"breakingPolicy": "forbidden",
|
|
77
|
+
"description": "A change that restructures existing code without changing its behavior.",
|
|
65
78
|
"emoji": "âŧïļ",
|
|
79
|
+
"key": "refactor",
|
|
66
80
|
"label": "Refactoring",
|
|
67
|
-
"
|
|
81
|
+
"tier": "internal"
|
|
68
82
|
},
|
|
69
83
|
{
|
|
70
|
-
"tier": "internal",
|
|
71
|
-
"key": "tests",
|
|
72
84
|
"aliases": ["test"],
|
|
85
|
+
"breakingPolicy": "forbidden",
|
|
86
|
+
"description": "A change confined to tests, test fixtures, or test helpers, including one that unblocks a build or a type check.",
|
|
73
87
|
"emoji": "ð§Š",
|
|
88
|
+
"key": "tests",
|
|
74
89
|
"label": "Tests",
|
|
75
|
-
"
|
|
90
|
+
"tier": "internal"
|
|
76
91
|
},
|
|
77
92
|
{
|
|
78
|
-
"tier": "process",
|
|
79
|
-
"key": "tooling",
|
|
80
93
|
"aliases": [],
|
|
94
|
+
"breakingPolicy": "forbidden",
|
|
95
|
+
"description": "A change to the tools used to develop the project: build, lint, formatting, and release configuration, and development scripts.",
|
|
81
96
|
"emoji": "âïļ",
|
|
97
|
+
"key": "tooling",
|
|
82
98
|
"label": "Tooling",
|
|
83
|
-
"
|
|
99
|
+
"tier": "process"
|
|
84
100
|
},
|
|
85
101
|
{
|
|
86
|
-
"tier": "process",
|
|
87
|
-
"key": "ci",
|
|
88
102
|
"aliases": [],
|
|
103
|
+
"breakingPolicy": "forbidden",
|
|
104
|
+
"description": "A change to continuous-integration workflows and their configuration.",
|
|
89
105
|
"emoji": "ð·",
|
|
106
|
+
"key": "ci",
|
|
90
107
|
"label": "CI",
|
|
91
|
-
"
|
|
108
|
+
"tier": "process"
|
|
92
109
|
},
|
|
93
110
|
{
|
|
94
|
-
"tier": "process",
|
|
95
|
-
"key": "deps",
|
|
96
111
|
"aliases": ["dep"],
|
|
112
|
+
"breakingPolicy": "forbidden",
|
|
113
|
+
"description": "A change that adds, removes, or upgrades a dependency, including its lockfile and version-catalog entries.",
|
|
97
114
|
"emoji": "ðĶ",
|
|
115
|
+
"key": "deps",
|
|
98
116
|
"label": "Dependencies",
|
|
99
|
-
"
|
|
117
|
+
"tier": "process"
|
|
100
118
|
},
|
|
101
119
|
{
|
|
102
|
-
"tier": "process",
|
|
103
|
-
"key": "ai",
|
|
104
120
|
"aliases": [],
|
|
121
|
+
"breakingPolicy": "forbidden",
|
|
122
|
+
"description": "A change to guidance on working in the repository itself, such as its `AGENTS.md` or a repo-local skill, or to the repository's agent configuration.",
|
|
105
123
|
"emoji": "ðĪ",
|
|
124
|
+
"key": "ai",
|
|
106
125
|
"label": "Agentic support",
|
|
107
|
-
"
|
|
126
|
+
"tier": "process"
|
|
108
127
|
},
|
|
109
128
|
{
|
|
110
|
-
"tier": "process",
|
|
111
|
-
"key": "docs",
|
|
112
129
|
"aliases": ["doc"],
|
|
130
|
+
"breakingPolicy": "forbidden",
|
|
131
|
+
"description": "A change to documentation for human readers, such as a README, a guide, or a code comment.",
|
|
113
132
|
"emoji": "ð",
|
|
133
|
+
"key": "docs",
|
|
114
134
|
"label": "Documentation",
|
|
115
|
-
"
|
|
135
|
+
"tier": "process"
|
|
116
136
|
},
|
|
117
137
|
{
|
|
118
|
-
"tier": "process",
|
|
119
|
-
"key": "fmt",
|
|
120
138
|
"aliases": [],
|
|
139
|
+
"breakingPolicy": "forbidden",
|
|
140
|
+
"description": "A change to formatting alone, such as whitespace or line wrapping, that leaves the content unchanged.",
|
|
121
141
|
"emoji": "ðĻ",
|
|
142
|
+
"excludedFromChangelog": true,
|
|
143
|
+
"key": "fmt",
|
|
122
144
|
"label": "Formatting",
|
|
123
|
-
"
|
|
124
|
-
"excludedFromChangelog": true
|
|
145
|
+
"tier": "process"
|
|
125
146
|
}
|
|
126
147
|
],
|
|
127
|
-
"
|
|
128
|
-
"breaking": {
|
|
129
|
-
"emoji": "ðĻ",
|
|
130
|
-
"label": "Breaking"
|
|
131
|
-
}
|
|
132
|
-
}
|
|
148
|
+
"version": "1.1.0"
|
|
133
149
|
}
|
|
@@ -4,13 +4,18 @@
|
|
|
4
4
|
"title": "Work types",
|
|
5
5
|
"description": "Canonical taxonomy of commit work types used by release-kit. Drives section ordering, audience classification, and the `!` (breaking) policy. The structured single-source-of-truth for everything that previously lived in `DEFAULT_WORK_TYPES` and `cliff.toml.template` group definitions.",
|
|
6
6
|
"type": "object",
|
|
7
|
-
"required": ["tiers", "types", "markers"],
|
|
7
|
+
"required": ["tiers", "types", "markers", "version"],
|
|
8
8
|
"additionalProperties": false,
|
|
9
9
|
"properties": {
|
|
10
10
|
"$schema": {
|
|
11
11
|
"type": "string",
|
|
12
12
|
"description": "Optional reference to this schema for IDE validation."
|
|
13
13
|
},
|
|
14
|
+
"version": {
|
|
15
|
+
"type": "string",
|
|
16
|
+
"description": "Semantic version of the data shape. Bumped when the structure changes in a way that breaks downstream consumers.",
|
|
17
|
+
"pattern": "^\\d+\\.\\d+\\.\\d+$"
|
|
18
|
+
},
|
|
14
19
|
"tiers": {
|
|
15
20
|
"type": "array",
|
|
16
21
|
"description": "Render tiers in canonical order. Each entry's `tier` field must reference one of these names.",
|
|
@@ -55,7 +60,7 @@
|
|
|
55
60
|
},
|
|
56
61
|
"workType": {
|
|
57
62
|
"type": "object",
|
|
58
|
-
"required": ["tier", "key", "aliases", "emoji", "label", "breakingPolicy"],
|
|
63
|
+
"required": ["tier", "key", "aliases", "emoji", "label", "breakingPolicy", "description"],
|
|
59
64
|
"additionalProperties": false,
|
|
60
65
|
"properties": {
|
|
61
66
|
"tier": {
|
|
@@ -84,6 +89,11 @@
|
|
|
84
89
|
"description": "Human-readable section label (rendered as `${emoji} ${label}` in changelogs and release notes).",
|
|
85
90
|
"minLength": 1
|
|
86
91
|
},
|
|
92
|
+
"description": {
|
|
93
|
+
"type": "string",
|
|
94
|
+
"description": "The changes that the type covers, read by an agent choosing a type for a change.",
|
|
95
|
+
"minLength": 1
|
|
96
|
+
},
|
|
87
97
|
"breakingPolicy": {
|
|
88
98
|
"type": "string",
|
|
89
99
|
"description": "Policy governing the `!` (breaking) marker for this type. `forbidden`: `!` is a policy violation. `optional`: `!` is allowed. `required`: bare type is a policy violation; only the `!` form is accepted.",
|
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Canonical work-types data
|
|
2
|
+
* Canonical work-types data: the runtime mirror of `work-types.json`.
|
|
3
3
|
*
|
|
4
|
-
* `work-types.json` is
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* esbuild's `bundle: false` mode strips, so a plain TS module is the most reliable way
|
|
8
|
-
* to ship the data to consumers.
|
|
4
|
+
* `work-types.json` is release-kit's copy of the codeassembly canonical. This `.ts` mirror exists for
|
|
5
|
+
* runtime consumption: The compiler baseline does not enable JSON module imports, and a TS constant keeps
|
|
6
|
+
* `breakingPolicy` typed as its three-value union.
|
|
9
7
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* `
|
|
8
|
+
* `nmr work-types:sync` updates only the JSON, so copy its change here by hand. A drift test
|
|
9
|
+
* (`workTypesData.unit.test.ts`) asserts that this constant deep-equals the parsed contents of
|
|
10
|
+
* `work-types.json`.
|
|
13
11
|
*/
|
|
14
12
|
/** Schema for a single entry. */
|
|
15
13
|
export interface WorkTypeEntry {
|
|
@@ -18,6 +16,7 @@ export interface WorkTypeEntry {
|
|
|
18
16
|
aliases: string[];
|
|
19
17
|
emoji: string;
|
|
20
18
|
label: string;
|
|
19
|
+
description: string;
|
|
21
20
|
breakingPolicy: 'forbidden' | 'optional' | 'required';
|
|
22
21
|
excludedFromChangelog?: boolean;
|
|
23
22
|
}
|
|
@@ -34,6 +33,8 @@ export interface MarkerEntry {
|
|
|
34
33
|
}
|
|
35
34
|
/** Schema for the full data. */
|
|
36
35
|
export interface WorkTypesData {
|
|
36
|
+
/** Semantic version of the data shape, as declared by the upstream canonical. */
|
|
37
|
+
version: string;
|
|
37
38
|
tiers: string[];
|
|
38
39
|
types: WorkTypeEntry[];
|
|
39
40
|
/**
|
|
@@ -1,18 +1,60 @@
|
|
|
1
1
|
export const WORK_TYPES_DATA = {
|
|
2
|
+
version: '1.1.0',
|
|
2
3
|
tiers: ['public', 'internal', 'process'],
|
|
3
4
|
types: [
|
|
4
|
-
{
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
{
|
|
6
|
+
tier: 'public',
|
|
7
|
+
key: 'feat',
|
|
8
|
+
aliases: ['feature'],
|
|
9
|
+
emoji: 'ð',
|
|
10
|
+
label: 'Features',
|
|
11
|
+
description: 'A change that gives consumers a new capability or extends an existing one.',
|
|
12
|
+
breakingPolicy: 'optional',
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
tier: 'public',
|
|
16
|
+
key: 'drop',
|
|
17
|
+
aliases: [],
|
|
18
|
+
emoji: 'ðŠĶ',
|
|
19
|
+
label: 'Removed',
|
|
20
|
+
description: 'A change that removes a capability or surface on which consumers depend.',
|
|
21
|
+
breakingPolicy: 'required',
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
tier: 'public',
|
|
25
|
+
key: 'deprecate',
|
|
26
|
+
aliases: [],
|
|
27
|
+
emoji: 'ðïļ',
|
|
28
|
+
label: 'Deprecated',
|
|
29
|
+
description: 'A change that marks a capability or surface for removal while the capability or surface keeps working.',
|
|
30
|
+
breakingPolicy: 'forbidden',
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
tier: 'public',
|
|
34
|
+
key: 'fix',
|
|
35
|
+
aliases: ['bugfix'],
|
|
36
|
+
emoji: 'ð',
|
|
37
|
+
label: 'Bug fixes',
|
|
38
|
+
description: 'A change that corrects behavior that consumers meet and that differs from what was intended.',
|
|
39
|
+
breakingPolicy: 'optional',
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
tier: 'public',
|
|
43
|
+
key: 'sec',
|
|
44
|
+
aliases: ['security'],
|
|
45
|
+
emoji: 'ð',
|
|
46
|
+
label: 'Security',
|
|
47
|
+
description: 'A change that closes a vulnerability or hardens a consumer-facing surface against attack.',
|
|
48
|
+
breakingPolicy: 'optional',
|
|
49
|
+
},
|
|
9
50
|
{
|
|
10
51
|
tier: 'public',
|
|
11
52
|
key: 'perf',
|
|
12
53
|
aliases: ['performance'],
|
|
13
54
|
emoji: 'âĄ',
|
|
14
55
|
label: 'Performance',
|
|
15
|
-
|
|
56
|
+
description: 'A change that reduces the time, memory, or other resources that consumer-facing work uses, without changing its result.',
|
|
57
|
+
breakingPolicy: 'optional',
|
|
16
58
|
},
|
|
17
59
|
{
|
|
18
60
|
tier: 'internal',
|
|
@@ -20,6 +62,7 @@ export const WORK_TYPES_DATA = {
|
|
|
20
62
|
aliases: ['utility'],
|
|
21
63
|
emoji: 'ðïļ',
|
|
22
64
|
label: 'Internal features',
|
|
65
|
+
description: 'A change that adds or extends a capability that consumers do not use directly, such as a helper or an internal module.',
|
|
23
66
|
breakingPolicy: 'forbidden',
|
|
24
67
|
},
|
|
25
68
|
{
|
|
@@ -28,19 +71,61 @@ export const WORK_TYPES_DATA = {
|
|
|
28
71
|
aliases: [],
|
|
29
72
|
emoji: 'âŧïļ',
|
|
30
73
|
label: 'Refactoring',
|
|
74
|
+
description: 'A change that restructures existing code without changing its behavior.',
|
|
75
|
+
breakingPolicy: 'forbidden',
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
tier: 'internal',
|
|
79
|
+
key: 'tests',
|
|
80
|
+
aliases: ['test'],
|
|
81
|
+
emoji: 'ð§Š',
|
|
82
|
+
label: 'Tests',
|
|
83
|
+
description: 'A change confined to tests, test fixtures, or test helpers, including one that unblocks a build or a type check.',
|
|
84
|
+
breakingPolicy: 'forbidden',
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
tier: 'process',
|
|
88
|
+
key: 'tooling',
|
|
89
|
+
aliases: [],
|
|
90
|
+
emoji: 'âïļ',
|
|
91
|
+
label: 'Tooling',
|
|
92
|
+
description: 'A change to the tools used to develop the project: build, lint, formatting, and release configuration, and development scripts.',
|
|
93
|
+
breakingPolicy: 'forbidden',
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
tier: 'process',
|
|
97
|
+
key: 'ci',
|
|
98
|
+
aliases: [],
|
|
99
|
+
emoji: 'ð·',
|
|
100
|
+
label: 'CI',
|
|
101
|
+
description: 'A change to continuous-integration workflows and their configuration.',
|
|
102
|
+
breakingPolicy: 'forbidden',
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
tier: 'process',
|
|
106
|
+
key: 'deps',
|
|
107
|
+
aliases: ['dep'],
|
|
108
|
+
emoji: 'ðĶ',
|
|
109
|
+
label: 'Dependencies',
|
|
110
|
+
description: 'A change that adds, removes, or upgrades a dependency, including its lockfile and version-catalog entries.',
|
|
111
|
+
breakingPolicy: 'forbidden',
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
tier: 'process',
|
|
115
|
+
key: 'ai',
|
|
116
|
+
aliases: [],
|
|
117
|
+
emoji: 'ðĪ',
|
|
118
|
+
label: 'Agentic support',
|
|
119
|
+
description: "A change to guidance on working in the repository itself, such as its `AGENTS.md` or a repo-local skill, or to the repository's agent configuration.",
|
|
31
120
|
breakingPolicy: 'forbidden',
|
|
32
121
|
},
|
|
33
|
-
{ tier: 'internal', key: 'tests', aliases: ['test'], emoji: 'ð§Š', label: 'Tests', breakingPolicy: 'forbidden' },
|
|
34
|
-
{ tier: 'process', key: 'tooling', aliases: [], emoji: 'âïļ', label: 'Tooling', breakingPolicy: 'forbidden' },
|
|
35
|
-
{ tier: 'process', key: 'ci', aliases: [], emoji: 'ð·', label: 'CI', breakingPolicy: 'forbidden' },
|
|
36
|
-
{ tier: 'process', key: 'deps', aliases: ['dep'], emoji: 'ðĶ', label: 'Dependencies', breakingPolicy: 'forbidden' },
|
|
37
|
-
{ tier: 'process', key: 'ai', aliases: [], emoji: 'ðĪ', label: 'Agentic support', breakingPolicy: 'forbidden' },
|
|
38
122
|
{
|
|
39
123
|
tier: 'process',
|
|
40
124
|
key: 'docs',
|
|
41
125
|
aliases: ['doc'],
|
|
42
126
|
emoji: 'ð',
|
|
43
127
|
label: 'Documentation',
|
|
128
|
+
description: 'A change to documentation for human readers, such as a README, a guide, or a code comment.',
|
|
44
129
|
breakingPolicy: 'forbidden',
|
|
45
130
|
},
|
|
46
131
|
{
|
|
@@ -49,6 +134,7 @@ export const WORK_TYPES_DATA = {
|
|
|
49
134
|
aliases: [],
|
|
50
135
|
emoji: 'ðĻ',
|
|
51
136
|
label: 'Formatting',
|
|
137
|
+
description: 'A change to formatting alone, such as whitespace or line wrapping, that leaves the content unchanged.',
|
|
52
138
|
breakingPolicy: 'forbidden',
|
|
53
139
|
excludedFromChangelog: true,
|
|
54
140
|
},
|
package/docs/api.md
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# Programmatic API
|
|
2
|
+
|
|
3
|
+
How to build a release config by hand with `deriveWorkspaceConfig()`, the script-based approach that predates the CLI, and the workspace records that `resolveReleaseTags` takes.
|
|
4
|
+
|
|
5
|
+
## Using `deriveWorkspaceConfig()` for manual configuration
|
|
6
|
+
|
|
7
|
+
If you need to build a `MonorepoReleaseConfig` manually (e.g., for the legacy script-based approach), the exported `deriveWorkspaceConfig()` helper creates a `WorkspaceConfig` from a workspace-relative path. It reads the workspace's `package.json` to derive the tag prefix from the package name:
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
import { deriveWorkspaceConfig } from '@williamthorsen/release-kit';
|
|
11
|
+
|
|
12
|
+
// packages/arrays/package.json contains `"name": "@scope/arrays"`
|
|
13
|
+
deriveWorkspaceConfig('packages/arrays');
|
|
14
|
+
// => {
|
|
15
|
+
// dir: 'arrays',
|
|
16
|
+
// name: '@scope/arrays',
|
|
17
|
+
// tagPrefix: 'arrays-v',
|
|
18
|
+
// workspacePath: 'packages/arrays',
|
|
19
|
+
// packageFiles: ['packages/arrays/package.json'],
|
|
20
|
+
// changelogPaths: ['packages/arrays'],
|
|
21
|
+
// paths: ['packages/arrays/**'],
|
|
22
|
+
// }
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
`dir` is the basename of the workspace path and is the stable internal identifier used by `--only`, `WorkspaceOverride.dir`, and the dependency graph. `tagPrefix` is derived from the unscoped `package.json` `name` â any leading `@scope/` is stripped â so tags reflect the package identity rather than the directory layout. For example, a workspace at `packages/core` with `"name": "@williamthorsen/nmr-core"` produces `tagPrefix: 'nmr-core-v'`, yielding tags like `nmr-core-v1.3.0`.
|
|
26
|
+
|
|
27
|
+
The workspace's `package.json` must declare a non-empty `name` field; `deriveWorkspaceConfig()` throws otherwise. If two workspaces produce the same `tagPrefix` (because their unscoped names collide), `mergeMonorepoConfig()` throws and names the colliding workspaces so you can rename one.
|
|
28
|
+
|
|
29
|
+
## Legacy script-based approach
|
|
30
|
+
|
|
31
|
+
The CLI-driven approach is recommended for new setups. The script-based approach (using `runReleasePrepare` with a manually maintained config) is still supported for backward compatibility.
|
|
32
|
+
|
|
33
|
+
```typescript
|
|
34
|
+
// .github/scripts/release.config.ts
|
|
35
|
+
import type { MonorepoReleaseConfig } from '@williamthorsen/release-kit';
|
|
36
|
+
import { deriveWorkspaceConfig } from '@williamthorsen/release-kit';
|
|
37
|
+
|
|
38
|
+
export const config: MonorepoReleaseConfig = {
|
|
39
|
+
workspaces: [deriveWorkspaceConfig('packages/arrays'), deriveWorkspaceConfig('packages/strings')],
|
|
40
|
+
formatCommand: 'npx prettier --write',
|
|
41
|
+
};
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
// .github/scripts/release-prepare.ts
|
|
46
|
+
import { runReleasePrepare } from '@williamthorsen/release-kit';
|
|
47
|
+
import { config } from './release.config.ts';
|
|
48
|
+
|
|
49
|
+
runReleasePrepare(config);
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
The key difference: the script-based approach requires manually listing every workspace, while the CLI auto-discovers them from `pnpm-workspace.yaml`.
|
|
53
|
+
|
|
54
|
+
## `resolveReleaseTags` takes workspaces; `WorkspaceConfig` requires `workspacePath`
|
|
55
|
+
|
|
56
|
+
Tag resolution is now driven by workspace records rather than a caller-supplied directory map, so `resolveReleaseTags` can report both the workspace `dir` and its `workspacePath` for every resolved tag.
|
|
57
|
+
|
|
58
|
+
- `resolveReleaseTags` signature changed from `(workspaceMap?: Map<string, string>)` to `(workspaces?: readonly WorkspaceConfig[])`.
|
|
59
|
+
- `WorkspaceConfig` gained a required `workspacePath: string` field.
|
|
60
|
+
|
|
61
|
+
Replace direct `Map`-based calls with `deriveWorkspaceConfig()`, which now populates `workspacePath` for you:
|
|
62
|
+
|
|
63
|
+
```diff
|
|
64
|
+
-import { resolveReleaseTags } from '@williamthorsen/release-kit';
|
|
65
|
+
-
|
|
66
|
+
-const workspaceMap = new Map([['core', 'packages/core']]);
|
|
67
|
+
-resolveReleaseTags(workspaceMap);
|
|
68
|
+
+import { deriveWorkspaceConfig, resolveReleaseTags } from '@williamthorsen/release-kit';
|
|
69
|
+
+
|
|
70
|
+
+resolveReleaseTags([deriveWorkspaceConfig('packages/core')]);
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
If you construct `WorkspaceConfig` objects directly, add `workspacePath` alongside the other required fields.
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# Changelogs
|
|
2
|
+
|
|
3
|
+
What reaches a published tarball, what each `.meta/changelog.json` item contains, how the git-cliff config is resolved, and how release notes reach a README.
|
|
4
|
+
|
|
5
|
+
Neither `CHANGELOG.md` nor `.meta/changelog.json` reaches a published tarball on its own. npm stopped including `CHANGELOG` automatically in npm 7, so a package that declares a `files` field ships a changelog only where that field names `CHANGELOG.md` and `.meta/changelog.json`. release-kit's readyup kit reports a publishable workspace whose `files` field omits either.
|
|
6
|
+
|
|
7
|
+
## `changelog.json` item schema
|
|
8
|
+
|
|
9
|
+
Each item under a section in `.meta/changelog.json` carries one required field and four optional ones:
|
|
10
|
+
|
|
11
|
+
| Field | Type | Meaning |
|
|
12
|
+
| ------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
13
|
+
| `description` | `string` | The bullet headline, taken from the commit subject with the ticket ID and type prefix stripped. |
|
|
14
|
+
| `body` | `string` | The commit body, with trailing trailer metadata stripped. |
|
|
15
|
+
| `breaking` | `boolean` | Present and `true` where the commit subject carried the `!` prefix and the commit's type permits it. See [`!` (breaking change) policy](work-types.md#-breaking-change-policy). |
|
|
16
|
+
| `migration` | `string` | The migration step for a consumer. See below. |
|
|
17
|
+
| `hash` | `string` | The full commit SHA, and the key on which an override entry matches. Absent on synthetic propagation entries. |
|
|
18
|
+
|
|
19
|
+
Every optional field is omitted rather than emitted as `null`, so a consumer tests for presence.
|
|
20
|
+
|
|
21
|
+
### The `migration` field
|
|
22
|
+
|
|
23
|
+
A commit body states a migration step as a paragraph opening with the literal label `Migration:`. Where one is present, `migration` carries that paragraph with the label stripped:
|
|
24
|
+
|
|
25
|
+
```jsonc
|
|
26
|
+
{
|
|
27
|
+
"description": "Rename the workspace field",
|
|
28
|
+
"body": "Renames `name` to `id`.\n\nMigration: Change any uses of `name` to `id`.",
|
|
29
|
+
"migration": "Change any uses of `name` to `id`.",
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Three properties are worth knowing:
|
|
34
|
+
|
|
35
|
+
- **It is independent of `breaking`.** A `deprecate` cannot carry `!` under the default breaking policy, and a `deprecate` still calls for a migration. Filter on `migration` to find every step; filter on `breaking` to find every breaking change.
|
|
36
|
+
- **`body` keeps the paragraph.** The field is an extraction, not a move, so `CHANGELOG.md` and `.meta/changelog.json` go on agreeing.
|
|
37
|
+
- **It is derived, not authored.** `migration` is not a field an override file can set (see [File shape](editorial-overrides.md#file-shape)); it is re-derived from whatever `body` an override installs, and cleared where that body carries no labeled paragraph. To change the migration text, override `body`.
|
|
38
|
+
|
|
39
|
+
The label match is exact: `migration:` and `**Migration:**` are not recognized.
|
|
40
|
+
|
|
41
|
+
## cliff.toml setup
|
|
42
|
+
|
|
43
|
+
The package includes a bundled `cliff.toml.template` that is used automatically when no custom config is found. The resolution order:
|
|
44
|
+
|
|
45
|
+
| Priority | Path | Notes |
|
|
46
|
+
| -------- | ----------------------------- | ----------------------------------------------- |
|
|
47
|
+
| 1 | `cliffConfigPath` in config | Explicit path, returned without existence check |
|
|
48
|
+
| 2 | `.config/git-cliff.toml` | Project-level override |
|
|
49
|
+
| 3 | `cliff.toml` | Repo root fallback |
|
|
50
|
+
| 4 | Bundled `cliff.toml.template` | Automatic fallback |
|
|
51
|
+
|
|
52
|
+
The bundled template provides a generic git-cliff configuration that:
|
|
53
|
+
|
|
54
|
+
- Strips issue-ticket prefixes matching `^[A-Z]+-\d+\s+` (e.g., `TOOL-123 `, `AFG-456 `)
|
|
55
|
+
- Handles both `type: description` and `workspace|type: description` commit formats
|
|
56
|
+
- Groups commits by work type via `[git].commit_parsers`
|
|
57
|
+
|
|
58
|
+
The body template is intentionally empty: release-kit reads cliff's `--context` JSON output and renders `CHANGELOG.md` in-process via `renderChangelogMarkdown` (see [How it works](../README.md#how-it-works) for the rationale). The `[git].commit_parsers` section remains load-bearing for `--context` group assignment.
|
|
59
|
+
|
|
60
|
+
To customize, scaffold a local copy with `release-kit init --with-config` and edit `.config/git-cliff.toml`. Edit only the `[git]` section â body-template changes have no effect.
|
|
61
|
+
|
|
62
|
+
## Release-notes injection
|
|
63
|
+
|
|
64
|
+
With `releaseNotes.shouldInjectIntoReadme` set to `true`, `release-kit publish` writes each package's release notes into its `README.md` for the duration of the publish, then restores the file. The notes are the all-audience sections of the released version's entry in `.meta/changelog.json`, under a `## Release notes â v<version> (<date>)` heading, and they replace whatever lies between the marker pair:
|
|
65
|
+
|
|
66
|
+
```markdown
|
|
67
|
+
<!-- section:release-notes --><!-- /section:release-notes -->
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
A README without the marker pair receives the notes at its top, above its title, and release-kit's readyup kit reports a README that lacks the markers. Injection is skipped with a warning when `changelogJson.enabled` is `false`, when the version has no entry, or when the entry has no all-audience content. `release-kit prepare --with-release-notes` writes the same injected README as a [preview](releasing.md#previewing-release-notes-with---with-release-notes).
|