@williamthorsen/release-kit 4.8.0 → 5.1.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 +134 -4
- package/README.md +404 -40
- package/cliff.toml.template +2 -1
- package/dist/esm/.cache +1 -1
- package/dist/esm/assertCleanWorkingTree.js +1 -1
- package/dist/esm/bin/release-kit.js +45 -14
- package/dist/esm/buildChangelogEntries.d.ts +3 -0
- package/dist/esm/{generateChangelogJson.js → buildChangelogEntries.js} +40 -77
- package/dist/esm/buildDependencyGraph.d.ts +4 -3
- package/dist/esm/buildDependencyGraph.js +18 -11
- package/dist/esm/buildReleaseSummary.js +12 -4
- package/dist/esm/buildSyntheticChangelogEntry.d.ts +5 -0
- package/dist/esm/buildSyntheticChangelogEntry.js +13 -0
- package/dist/esm/bumpAllVersions.d.ts +1 -0
- package/dist/esm/bumpAllVersions.js +16 -2
- package/dist/esm/bumpVersion.js +3 -0
- package/dist/esm/changelogJsonFile.d.ts +4 -0
- package/dist/esm/changelogJsonFile.js +68 -0
- package/dist/esm/commitCommand.js +1 -1
- package/dist/esm/compareVersions.d.ts +1 -0
- package/dist/esm/compareVersions.js +27 -0
- package/dist/esm/createGithubRelease.d.ts +6 -2
- package/dist/esm/createGithubRelease.js +17 -17
- package/dist/esm/createGithubReleaseCommand.d.ts +1 -0
- package/dist/esm/createGithubReleaseCommand.js +41 -0
- package/dist/esm/decideRelease.d.ts +25 -0
- package/dist/esm/decideRelease.js +28 -0
- package/dist/esm/defaults.d.ts +1 -0
- package/dist/esm/defaults.js +7 -3
- package/dist/esm/deriveWorkspaceConfig.d.ts +2 -0
- package/dist/esm/deriveWorkspaceConfig.js +37 -0
- package/dist/esm/detectUndeclaredTagPrefixes.d.ts +7 -0
- package/dist/esm/detectUndeclaredTagPrefixes.js +46 -0
- package/dist/esm/generateChangelogs.d.ts +1 -1
- package/dist/esm/generateChangelogs.js +14 -3
- package/dist/esm/getCommitsSinceTarget.d.ts +1 -1
- package/dist/esm/getCommitsSinceTarget.js +8 -4
- package/dist/esm/index.d.ts +2 -39
- package/dist/esm/index.js +0 -75
- package/dist/esm/init/initCommand.js +1 -1
- package/dist/esm/init/scaffold.d.ts +1 -1
- package/dist/esm/init/scaffold.js +8 -5
- package/dist/esm/init/templates.d.ts +1 -0
- package/dist/esm/init/templates.js +35 -5
- package/dist/esm/injectReleaseNotesIntoReadme.d.ts +6 -1
- package/dist/esm/injectReleaseNotesIntoReadme.js +20 -7
- package/dist/esm/loadConfig.d.ts +12 -2
- package/dist/esm/loadConfig.js +161 -14
- package/dist/esm/parseRequestedTags.d.ts +1 -0
- package/dist/esm/parseRequestedTags.js +10 -0
- package/dist/esm/prepareCommand.d.ts +3 -1
- package/dist/esm/prepareCommand.js +121 -31
- package/dist/esm/previewTagPrefixes.d.ts +30 -0
- package/dist/esm/previewTagPrefixes.js +120 -0
- package/dist/esm/propagateBumps.d.ts +1 -0
- package/dist/esm/propagateBumps.js +1 -1
- package/dist/esm/publish.d.ts +0 -1
- package/dist/esm/publish.js +3 -3
- package/dist/esm/publishCommand.js +18 -14
- package/dist/esm/pushCommand.js +5 -4
- package/dist/esm/readCurrentVersion.d.ts +1 -0
- package/dist/esm/readCurrentVersion.js +21 -0
- package/dist/esm/releasePrepare.d.ts +2 -0
- package/dist/esm/releasePrepare.js +140 -54
- package/dist/esm/releasePrepareMono.js +312 -143
- package/dist/esm/releasePrepareProject.d.ts +9 -0
- package/dist/esm/releasePrepareProject.js +109 -0
- package/dist/esm/renderReleaseNotes.d.ts +1 -0
- package/dist/esm/renderReleaseNotes.js +29 -2
- package/dist/esm/reportPrepare.js +146 -73
- package/dist/esm/resolveCliffConfigPath.js +1 -1
- package/dist/esm/resolveCommandTags.d.ts +1 -1
- package/dist/esm/resolveCommandTags.js +17 -13
- package/dist/esm/resolveReleaseNotesConfig.d.ts +8 -1
- package/dist/esm/resolveReleaseNotesConfig.js +17 -7
- package/dist/esm/resolveReleaseTags.d.ts +2 -1
- package/dist/esm/resolveReleaseTags.js +19 -14
- package/dist/esm/showTagPrefixesCommand.d.ts +1 -0
- package/dist/esm/showTagPrefixesCommand.js +84 -0
- package/dist/esm/sync-labels/initCommand.js +1 -1
- package/dist/esm/sync-labels/presets.js +1 -1
- package/dist/esm/tagCommand.js +1 -1
- package/dist/esm/types.d.ts +77 -19
- package/dist/esm/validateConfig.js +205 -36
- package/dist/esm/validateOnlyExcludesStrandedDependents.d.ts +14 -0
- package/dist/esm/validateOnlyExcludesStrandedDependents.js +109 -0
- package/dist/esm/version.d.ts +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/esm/writeReleaseNotesPreviews.d.ts +18 -0
- package/dist/esm/writeReleaseNotesPreviews.js +65 -0
- package/package.json +5 -2
- package/presets/labels/common.yaml +9 -6
- package/schemas/label-map.json +24 -0
- package/dist/esm/component.d.ts +0 -2
- package/dist/esm/component.js +0 -14
- package/dist/esm/findPackageRoot.d.ts +0 -1
- package/dist/esm/findPackageRoot.js +0 -17
- package/dist/esm/generateChangelogJson.d.ts +0 -7
- package/dist/esm/githubReleaseCommand.d.ts +0 -1
- package/dist/esm/githubReleaseCommand.js +0 -35
package/README.md
CHANGED
|
@@ -4,6 +4,52 @@ Version-bumping and changelog-generation toolkit for release workflows.
|
|
|
4
4
|
|
|
5
5
|
Provides a self-contained CLI that auto-discovers workspaces from `pnpm-workspace.yaml`, parses conventional commits, determines version bumps, updates `package.json` files, and generates changelogs with `git-cliff`.
|
|
6
6
|
|
|
7
|
+
<!-- section:release-notes -->
|
|
8
|
+
## Release notes — v5.1.0 (2026-04-30)
|
|
9
|
+
|
|
10
|
+
### Bug fixes
|
|
11
|
+
|
|
12
|
+
- Make publish's clean-tree safety gate reachable (#311)
|
|
13
|
+
|
|
14
|
+
Fixes an issue where `release-kit publish` failed with pnpm's "working tree is dirty" error on a clean tree whenever `releaseNotes.shouldInjectIntoReadme: true` was configured. release-kit injects the release notes into the package README before invoking `pnpm publish`, so pnpm's own working-tree check fired on a tree release-kit had just dirtied — even though the user's tree was clean at command start.
|
|
15
|
+
|
|
16
|
+
- Make `--set-version` + `project` rejection explicit (#319)
|
|
17
|
+
|
|
18
|
+
Improves the error users see when invoking `release-kit prepare --set-version` with a `project` block configured. The combination is still rejected — as before — but now produces a single, project-aware message ("--set-version cannot be combined with a project release…") rather than the previous two-step chain (`--set-version requires --only`, then `--only cannot be combined with a project release` after the user added `--only`).
|
|
19
|
+
|
|
20
|
+
- Reject `--only` that would strand excluded dependents (#321)
|
|
21
|
+
|
|
22
|
+
Fixes a silent footgun in `release-kit prepare --only=...`: an excluded internal dependent with its own changes would be left unreleased with no runtime signal, even though the targeted workspace it depends on was being released. The command now rejects such invocations up front, naming every excluded dependent whose changes would be stranded.
|
|
23
|
+
|
|
24
|
+
- Order prerelease versions correctly in changelog sort (#334)
|
|
25
|
+
|
|
26
|
+
Fixes a latent issue in `@williamthorsen/release-kit` where prerelease version tags (e.g., `1.2.3-alpha`, `1.2.3-rc.1`) were sorted as if their prerelease component were absent, causing them to appear in the wrong position relative to releases sharing the same base version. Changelog entries are now ordered per SemVer §11: prerelease versions precede the corresponding release (`1.2.3-alpha < 1.2.3`), build metadata is ignored for ordering, and entries that fail SemVer validation sort deterministically to the bottom of the list rather than collapsing into mid-list positions.
|
|
27
|
+
|
|
28
|
+
### Features
|
|
29
|
+
|
|
30
|
+
- Add `project` block for project-level release stage (#317)
|
|
31
|
+
|
|
32
|
+
Adds support for monorepos that ship a single combined deliverable to version, changelog, and release-note the project itself rather than only its constituent workspaces.
|
|
33
|
+
|
|
34
|
+
- Publish JSON Schema for `.meta/label-map.json` (#325)
|
|
35
|
+
|
|
36
|
+
Adds a JSON Schema for `.meta/label-map.json` to release-kit, packaged at `packages/release-kit/schemas/label-map.json` and shipped to npm. Consumers reference it via the stable raw URL pattern `https://github.com/williamthorsen/node-monorepo-tools/raw/release-kit-v<version>/packages/release-kit/schemas/label-map.json` — the same shape audit-deps already uses.
|
|
37
|
+
|
|
38
|
+
- Label prepare errors with the failing stage (#326)
|
|
39
|
+
|
|
40
|
+
Adds stage attribution to errors thrown during `release-kit prepare`. Errors from per-workspace bumps and changelog generation, the project release stage, and the post-release format command now begin with a stage label that identifies the failing stage and (where relevant) the affected workspace.
|
|
41
|
+
|
|
42
|
+
- Make `--force` and `--bump` orthogonal (#328)
|
|
43
|
+
|
|
44
|
+
Decouples `--force` and `--bump` so each flag has a single responsibility, and unifies skip semantics across the per-workspace and project pipelines.
|
|
45
|
+
|
|
46
|
+
### Documentation
|
|
47
|
+
|
|
48
|
+
- Document tag prefix collisions as general rule (#320)
|
|
49
|
+
|
|
50
|
+
Documents the strict-prefix tag-prefix collision rule as a general validation rule that applies to every release-kit consumer declaring more than one tag prefix: across active workspaces, declared legacy identities, retired packages, and the optional `project` block. Previously, the rule appeared only inside the `Project releases` validation list.
|
|
51
|
+
<!-- /section:release-notes -->
|
|
52
|
+
|
|
7
53
|
## Installation
|
|
8
54
|
|
|
9
55
|
```bash
|
|
@@ -54,9 +100,9 @@ That's it for most repos. The CLI auto-discovers workspaces and applies sensible
|
|
|
54
100
|
|
|
55
101
|
## How it works
|
|
56
102
|
|
|
57
|
-
1. **Workspace discovery**: reads `pnpm-workspace.yaml` and resolves its `packages` globs to find workspace directories. Each directory containing a `package.json` becomes a
|
|
103
|
+
1. **Workspace discovery**: reads `pnpm-workspace.yaml` and resolves its `packages` globs to find workspace directories. Each directory containing a `package.json` becomes a workspace. If no workspace file is found, the repo is treated as a single-package project.
|
|
58
104
|
2. **Config loading**: loads `.config/release-kit.config.ts` (if present) via [jiti](https://github.com/unjs/jiti) and merges it with discovered defaults.
|
|
59
|
-
3. **Commit analysis**: for each
|
|
105
|
+
3. **Commit analysis**: for each workspace, finds commits since the last version tag, parses them for type and scope, and determines the appropriate version bump.
|
|
60
106
|
4. **Version bump + changelog**: bumps `package.json` versions and generates changelogs via `git-cliff`.
|
|
61
107
|
5. **Release tags file**: writes computed tags to `tmp/.release-tags` for the release workflow to read when tagging and pushing.
|
|
62
108
|
|
|
@@ -73,7 +119,7 @@ scope|type!: description # scoped breaking change
|
|
|
73
119
|
type(scope)!: description # conventional scoped breaking change
|
|
74
120
|
```
|
|
75
121
|
|
|
76
|
-
The `scope|type:` format scopes a commit to a specific
|
|
122
|
+
The `scope|type:` format scopes a commit to a specific workspace in a monorepo. Use `scopeAliases` in your config to map shorthand names to canonical scope names.
|
|
77
123
|
|
|
78
124
|
## Configuration
|
|
79
125
|
|
|
@@ -85,8 +131,8 @@ Configuration is optional. The CLI works out of the box by auto-discovering work
|
|
|
85
131
|
import type { ReleaseKitConfig } from '@williamthorsen/release-kit';
|
|
86
132
|
|
|
87
133
|
const config: ReleaseKitConfig = {
|
|
88
|
-
// Exclude a
|
|
89
|
-
|
|
134
|
+
// Exclude a workspace from release processing
|
|
135
|
+
workspaces: [{ dir: 'internal-tools', shouldExclude: true }],
|
|
90
136
|
|
|
91
137
|
// Run a formatter after changelog generation (modified file paths are appended as arguments)
|
|
92
138
|
formatCommand: 'npx prettier --write',
|
|
@@ -108,23 +154,152 @@ The config file supports both `export default config` and `export const config =
|
|
|
108
154
|
| Field | Type | Description |
|
|
109
155
|
| ----------------- | -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
|
|
110
156
|
| `cliffConfigPath` | `string` | Explicit path to cliff config. If omitted, resolved automatically: `.config/git-cliff.toml` → `cliff.toml` → bundled template |
|
|
111
|
-
| `
|
|
157
|
+
| `workspaces` | `WorkspaceOverride[]` | Override or exclude discovered workspaces (matched by `dir`) |
|
|
112
158
|
| `formatCommand` | `string` | Shell command to run after changelog generation; modified file paths are appended as arguments |
|
|
113
159
|
| `versionPatterns` | `VersionPatterns` | Rules for which commit types trigger major/minor bumps |
|
|
114
160
|
| `scopeAliases` | `Record<string, string>` | Maps shorthand scope names to canonical names in commits |
|
|
115
161
|
| `workTypes` | `Record<string, WorkTypeConfig>` | Work type definitions, merged with defaults by key |
|
|
162
|
+
| `retiredPackages` | `RetiredPackage[]` | Packages that once lived in this repo but have been extracted or removed; suppresses undeclared-tag-prefix warnings |
|
|
163
|
+
| `project` | `ProjectConfig` | Opt-in project-level release block. Declaring `project: {}` (even empty) enables a project-release stage in `prepare` |
|
|
116
164
|
|
|
117
165
|
All fields are optional.
|
|
118
166
|
|
|
119
|
-
### `
|
|
167
|
+
### `WorkspaceOverride`
|
|
120
168
|
|
|
121
169
|
```typescript
|
|
122
|
-
interface
|
|
170
|
+
interface WorkspaceOverride {
|
|
123
171
|
dir: string; // Package directory name (e.g., 'arrays')
|
|
124
172
|
shouldExclude?: boolean; // If true, exclude from release processing
|
|
173
|
+
legacyIdentities?: LegacyIdentity[]; // Prior `(name, tagPrefix)` identities for this workspace
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
interface LegacyIdentity {
|
|
177
|
+
name: string; // Full scoped npm name at the time (e.g., '@scope/pkg')
|
|
178
|
+
tagPrefix: string; // Tag prefix under which historical tags were published (e.g., 'core-v')
|
|
179
|
+
}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
`legacyIdentities` captures prior identities of a workspace as complete `(name, tagPrefix)` snapshots. The union of the current `tagPrefix` and each identity's `tagPrefix` is consulted when release-kit searches for the most recent baseline tag and when generating changelogs. Use it when a workspace's historical tags were published under a different npm name, a different tag prefix, or both — typically across a package rename. Both fields are required per identity: each entry must be a complete historical snapshot that stays valid regardless of subsequent renames. Run `release-kit show-tag-prefixes` to detect undeclared candidates and produce a paste-ready config snippet. Listing the current identity (full `(name, tagPrefix)` match) is rejected as a no-op duplicate; an identity whose `tagPrefix` matches the current but whose `name` differs is valid and documents a prior rename that reused the same tag shape. If the workspace no longer exists in this repo at all (the package was extracted or removed), use [`retiredPackages`](#retiredpackage) instead.
|
|
183
|
+
|
|
184
|
+
### `RetiredPackage`
|
|
185
|
+
|
|
186
|
+
```typescript
|
|
187
|
+
interface RetiredPackage {
|
|
188
|
+
name: string; // Final scoped npm name while the package lived in this repo
|
|
189
|
+
tagPrefix: string; // Tag prefix under which the package's historical tags were published
|
|
190
|
+
successor?: string; // Optional successor package name (e.g., 'readyup')
|
|
191
|
+
}
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
`retiredPackages` is the repo-level complement to `legacyIdentities`. Use `legacyIdentities` when the workspace still exists in this repo under a new identity; use `retiredPackages` when no workspace for this package exists in this repo anymore — the package was extracted to another repo or removed outright. Retired entries are inert: release-kit never consults them for baseline lookup or changelog attribution. Their declared `tagPrefix` values are recognized as historical, so `show-tag-prefixes` stops flagging them under "Undeclared tag prefixes."
|
|
195
|
+
|
|
196
|
+
Worked example — `preflight` was extracted from this monorepo and continues as the standalone `readyup` project. Its tags stay in this repo as historical anchors:
|
|
197
|
+
|
|
198
|
+
```typescript
|
|
199
|
+
import type { ReleaseKitConfig } from '@williamthorsen/release-kit';
|
|
200
|
+
|
|
201
|
+
const config: ReleaseKitConfig = {
|
|
202
|
+
retiredPackages: [{ name: '@scope/preflight', tagPrefix: 'preflight-v', successor: 'readyup' }],
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
export default config;
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
Validation rules:
|
|
209
|
+
|
|
210
|
+
- `name` and `tagPrefix` are required per entry and must be non-empty strings.
|
|
211
|
+
- `successor` is optional; if present, it must be a non-empty string.
|
|
212
|
+
- Full-tuple `(name, tagPrefix)` duplicates within `retiredPackages` are rejected.
|
|
213
|
+
- Two entries sharing the same `tagPrefix` but different `name`s are accepted — this documents a package renamed within the repo before being retired.
|
|
214
|
+
|
|
215
|
+
`show-tag-prefixes` currently does not render a dedicated "Retired packages" section (deferred). Declaring a retired entry is verifiable by confirming that its `tagPrefix` stops appearing under "Undeclared tag prefixes" in the `show-tag-prefixes` output.
|
|
216
|
+
|
|
217
|
+
### Tag prefix collisions
|
|
218
|
+
|
|
219
|
+
Tag prefixes from distinct owners must not be identical or be a strict prefix of one another. An owner is one of:
|
|
220
|
+
|
|
221
|
+
- An active workspace, comprising its derived `tagPrefix` plus any declared `legacyIdentities[].tagPrefix`. Identities of the same workspace are one owner, so their prefixes are allowed to overlap (this represents the same package across renames).
|
|
222
|
+
- A `retiredPackages[]` entry (one owner per entry).
|
|
223
|
+
- The `project` block, when configured.
|
|
224
|
+
|
|
225
|
+
release-kit resolves baseline tags via `git describe --match=<prefix>*`, so a strict-prefix overlap between distinct owners would cause that glob to return cross-matches against the wrong owner's history. For example, a project prefix of `v` collides with a workspace prefix of `vue-helpers-v`, since `git describe --match=v*` would return both project tags and `vue-helpers` tags.
|
|
226
|
+
|
|
227
|
+
The rule is enforced at config load; the resulting error identifies both colliding declarations.
|
|
228
|
+
|
|
229
|
+
### Project releases
|
|
230
|
+
|
|
231
|
+
Some monorepos ship a single combined deliverable — a Chrome extension, a CLI binary, a packaged desktop app — for which the per-workspace tags and changelogs alone do not describe what the user actually receives. Declare the optional `project` block to add a project-level release stage that runs alongside the per-workspace pipeline.
|
|
232
|
+
|
|
233
|
+
```typescript
|
|
234
|
+
import type { ReleaseKitConfig } from '@williamthorsen/release-kit';
|
|
235
|
+
|
|
236
|
+
const config: ReleaseKitConfig = {
|
|
237
|
+
// Empty object is enough to opt in. Every non-excluded workspace contributes.
|
|
238
|
+
project: {},
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
export default config;
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
When configured, each `release-kit prepare` run additionally:
|
|
245
|
+
|
|
246
|
+
- Computes commits since the last project tag (`<tagPrefix><version>`), filtered to the union of every contributing workspace's paths.
|
|
247
|
+
- Bumps the root `package.json`'s `version` field using the same bump-derivation rules as workspaces (or the `--bump=...` override).
|
|
248
|
+
- Regenerates the root `./CHANGELOG.md` via `git-cliff`, scoped to the project's `tagPrefix` and contributing paths.
|
|
249
|
+
- Emits `./.meta/changelog.json` (when `changelogJson.enabled`).
|
|
250
|
+
- With `--with-release-notes`, additionally emits `./docs/RELEASE_NOTES.v<version>.md`.
|
|
251
|
+
- Appends the project tag to `tmp/.release-tags` so `release-kit commit` and `release-kit tag` pick it up alongside per-workspace tags.
|
|
252
|
+
|
|
253
|
+
If no contributing workspace has commits since the last project tag, the project release is silently skipped — same behavior as a per-workspace skip.
|
|
254
|
+
|
|
255
|
+
#### `ProjectConfig`
|
|
256
|
+
|
|
257
|
+
```typescript
|
|
258
|
+
interface ProjectConfig {
|
|
259
|
+
tagPrefix?: string; // Defaults to 'v'
|
|
125
260
|
}
|
|
126
261
|
```
|
|
127
262
|
|
|
263
|
+
| Field | Default | Description |
|
|
264
|
+
| ----------- | ------- | -------------------------------------------------------------------- |
|
|
265
|
+
| `tagPrefix` | `'v'` | Prefix for project tags. The full tag is `${tagPrefix}${newVersion}` |
|
|
266
|
+
|
|
267
|
+
Contributing workspaces are implicit: every non-excluded discovered workspace contributes. There is no field to override the contributing set in this initial release; if a future consumer needs to release a workspace as a component but exclude it from the project release, that override can be added then.
|
|
268
|
+
|
|
269
|
+
Validation rules:
|
|
270
|
+
|
|
271
|
+
- The root `package.json` must exist and declare a `version` field. release-kit reports an error at config-load time if either is missing.
|
|
272
|
+
- The `project` block is rejected in single-package mode (the implicit "all non-excluded workspaces contribute" rule is meaningless in a single-package repo).
|
|
273
|
+
- Unknown fields inside `project` are rejected.
|
|
274
|
+
|
|
275
|
+
CLI flag interactions:
|
|
276
|
+
|
|
277
|
+
- `--dry-run` previews project artifacts alongside workspace artifacts; no files are written.
|
|
278
|
+
- `--bump=major|minor|patch` propagates to the project release as a level chooser. It does not trigger a release on its own when there are no commits or no bump-worthy commits.
|
|
279
|
+
- `--force` runs the project release even when no commits or no bump-worthy commits exist since the last project tag. Defaults to patch when `--bump` is not given; combine with `--bump=X` to release at a different level.
|
|
280
|
+
- `--only` is rejected with an error when `project` is configured. `--only` is a surgical, single-workspace operation; combining it with a project release that rolls up every contributing workspace would create ambiguous semantics. To release a single workspace, use a config without a `project` block, or run a full `prepare` (no `--only`) to include the project release.
|
|
281
|
+
- `--set-version` is rejected with an error when `project` is configured. `--set-version` operates on a single workspace, but a project release rolls up every contributing workspace; the two semantics don't compose. To use `--set-version`, run on a config without a `project` block.
|
|
282
|
+
|
|
283
|
+
`--bump` and `--force` are orthogonal: `--bump` is purely a level chooser; `--force` is purely a release trigger. Examples:
|
|
284
|
+
|
|
285
|
+
```sh
|
|
286
|
+
# Release every target at its natural bump level (no flags).
|
|
287
|
+
release-kit prepare
|
|
288
|
+
|
|
289
|
+
# Force a release even when no bump-worthy commits exist; defaults to patch
|
|
290
|
+
# per target, with each target keeping its natural bump if one is derivable.
|
|
291
|
+
release-kit prepare --force
|
|
292
|
+
|
|
293
|
+
# Force a release at a uniform level across every releasing target.
|
|
294
|
+
release-kit prepare --force --bump=minor
|
|
295
|
+
|
|
296
|
+
# --bump=X alone is a level chooser, NOT a trigger. If a target has no
|
|
297
|
+
# bump-worthy commits, it skips with a "Pass --force..." reason. If it has
|
|
298
|
+
# bump-worthy commits, the override applies. (Behavioral change from earlier
|
|
299
|
+
# release-kit versions, where --bump=X alone would force a release.)
|
|
300
|
+
release-kit prepare --bump=minor
|
|
301
|
+
```
|
|
302
|
+
|
|
128
303
|
### `VersionPatterns`
|
|
129
304
|
|
|
130
305
|
Defines which commit types trigger major or minor bumps. Any recognized type not listed defaults to a patch bump.
|
|
@@ -140,21 +315,29 @@ Default: `{ major: ['!'], minor: ['feat'] }`
|
|
|
140
315
|
|
|
141
316
|
### Default work types
|
|
142
317
|
|
|
143
|
-
| Key
|
|
144
|
-
|
|
|
145
|
-
| `fix`
|
|
146
|
-
| `
|
|
147
|
-
| `
|
|
148
|
-
| `
|
|
149
|
-
| `
|
|
150
|
-
| `
|
|
151
|
-
| `
|
|
152
|
-
| `
|
|
153
|
-
| `
|
|
154
|
-
| `
|
|
318
|
+
| Key | Header | Aliases |
|
|
319
|
+
| ----------- | --------------- | ------------- |
|
|
320
|
+
| `fix` | Bug fixes | `bugfix` |
|
|
321
|
+
| `deprecate` | Deprecated | |
|
|
322
|
+
| `feat` | Features | `feature` |
|
|
323
|
+
| `internal` | Internal | |
|
|
324
|
+
| `perf` | Performance | `performance` |
|
|
325
|
+
| `refactor` | Refactoring | |
|
|
326
|
+
| `sec` | Security | `security` |
|
|
327
|
+
| `tests` | Tests | `test` |
|
|
328
|
+
| `tooling` | Tooling | |
|
|
329
|
+
| `ci` | CI | |
|
|
330
|
+
| `deps` | Dependencies | `dep` |
|
|
331
|
+
| `docs` | Documentation | `doc` |
|
|
332
|
+
| `ai` | Agentic support | |
|
|
333
|
+
| `fmt` | (skipped) | |
|
|
155
334
|
|
|
156
335
|
Work types from your config are merged with these defaults by key — your entries override or extend, they don't replace the full set.
|
|
157
336
|
|
|
337
|
+
`fmt:` commits are recognized for version-bump determination (they contribute to a patch bump) but are skipped by the bundled `cliff.toml.template`, so they do not appear in `CHANGELOG.md` or release notes.
|
|
338
|
+
|
|
339
|
+
Release-notes sections are rendered in the declaration order of the merged work-types record, with any unknown titles trailing the known ones. The default `devOnlySections` (excluded from public release notes but still written to `CHANGELOG.md`) are: `Agentic support`, `CI`, `Dependencies`, `Internal`, `Refactoring`, `Tests`, `Tooling`. Override via `changelogJson.devOnlySections` in your config.
|
|
340
|
+
|
|
158
341
|
## CLI reference
|
|
159
342
|
|
|
160
343
|
### Global options
|
|
@@ -168,15 +351,82 @@ Work types from your config are merged with these defaults by key — your entri
|
|
|
168
351
|
|
|
169
352
|
Run release preparation with automatic workspace discovery.
|
|
170
353
|
|
|
171
|
-
| Flag | Description
|
|
172
|
-
| ---------------------------- |
|
|
173
|
-
| `--dry-run` | Preview changes without writing files
|
|
174
|
-
| `--bump=major\|minor\|patch` | Override the bump type for all
|
|
175
|
-
| `--
|
|
176
|
-
| `--
|
|
177
|
-
| `--
|
|
354
|
+
| Flag | Description |
|
|
355
|
+
| ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
356
|
+
| `--dry-run` | Preview changes without writing files |
|
|
357
|
+
| `--bump=major\|minor\|patch` | Override the bump type for all workspaces |
|
|
358
|
+
| `--set-version=X.Y.Z` | Set an explicit canonical semver version; bypasses commit-derived bumps. Requires `--only` in monorepo mode. |
|
|
359
|
+
| `--force` | Release even when no commits or no bump-worthy commits exist since the last tag (defaults to patch; combine with `--bump=X` for a different level) |
|
|
360
|
+
| `--only=name1,name2` | Only process the named workspaces (monorepo only; rejected when a `project` block is configured) |
|
|
361
|
+
| `--with-release-notes` | Write per-workspace release-notes previews under `{workspacePath}/docs/` |
|
|
362
|
+
| `--help`, `-h` | Show help |
|
|
363
|
+
|
|
364
|
+
Workspace names for `--only` match the package directory name (e.g., `arrays`, `release-kit`).
|
|
365
|
+
|
|
366
|
+
#### Previewing release notes with `--with-release-notes`
|
|
367
|
+
|
|
368
|
+
`--with-release-notes` writes two versioned files per workspace after each workspace's `changelog.json` is produced:
|
|
369
|
+
|
|
370
|
+
- `{workspacePath}/docs/README.v{version}.md` — the workspace `README.md` with release notes injected at the `<!-- section:release-notes -->` marker.
|
|
371
|
+
- `{workspacePath}/docs/RELEASE_NOTES.v{version}.md` — the standalone release notes for this version.
|
|
372
|
+
|
|
373
|
+
The publish-time inject-and-revert lifecycle is unchanged; previews are additive, deterministic, and safe to regenerate. When `changelogJson.enabled` is `false`, the flag logs a warning and skips preview generation. In dry-run mode, planned writes are logged and no files are created.
|
|
374
|
+
|
|
375
|
+
Because preview filenames are versioned, committing them will accumulate files over time. The recommended `.gitignore` entry for monorepos is:
|
|
376
|
+
|
|
377
|
+
```gitignore
|
|
378
|
+
packages/*/docs/*.v*.md
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
For single-package repos:
|
|
382
|
+
|
|
383
|
+
```gitignore
|
|
384
|
+
docs/*.v*.md
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
#### Setting an explicit version with `--set-version`
|
|
388
|
+
|
|
389
|
+
The `--set-version` flag is a first-class escape hatch for the cases where commit-derived bump logic produces the wrong version — most notably, promoting a pre-1.0 package to 1.0.0. Pre-1.0 packages collapse a `feat!` breaking change to a minor bump (matching semantic-release's `initialMajor: false` and release-please's `bump-minor-pre-major`), so a deliberate promotion to 1.0.0 must be requested explicitly.
|
|
390
|
+
|
|
391
|
+
The flag validates that:
|
|
392
|
+
|
|
393
|
+
- The value is canonical `N.N.N` semver (pre-release suffixes are rejected).
|
|
394
|
+
- The target is strictly greater than the current version (numeric comparison on each component).
|
|
395
|
+
- In monorepo mode, `--only` is set and resolves to exactly one workspace.
|
|
396
|
+
|
|
397
|
+
`--set-version` is mutually exclusive with `--bump` and `--force`. The rest of the pipeline (changelog generation, tag creation, commit summary, propagation to dependents) runs unchanged, so dependents receive a propagated patch bump triggered by the overridden version.
|
|
398
|
+
|
|
399
|
+
Promoting a pre-1.0 package to 1.0.0 in a monorepo:
|
|
178
400
|
|
|
179
|
-
|
|
401
|
+
```sh
|
|
402
|
+
release-kit prepare --only arrays --set-version 1.0.0
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
An empty changelog section is expected for a bare promotion, because the changelog is generated from commits since the last tag. To include a narrative entry, land a descriptive release commit (e.g., a `feat!` describing the stable API) before running `prepare`.
|
|
406
|
+
|
|
407
|
+
### `release-kit create-github-release`
|
|
408
|
+
|
|
409
|
+
Create GitHub Releases from `changelog.json` for tags on HEAD. Independent of `npm publish`: invoking this command creates Releases regardless of whether the matching package was published.
|
|
410
|
+
|
|
411
|
+
| Flag | Description |
|
|
412
|
+
| ---------------------- | ------------------------------------------------------------------------- |
|
|
413
|
+
| `--dry-run` | Preview without creating releases |
|
|
414
|
+
| `--tags=tag1,tag2,...` | Only create releases for the named tags (comma-separated, full tag names) |
|
|
415
|
+
| `--help`, `-h` | Show help |
|
|
416
|
+
|
|
417
|
+
When `--tags` is omitted, every release tag pointing at HEAD is processed. The CLI requires the `gh` CLI on `PATH` and `contents: write` permission. The bundled `create-github-release.reusable.yaml` GitHub Actions workflow runs this command in CI.
|
|
418
|
+
|
|
419
|
+
### `release-kit show-tag-prefixes`
|
|
420
|
+
|
|
421
|
+
Print a per-workspace table of derived tag prefixes, tag counts, and declared legacy prefixes. Also surfaces any release-shaped tag prefix in the repo that is neither a derived prefix nor declared via `legacyIdentities`, along with a copy-pasteable `workspaces: [...]` config snippet. The snippet uses a `TODO-fill-in-legacy-npm-name` placeholder for each identity's `name`; replace it with the package's prior npm name before pasting.
|
|
422
|
+
|
|
423
|
+
| Flag | Description |
|
|
424
|
+
| -------------- | ----------- |
|
|
425
|
+
| `--help`, `-h` | Show help |
|
|
426
|
+
|
|
427
|
+
Exits `0` when every workspace derives a prefix and there are no cross-workspace collisions; exits `1` on any derivation failure or collision. Undeclared candidates do not affect the exit code — they surface as a warning via the `legacy tag prefixes are declared` readyup check.
|
|
428
|
+
|
|
429
|
+
In single-package mode, prints a single row with `workspacePath = .` and `derivedPrefix = v`; legacy entries and undeclared-candidate scanning are not applicable.
|
|
180
430
|
|
|
181
431
|
### `release-kit init`
|
|
182
432
|
|
|
@@ -191,6 +441,8 @@ Initialize release-kit in the current repository. By default, scaffolds only the
|
|
|
191
441
|
|
|
192
442
|
Scaffolded files:
|
|
193
443
|
|
|
444
|
+
- `.github/workflows/create-github-release.yaml` — workflow that creates a GitHub Release on tag push, independent of npm publish
|
|
445
|
+
- `.github/workflows/publish.yaml` — workflow that delegates to a reusable publish workflow
|
|
194
446
|
- `.github/workflows/release.yaml` — workflow that delegates to a reusable release workflow
|
|
195
447
|
- `.config/release-kit.config.ts` — starter config with commented-out customization examples (with `--with-config`)
|
|
196
448
|
- `.config/git-cliff.toml` — copied from the bundled template (with `--with-config`)
|
|
@@ -207,13 +459,33 @@ Manage GitHub label definitions via config-driven YAML files.
|
|
|
207
459
|
|
|
208
460
|
`init` scaffolds `.config/sync-labels.config.ts` with auto-detected workspace scope labels and a `.github/workflows/sync-labels.yaml` caller workflow, then generates `.github/labels.yaml`. `generate` reads the config and writes `.github/labels.yaml`. `sync` triggers the workflow remotely — it requires the `gh` CLI and an existing workflow file.
|
|
209
461
|
|
|
462
|
+
#### Published JSON Schema for `.meta/label-map.json`
|
|
463
|
+
|
|
464
|
+
release-kit publishes a JSON Schema for `.meta/label-map.json` — a separate, generic data file that maps commit-prefix scopes and types to GitHub label names. The schema lives at `packages/release-kit/schemas/label-map.json` in this repo and is reachable via the stable raw URL:
|
|
465
|
+
|
|
466
|
+
```
|
|
467
|
+
https://github.com/williamthorsen/node-monorepo-tools/raw/release-kit-v<version>/packages/release-kit/schemas/label-map.json
|
|
468
|
+
```
|
|
469
|
+
|
|
470
|
+
Consumers reference it from the top of their `.meta/label-map.json`:
|
|
471
|
+
|
|
472
|
+
```json
|
|
473
|
+
{
|
|
474
|
+
"$schema": "https://github.com/williamthorsen/node-monorepo-tools/raw/release-kit-v<version>/packages/release-kit/schemas/label-map.json",
|
|
475
|
+
"types": { "feat": "feature", "fix": "fix" },
|
|
476
|
+
"scopes": { "audit": "scope:audit" }
|
|
477
|
+
}
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
release-kit publishes the schema only; it does not generate `.meta/label-map.json`. Generation requires commit-prefix knowledge that lives outside release-kit (in agent-conventions tooling), and is owned by those consumers.
|
|
481
|
+
|
|
210
482
|
## GitHub Actions workflow
|
|
211
483
|
|
|
212
484
|
The `init` command scaffolds a release workflow at `.github/workflows/release.yaml` that delegates to a reusable release workflow. The scaffolded workflow accepts these inputs:
|
|
213
485
|
|
|
214
486
|
| Input | Type | Description |
|
|
215
487
|
| ------ | ------ | ------------------------------------------------------------------- |
|
|
216
|
-
| `only` | string |
|
|
488
|
+
| `only` | string | Workspaces to release (comma-separated, leave empty for all) |
|
|
217
489
|
| `bump` | choice | Override bump type: `patch`, `minor`, `major` (empty = auto-detect) |
|
|
218
490
|
|
|
219
491
|
For repos that need a self-contained workflow instead of the reusable one, the scaffolded file can be expanded. The key steps are: checkout with full history (`fetch-depth: 0`), run `release-kit prepare` with optional `--only` and `--bump` flags, check for changes, read tags from `tmp/.release-tags`, then commit, tag, and push.
|
|
@@ -221,10 +493,10 @@ For repos that need a self-contained workflow instead of the reusable one, the s
|
|
|
221
493
|
### Triggering a release
|
|
222
494
|
|
|
223
495
|
```sh
|
|
224
|
-
# All
|
|
496
|
+
# All workspaces
|
|
225
497
|
gh workflow run release.yaml
|
|
226
498
|
|
|
227
|
-
# Specific
|
|
499
|
+
# Specific workspace(s)
|
|
228
500
|
gh workflow run release.yaml -f only=arrays
|
|
229
501
|
gh workflow run release.yaml -f only=arrays,strings -f bump=minor
|
|
230
502
|
```
|
|
@@ -257,25 +529,57 @@ This package shells out to two external tools:
|
|
|
257
529
|
- **`git`** — must be available on `PATH`. Used to find tags and retrieve commit history.
|
|
258
530
|
- **`git-cliff`** — automatically downloaded and cached via `npx` on first invocation. No need to install it as a dev dependency.
|
|
259
531
|
|
|
260
|
-
##
|
|
532
|
+
## Upgrading from v4 to v5
|
|
533
|
+
|
|
534
|
+
Release-kit v5 derives each workspace's tag prefix from its unscoped `package.json` `name`, so a package at `packages/core` with `"name": "@scope/nmr-core"` uses tags like `nmr-core-v1.3.0`. Repos that previously tagged under the directory basename (e.g., `core-v1.3.0`) do not need to rewrite history — declare the prior identity in `legacyIdentities` so release-kit recognizes historical tags under both the new and old prefixes.
|
|
535
|
+
|
|
536
|
+
Minimal worked example for a repo whose pre-v5 tags were `core-v0.2.7` and whose npm name has not changed:
|
|
537
|
+
|
|
538
|
+
```typescript
|
|
539
|
+
// .config/release-kit.config.ts
|
|
540
|
+
import type { ReleaseKitConfig } from '@williamthorsen/release-kit';
|
|
541
|
+
|
|
542
|
+
const config: ReleaseKitConfig = {
|
|
543
|
+
workspaces: [
|
|
544
|
+
{
|
|
545
|
+
dir: 'core',
|
|
546
|
+
legacyIdentities: [{ name: '@scope/nmr-core', tagPrefix: 'core-v' }],
|
|
547
|
+
},
|
|
548
|
+
],
|
|
549
|
+
};
|
|
550
|
+
|
|
551
|
+
export default config;
|
|
552
|
+
```
|
|
553
|
+
|
|
554
|
+
Each `legacyIdentity` is a complete `(name, tagPrefix)` snapshot of the workspace at an earlier point. In the common case — the tag-derivation rule changed but the npm name did not — the identity's `name` equals the current `name`. If an earlier publish used a different npm name, use that prior name here.
|
|
555
|
+
|
|
556
|
+
Verify with `release-kit show-tag-prefixes` — it prints the derived prefix per workspace, tag counts under each declared legacy prefix, and any undeclared release-shaped prefixes it finds in the repo (with a copy-pasteable config snippet that includes a `TODO-fill-in-legacy-npm-name` placeholder to replace with the prior npm name). After declaring, `release-kit prepare` consults the union of the current and legacy tag prefixes when searching for the most recent baseline tag, and changelog generation matches tags under either prefix.
|
|
261
557
|
|
|
262
|
-
|
|
558
|
+
See the `legacyIdentities` entry in the [`WorkspaceOverride`](#workspaceoverride) section for the config shape.
|
|
559
|
+
|
|
560
|
+
## Using `deriveWorkspaceConfig()` for manual configuration
|
|
561
|
+
|
|
562
|
+
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:
|
|
263
563
|
|
|
264
564
|
```typescript
|
|
265
|
-
import {
|
|
565
|
+
import { deriveWorkspaceConfig } from '@williamthorsen/release-kit';
|
|
266
566
|
|
|
267
|
-
//
|
|
268
|
-
|
|
567
|
+
// packages/arrays/package.json contains `"name": "@scope/arrays"`
|
|
568
|
+
deriveWorkspaceConfig('packages/arrays');
|
|
269
569
|
// => {
|
|
270
570
|
// dir: 'arrays',
|
|
571
|
+
// name: '@scope/arrays',
|
|
271
572
|
// tagPrefix: 'arrays-v',
|
|
573
|
+
// workspacePath: 'packages/arrays',
|
|
272
574
|
// packageFiles: ['packages/arrays/package.json'],
|
|
273
575
|
// changelogPaths: ['packages/arrays'],
|
|
274
576
|
// paths: ['packages/arrays/**'],
|
|
275
577
|
// }
|
|
276
578
|
```
|
|
277
579
|
|
|
278
|
-
|
|
580
|
+
`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`.
|
|
581
|
+
|
|
582
|
+
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.
|
|
279
583
|
|
|
280
584
|
## Legacy script-based approach
|
|
281
585
|
|
|
@@ -284,10 +588,10 @@ The CLI-driven approach is recommended for new setups. The script-based approach
|
|
|
284
588
|
```typescript
|
|
285
589
|
// .github/scripts/release.config.ts
|
|
286
590
|
import type { MonorepoReleaseConfig } from '@williamthorsen/release-kit';
|
|
287
|
-
import {
|
|
591
|
+
import { deriveWorkspaceConfig } from '@williamthorsen/release-kit';
|
|
288
592
|
|
|
289
593
|
export const config: MonorepoReleaseConfig = {
|
|
290
|
-
|
|
594
|
+
workspaces: [deriveWorkspaceConfig('packages/arrays'), deriveWorkspaceConfig('packages/strings')],
|
|
291
595
|
formatCommand: 'npx prettier --write',
|
|
292
596
|
};
|
|
293
597
|
```
|
|
@@ -300,10 +604,70 @@ import { config } from './release.config.ts';
|
|
|
300
604
|
runReleasePrepare(config);
|
|
301
605
|
```
|
|
302
606
|
|
|
303
|
-
The key difference: the script-based approach requires manually listing every
|
|
607
|
+
The key difference: the script-based approach requires manually listing every workspace, while the CLI auto-discovers them from `pnpm-workspace.yaml`.
|
|
304
608
|
|
|
305
609
|
## Breaking changes
|
|
306
610
|
|
|
611
|
+
### `resolveReleaseTags` takes workspaces; `WorkspaceConfig` requires `workspacePath`
|
|
612
|
+
|
|
613
|
+
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.
|
|
614
|
+
|
|
615
|
+
- `resolveReleaseTags` signature changed from `(workspaceMap?: Map<string, string>)` to `(workspaces?: readonly WorkspaceConfig[])`.
|
|
616
|
+
- `WorkspaceConfig` gained a required `workspacePath: string` field.
|
|
617
|
+
|
|
618
|
+
Replace direct `Map`-based calls with `deriveWorkspaceConfig()`, which now populates `workspacePath` for you:
|
|
619
|
+
|
|
620
|
+
```diff
|
|
621
|
+
-import { resolveReleaseTags } from '@williamthorsen/release-kit';
|
|
622
|
+
-
|
|
623
|
+
-const workspaceMap = new Map([['core', 'packages/core']]);
|
|
624
|
+
-resolveReleaseTags(workspaceMap);
|
|
625
|
+
+import { deriveWorkspaceConfig, resolveReleaseTags } from '@williamthorsen/release-kit';
|
|
626
|
+
+
|
|
627
|
+
+resolveReleaseTags([deriveWorkspaceConfig('packages/core')]);
|
|
628
|
+
```
|
|
629
|
+
|
|
630
|
+
If you construct `WorkspaceConfig` objects directly, add `workspacePath` alongside the other required fields.
|
|
631
|
+
|
|
632
|
+
### `release-kit publish` and `release-kit push` replace `--only` with `--tags`
|
|
633
|
+
|
|
634
|
+
The `--only=<dir>` flag on `release-kit publish` and `release-kit push` has been removed. Both commands now filter by full tag name via `--tags=<tag1>[,<tag2>...]`, matching `release-kit create-github-release`. Passing `--only=...` after upgrading produces an `Unknown option: --only` error.
|
|
635
|
+
|
|
636
|
+
Local usage mapping:
|
|
637
|
+
|
|
638
|
+
```diff
|
|
639
|
+
-release-kit publish --only=core
|
|
640
|
+
+release-kit publish --tags=core-v1.3.0
|
|
641
|
+
|
|
642
|
+
-release-kit push --only=core,cli
|
|
643
|
+
+release-kit push --tags=core-v1.3.0,cli-v0.5.0
|
|
644
|
+
```
|
|
645
|
+
|
|
646
|
+
Omitting `--tags` preserves the previous behavior of operating on every release tag at HEAD. The reusable workflow `publish.reusable.yaml` also accepts an optional `tags:` input, and the scaffolded `publish.yaml` now passes `tags: ${{ github.ref_name }}` so the publish scope is explicit rather than relying on `actions/checkout@v6`'s fetch default. Existing callers that do not set `tags:` continue to work unchanged.
|
|
647
|
+
|
|
648
|
+
### GitHub Release creation moved to its own command and workflow
|
|
649
|
+
|
|
650
|
+
`release-kit publish` no longer creates GitHub Releases as a side effect, and the `releaseNotes.shouldCreateGithubRelease` config field has been removed. Adoption is now signaled by installing the dedicated `create-github-release.reusable.yaml` workflow.
|
|
651
|
+
|
|
652
|
+
If you previously set the field, remove it from `.config/release-kit.config.ts`. The new caller template (scaffolded by `release-kit init`) looks like this:
|
|
653
|
+
|
|
654
|
+
```yaml
|
|
655
|
+
name: Create GitHub Release
|
|
656
|
+
on:
|
|
657
|
+
push:
|
|
658
|
+
tags:
|
|
659
|
+
- '*-v[0-9]*.[0-9]*.[0-9]*'
|
|
660
|
+
permissions:
|
|
661
|
+
contents: write
|
|
662
|
+
jobs:
|
|
663
|
+
create-github-release:
|
|
664
|
+
uses: williamthorsen/node-monorepo-tools/.github/workflows/create-github-release.reusable.yaml@workflow/create-github-release-v1
|
|
665
|
+
with:
|
|
666
|
+
tag: ${{ github.ref_name }}
|
|
667
|
+
```
|
|
668
|
+
|
|
669
|
+
The CLI command was renamed from `release-kit github-release` to `release-kit create-github-release`, and its filter flag changed from `--only=<package-name>` to `--tags=<full-tag-name>[,...]`.
|
|
670
|
+
|
|
307
671
|
### v1.1.0: `formatCommand` receives file paths as trailing arguments
|
|
308
672
|
|
|
309
673
|
Previously, `formatCommand` was executed as-is (e.g., `pnpm run fmt` would run without arguments). Now, the paths of all modified files (package.json files and changelogs) are appended as trailing arguments.
|
package/cliff.toml.template
CHANGED
|
@@ -61,6 +61,7 @@ commit_preprocessors = []
|
|
|
61
61
|
commit_parsers = [
|
|
62
62
|
{ message = "^release:", skip = true },
|
|
63
63
|
{ message = "^Merge", skip = true },
|
|
64
|
+
{ message = "^(\\#\\d+([.\\-]\\d+)?|\\#\\#|[A-Z]+-\\d+)\\s+([\\w-]+\\|)?ai(!)?:", group = "Agentic support" },
|
|
64
65
|
{ message = "^(\\#\\d+([.\\-]\\d+)?|\\#\\#|[A-Z]+-\\d+)\\s+([\\w-]+\\|)?bugfix(!)?:", group = "Bug fixes" },
|
|
65
66
|
{ message = "^(\\#\\d+([.\\-]\\d+)?|\\#\\#|[A-Z]+-\\d+)\\s+([\\w-]+\\|)?ci(!)?:", group = "CI" },
|
|
66
67
|
{ message = "^(\\#\\d+([.\\-]\\d+)?|\\#\\#|[A-Z]+-\\d+)\\s+([\\w-]+\\|)?deprecate(!)?:", group = "Deprecated" },
|
|
@@ -69,7 +70,7 @@ commit_parsers = [
|
|
|
69
70
|
{ message = "^(\\#\\d+([.\\-]\\d+)?|\\#\\#|[A-Z]+-\\d+)\\s+([\\w-]+\\|)?feat(!)?:", group = "Features" },
|
|
70
71
|
{ message = "^(\\#\\d+([.\\-]\\d+)?|\\#\\#|[A-Z]+-\\d+)\\s+([\\w-]+\\|)?feature(!)?:", group = "Features" },
|
|
71
72
|
{ message = "^(\\#\\d+([.\\-]\\d+)?|\\#\\#|[A-Z]+-\\d+)\\s+([\\w-]+\\|)?fix(!)?:", group = "Bug fixes" },
|
|
72
|
-
{ message = "^(\\#\\d+([.\\-]\\d+)?|\\#\\#|[A-Z]+-\\d+)\\s+([\\w-]+\\|)?fmt(!)?:",
|
|
73
|
+
{ message = "^(\\#\\d+([.\\-]\\d+)?|\\#\\#|[A-Z]+-\\d+)\\s+([\\w-]+\\|)?fmt(!)?:", skip = true },
|
|
73
74
|
{ message = "^(\\#\\d+([.\\-]\\d+)?|\\#\\#|[A-Z]+-\\d+)\\s+([\\w-]+\\|)?internal(!)?:", group = "Internal" },
|
|
74
75
|
{ message = "^(\\#\\d+([.\\-]\\d+)?|\\#\\#|[A-Z]+-\\d+)\\s+([\\w-]+\\|)?perf(!)?:", group = "Performance" },
|
|
75
76
|
{ message = "^(\\#\\d+([.\\-]\\d+)?|\\#\\#|[A-Z]+-\\d+)\\s+([\\w-]+\\|)?performance(!)?:", group = "Performance" },
|
package/dist/esm/.cache
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
fca70d83414ef35352e152c9e916f24705c93c5556b14c16388a5b791752f075
|
|
@@ -6,7 +6,7 @@ function assertCleanWorkingTree() {
|
|
|
6
6
|
}).trim();
|
|
7
7
|
if (status.length > 0) {
|
|
8
8
|
throw new Error(
|
|
9
|
-
"Working tree has uncommitted changes. Commit or stash them
|
|
9
|
+
"Working tree has uncommitted changes. Commit or stash them, or use --no-git-checks to bypass this check."
|
|
10
10
|
);
|
|
11
11
|
}
|
|
12
12
|
}
|