@williamthorsen/release-kit 0.2.3 → 1.0.1
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 +45 -1
- package/README.md +204 -215
- package/dist/esm/.cache +1 -1
- package/dist/esm/bin/release-kit.js +24 -1
- package/dist/esm/component.d.ts +2 -0
- package/dist/esm/component.js +15 -0
- package/dist/esm/defaults.d.ts +3 -2
- package/dist/esm/defaults.js +17 -12
- package/dist/esm/determineBumpType.d.ts +2 -2
- package/dist/esm/determineBumpType.js +11 -13
- package/dist/esm/discoverWorkspaces.d.ts +1 -0
- package/dist/esm/discoverWorkspaces.js +45 -0
- package/dist/esm/getCommitsSinceTarget.js +2 -1
- package/dist/esm/index.d.ts +5 -3
- package/dist/esm/index.js +10 -3
- package/dist/esm/init/checks.js +2 -2
- package/dist/esm/init/initCommand.js +3 -6
- package/dist/esm/init/scaffold.js +2 -51
- package/dist/esm/init/templates.d.ts +0 -1
- package/dist/esm/init/templates.js +26 -42
- package/dist/esm/loadConfig.d.ts +5 -0
- package/dist/esm/loadConfig.js +93 -0
- package/dist/esm/parseCommitMessage.d.ts +1 -1
- package/dist/esm/parseCommitMessage.js +4 -4
- package/dist/esm/prepareCommand.d.ts +1 -0
- package/dist/esm/prepareCommand.js +77 -0
- package/dist/esm/releasePrepare.js +5 -2
- package/dist/esm/releasePrepareMono.js +11 -6
- package/dist/esm/runReleasePrepare.d.ts +8 -2
- package/dist/esm/runReleasePrepare.js +13 -18
- package/dist/esm/types.d.ts +22 -4
- package/dist/esm/validateConfig.d.ts +5 -0
- package/dist/esm/validateConfig.js +143 -0
- package/dist/tsconfig.generate-typings.tsbuildinfo +1 -1
- package/package.json +9 -4
package/CHANGELOG.md
CHANGED
|
@@ -2,7 +2,51 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
-
## [release-kit-
|
|
5
|
+
## [release-kit-v1.0.1] - 2026-03-12
|
|
6
|
+
|
|
7
|
+
### Bug fixes
|
|
8
|
+
|
|
9
|
+
- #34 release-kit|fix: Fix failure to find consumer's config (#35)
|
|
10
|
+
|
|
11
|
+
Resolves the config file path to an absolute path using `process.cwd()` before passing it to both `existsSync` and `jiti.import()`. Previously, `jiti.import()` received a bare relative path which it resolved against `import.meta.url` (the package's install location), making it impossible for consumers to load their config files. Also fixes root tsconfig includes to cover `.config/` and removes a stale duplicate comment.
|
|
12
|
+
|
|
13
|
+
## [release-kit-v1.0.0] - 2026-03-12
|
|
14
|
+
|
|
15
|
+
### Features
|
|
16
|
+
|
|
17
|
+
- #28 release-kit|feat!: Migrate to CLI-driven release preparation with auto-discovery (#31)
|
|
18
|
+
|
|
19
|
+
Replaces release-kit's script-based release preparation with a self-contained CLI (`npx @williamthorsen/release-kit prepare`) that auto-discovers workspaces from `pnpm-workspace.yaml`. Adds workspace auto-discovery, TypeScript config loading via jiti, config validation, and a `component()` factory that accepts full workspace-relative paths. Refactors the type system: `WorkTypeConfig` becomes a record keyed by type name, version-bump rules move to a separate `VersionPatterns` structure, and `ComponentConfig` gains a `dir` field for canonical directory identity.
|
|
20
|
+
|
|
21
|
+
### Refactoring
|
|
22
|
+
|
|
23
|
+
- #28 release-kit|refactor: Adjust location of config & tags file
|
|
24
|
+
|
|
25
|
+
### Tooling
|
|
26
|
+
|
|
27
|
+
- #28 release-kit|tooling: Remove legacy release-kit scripts
|
|
28
|
+
|
|
29
|
+
## [release-kit-v0.3.0] - 2026-03-11
|
|
30
|
+
|
|
31
|
+
### Features
|
|
32
|
+
|
|
33
|
+
- Release-kit|feat: Extract CLI runner into release-kit and co-locate scripts with workflow
|
|
34
|
+
|
|
35
|
+
Move release script logic (arg parsing, validation, component filtering) into a reusable `runReleasePrepare` function in the release-kit package. Consuming repos now provide only their config and call `runReleasePrepare(config)`.
|
|
36
|
+
|
|
37
|
+
Relocate release-prepare.ts and release.config.ts from scripts/ to .github/scripts/ so they live alongside the workflow they serve.
|
|
38
|
+
|
|
39
|
+
- #20 release-kit|feat: Add release-kit init CLI command for automated repo setup (#22)
|
|
40
|
+
|
|
41
|
+
Add an interactive `npx release-kit init` CLI command that checks repo eligibility, detects monorepo vs single-package layout, scaffolds workflow/scripts/config files, and updates `package.json` with release scripts.
|
|
42
|
+
|
|
43
|
+
Also expand `runReleasePrepare` to polymorphically handle both `MonorepoReleaseConfig` and `ReleaseConfig`, and update the esbuild plugin to preserve shebangs during compilation.
|
|
44
|
+
|
|
45
|
+
- #24 release-kit|feat: Return computed tags from release prepare and write .release-tags (#27)
|
|
46
|
+
|
|
47
|
+
`releasePrepare` and `releasePrepareMono` now return `string[]` of computed tag names instead of `void`. `runReleasePrepare` writes these tags to a `.release-tags` file (one tag per line) so the CI workflow can read them instead of independently deriving tag names from `git diff`. In dry-run mode the file is not written. This makes `tagPrefix` the single source of truth for tag names, eliminating the mismatch between TypeScript-computed tags and workflow-derived tags.
|
|
48
|
+
|
|
49
|
+
## [strings-v3.1.1] - 2026-03-10
|
|
6
50
|
|
|
7
51
|
### Tooling
|
|
8
52
|
|
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
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
7
|
## Installation
|
|
8
8
|
|
|
@@ -12,246 +12,193 @@ pnpm add -D @williamthorsen/release-kit git-cliff
|
|
|
12
12
|
|
|
13
13
|
## Quick start
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
4. Copy `cliff.toml.template` to your repo root as `cliff.toml`
|
|
19
|
-
5. Add the GitHub Actions release workflow
|
|
15
|
+
```bash
|
|
16
|
+
# 1. Set up release-kit in your repo (scaffolds workflow + optional config)
|
|
17
|
+
npx @williamthorsen/release-kit init
|
|
20
18
|
|
|
21
|
-
|
|
19
|
+
# 2. Preview what a release would do
|
|
20
|
+
npx @williamthorsen/release-kit prepare --dry-run
|
|
22
21
|
|
|
23
|
-
|
|
22
|
+
# 3. Copy cliff.toml.template to your repo root (if init didn't create one)
|
|
23
|
+
cp node_modules/@williamthorsen/release-kit/cliff.toml.template cliff.toml
|
|
24
|
+
```
|
|
24
25
|
|
|
25
|
-
|
|
26
|
+
That's it for most repos. The CLI auto-discovers workspaces and applies sensible defaults. Customize only what you need via `.config/release-kit.config.ts`.
|
|
26
27
|
|
|
27
|
-
|
|
28
|
-
import { DEFAULT_WORK_TYPES } from '@williamthorsen/release-kit';
|
|
29
|
-
import type { ReleaseConfig } from '@williamthorsen/release-kit';
|
|
30
|
-
|
|
31
|
-
export const config: ReleaseConfig = {
|
|
32
|
-
tagPrefix: 'v',
|
|
33
|
-
packageFiles: ['package.json'],
|
|
34
|
-
changelogPaths: ['.'],
|
|
35
|
-
workTypes: [...DEFAULT_WORK_TYPES],
|
|
36
|
-
formatCommand: 'pnpm run fmt',
|
|
37
|
-
};
|
|
38
|
-
```
|
|
28
|
+
## How it works
|
|
39
29
|
|
|
40
|
-
|
|
30
|
+
1. **Workspace discovery**: reads `pnpm-workspace.yaml` and resolves its `packages` globs to find workspace directories. Each directory containing a `package.json` becomes a component. If no workspace file is found, the repo is treated as a single-package project.
|
|
31
|
+
2. **Config loading**: loads `.config/release-kit.config.ts` (if present) via [jiti](https://github.com/unjs/jiti) and merges it with discovered defaults.
|
|
32
|
+
3. **Commit analysis**: for each component, finds commits since the last version tag, parses them for type and scope, and determines the appropriate version bump.
|
|
33
|
+
4. **Version bump + changelog**: bumps `package.json` versions and generates changelogs via `git-cliff`.
|
|
34
|
+
5. **Release tags file**: writes computed tags to `/tmp/release-kit/.release-tags` for CI consumption.
|
|
41
35
|
|
|
42
|
-
|
|
36
|
+
## CLI reference
|
|
43
37
|
|
|
44
|
-
|
|
45
|
-
import { DEFAULT_WORK_TYPES } from '@williamthorsen/release-kit';
|
|
46
|
-
import type { MonorepoReleaseConfig } from '@williamthorsen/release-kit';
|
|
38
|
+
### `release-kit prepare`
|
|
47
39
|
|
|
48
|
-
|
|
49
|
-
return {
|
|
50
|
-
tagPrefix: `${dir}-v`,
|
|
51
|
-
packageFiles: [`packages/${dir}/package.json`],
|
|
52
|
-
changelogPaths: [`packages/${dir}`],
|
|
53
|
-
paths: [`packages/${dir}/**`],
|
|
54
|
-
};
|
|
55
|
-
}
|
|
40
|
+
Run release preparation with automatic workspace discovery.
|
|
56
41
|
|
|
57
|
-
export const config: MonorepoReleaseConfig = {
|
|
58
|
-
components: [component('my-lib'), component('my-cli')],
|
|
59
|
-
workTypes: [...DEFAULT_WORK_TYPES],
|
|
60
|
-
formatCommand: 'pnpm run fmt',
|
|
61
|
-
};
|
|
62
42
|
```
|
|
43
|
+
Usage: release-kit prepare [options]
|
|
63
44
|
|
|
64
|
-
|
|
45
|
+
Options:
|
|
46
|
+
--dry-run Preview changes without writing files
|
|
47
|
+
--bump=major|minor|patch Override the bump type for all components
|
|
48
|
+
--only=name1,name2 Only process the named components (monorepo only)
|
|
49
|
+
--help, -h Show help
|
|
50
|
+
```
|
|
65
51
|
|
|
66
|
-
|
|
67
|
-
| ----------------- | ------------------ | -------- | ------------------------------------------------------------------ |
|
|
68
|
-
| `tagPrefix` | `string` | Yes | Git tag prefix for version tags (e.g., `'v'`) |
|
|
69
|
-
| `packageFiles` | `string[]` | Yes | Paths to `package.json` files to bump |
|
|
70
|
-
| `changelogPaths` | `string[]` | Yes | Directories in which to generate changelogs |
|
|
71
|
-
| `workTypes` | `WorkTypeConfig[]` | Yes | Ordered list of work type configurations for commit categorization |
|
|
72
|
-
| `formatCommand` | `string` | No | Shell command to run after changelog generation |
|
|
73
|
-
| `cliffConfigPath` | `string` | No | Path to `cliff.toml` (defaults to `'cliff.toml'`) |
|
|
52
|
+
Component names for `--only` match the package directory name (e.g., `arrays`, `release-kit`).
|
|
74
53
|
|
|
75
|
-
|
|
54
|
+
**Self-hosting note**: in a repo where `release-kit` is a workspace package (e.g., this monorepo), `npx` and `pnpm exec` may not resolve the binary. Run the built entry point directly:
|
|
76
55
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
| `workTypes` | `WorkTypeConfig[]` | Yes | Shared work type configurations |
|
|
81
|
-
| `formatCommand` | `string` | No | Shell command to run after changelog generation |
|
|
56
|
+
```bash
|
|
57
|
+
node packages/release-kit/dist/esm/bin/release-kit.js prepare --dry-run
|
|
58
|
+
```
|
|
82
59
|
|
|
83
|
-
|
|
60
|
+
### `release-kit init`
|
|
84
61
|
|
|
85
|
-
|
|
62
|
+
Initialize release-kit in the current repository. Scaffolds a GitHub Actions workflow and an optional config file.
|
|
86
63
|
|
|
87
|
-
|
|
64
|
+
```
|
|
65
|
+
Usage: release-kit init [options]
|
|
88
66
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
67
|
+
Options:
|
|
68
|
+
--dry-run Preview changes without writing files
|
|
69
|
+
--help, -h Show help
|
|
70
|
+
```
|
|
93
71
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
function parseArgs(): { dryRun: boolean; bumpOverride?: ReleaseType } {
|
|
97
|
-
const args = process.argv.slice(2);
|
|
98
|
-
let dryRun = false;
|
|
99
|
-
let bumpOverride: ReleaseType | undefined;
|
|
100
|
-
|
|
101
|
-
for (const arg of args) {
|
|
102
|
-
if (arg === '--dry-run') dryRun = true;
|
|
103
|
-
else if (arg.startsWith('--bump=')) {
|
|
104
|
-
const value = arg.slice('--bump='.length);
|
|
105
|
-
if (!VALID_BUMP_TYPES.includes(value)) {
|
|
106
|
-
console.error(`Invalid bump type "${value}". Must be: ${VALID_BUMP_TYPES.join(', ')}`);
|
|
107
|
-
process.exit(1);
|
|
108
|
-
}
|
|
109
|
-
bumpOverride = value as ReleaseType;
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
return { dryRun, bumpOverride };
|
|
114
|
-
}
|
|
72
|
+
Scaffolded files:
|
|
115
73
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
74
|
+
- `.config/release-kit.config.ts` — starter config with commented-out customization examples
|
|
75
|
+
- `.github/workflows/release.yaml` — workflow that delegates to a reusable release workflow
|
|
76
|
+
- `cliff.toml` — copied from the bundled template (prompted if missing)
|
|
119
77
|
|
|
120
|
-
|
|
78
|
+
## Configuration
|
|
79
|
+
|
|
80
|
+
Configuration is optional. The CLI works out of the box by auto-discovering workspaces and applying defaults. Create `.config/release-kit.config.ts` only when you need to customize behavior.
|
|
81
|
+
|
|
82
|
+
### Config file
|
|
121
83
|
|
|
122
84
|
```typescript
|
|
123
|
-
import {
|
|
124
|
-
import type { ReleaseType } from '@williamthorsen/release-kit';
|
|
125
|
-
import { config } from './release.config.ts';
|
|
85
|
+
import type { ReleaseKitConfig } from '@williamthorsen/release-kit';
|
|
126
86
|
|
|
127
|
-
const
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
let only: string[] | undefined;
|
|
134
|
-
|
|
135
|
-
for (const arg of args) {
|
|
136
|
-
if (arg === '--dry-run') dryRun = true;
|
|
137
|
-
else if (arg.startsWith('--bump=')) {
|
|
138
|
-
const value = arg.slice('--bump='.length);
|
|
139
|
-
if (!VALID_BUMP_TYPES.includes(value)) {
|
|
140
|
-
console.error(`Invalid bump type "${value}". Must be: ${VALID_BUMP_TYPES.join(', ')}`);
|
|
141
|
-
process.exit(1);
|
|
142
|
-
}
|
|
143
|
-
bumpOverride = value as ReleaseType;
|
|
144
|
-
} else if (arg.startsWith('--only=')) {
|
|
145
|
-
only = arg.slice('--only='.length).split(',');
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
return { dryRun, bumpOverride, only };
|
|
150
|
-
}
|
|
87
|
+
const config: ReleaseKitConfig = {
|
|
88
|
+
// Exclude a component from release processing
|
|
89
|
+
components: [{ dir: 'internal-tools', shouldExclude: true }],
|
|
90
|
+
|
|
91
|
+
// Run a formatter after changelog generation
|
|
92
|
+
formatCommand: 'pnpm run fmt',
|
|
151
93
|
|
|
152
|
-
|
|
94
|
+
// Override the default version patterns
|
|
95
|
+
versionPatterns: { major: ['!'], minor: ['feat', 'feature'] },
|
|
153
96
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
const name = c.tagPrefix.replace(/-v$/, '');
|
|
158
|
-
return only.includes(name);
|
|
159
|
-
});
|
|
160
|
-
effectiveConfig = { ...config, components: filtered };
|
|
161
|
-
}
|
|
97
|
+
// Add or override work types (merged with defaults by key)
|
|
98
|
+
workTypes: { perf: { header: 'Performance' } },
|
|
99
|
+
};
|
|
162
100
|
|
|
163
|
-
|
|
101
|
+
export default config;
|
|
164
102
|
```
|
|
165
103
|
|
|
166
|
-
|
|
104
|
+
The config file supports both `export default config` and `export const config = { ... }`.
|
|
105
|
+
|
|
106
|
+
### `ReleaseKitConfig` reference
|
|
107
|
+
|
|
108
|
+
| Field | Type | Description |
|
|
109
|
+
| ------------------ | -------------------------------- | ------------------------------------------------------------ |
|
|
110
|
+
| `cliffConfigPath` | `string` | Path to `cliff.toml` (defaults to `'cliff.toml'`) |
|
|
111
|
+
| `components` | `ComponentOverride[]` | Override or exclude discovered components (matched by `dir`) |
|
|
112
|
+
| `formatCommand` | `string` | Shell command to run after changelog generation |
|
|
113
|
+
| `versionPatterns` | `VersionPatterns` | Rules for which commit types trigger major/minor bumps |
|
|
114
|
+
| `workspaceAliases` | `Record<string, string>` | Maps shorthand workspace names to canonical names in commits |
|
|
115
|
+
| `workTypes` | `Record<string, WorkTypeConfig>` | Work type definitions, merged with defaults by key |
|
|
116
|
+
|
|
117
|
+
All fields are optional.
|
|
118
|
+
|
|
119
|
+
### `ComponentOverride`
|
|
167
120
|
|
|
168
|
-
```
|
|
169
|
-
{
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
}
|
|
121
|
+
```typescript
|
|
122
|
+
interface ComponentOverride {
|
|
123
|
+
dir: string; // Package directory name (e.g., 'arrays')
|
|
124
|
+
tagPrefix?: string; // Custom git tag prefix (defaults to '${dir}-v')
|
|
125
|
+
shouldExclude?: boolean; // If true, exclude from release processing
|
|
174
126
|
}
|
|
175
127
|
```
|
|
176
128
|
|
|
177
|
-
|
|
129
|
+
### `VersionPatterns`
|
|
178
130
|
|
|
179
|
-
|
|
131
|
+
Defines which commit types trigger major or minor bumps. Any recognized type not listed defaults to a patch bump.
|
|
180
132
|
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
|
|
133
|
+
```typescript
|
|
134
|
+
interface VersionPatterns {
|
|
135
|
+
major: string[]; // Patterns triggering a major bump ('!' = any breaking change)
|
|
136
|
+
minor: string[]; // Commit types triggering a minor bump
|
|
137
|
+
}
|
|
138
|
+
```
|
|
184
139
|
|
|
185
|
-
|
|
186
|
-
workflow_dispatch:
|
|
187
|
-
inputs:
|
|
188
|
-
bump:
|
|
189
|
-
description: 'Override bump type (leave empty to auto-detect)'
|
|
190
|
-
required: false
|
|
191
|
-
type: choice
|
|
192
|
-
options:
|
|
193
|
-
- ''
|
|
194
|
-
- patch
|
|
195
|
-
- minor
|
|
196
|
-
- major
|
|
140
|
+
Default: `{ major: ['!'], minor: ['feat', 'feature'] }`
|
|
197
141
|
|
|
198
|
-
|
|
199
|
-
contents: write
|
|
142
|
+
### Default work types
|
|
200
143
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
144
|
+
| Key | Header | Aliases |
|
|
145
|
+
| ---------- | ------------- | --------- |
|
|
146
|
+
| `fix` | Bug fixes | `bugfix` |
|
|
147
|
+
| `feat` | Features | `feature` |
|
|
148
|
+
| `internal` | Internal | |
|
|
149
|
+
| `refactor` | Refactoring | |
|
|
150
|
+
| `tests` | Tests | `test` |
|
|
151
|
+
| `tooling` | Tooling | |
|
|
152
|
+
| `ci` | CI | |
|
|
153
|
+
| `deps` | Dependencies | `dep` |
|
|
154
|
+
| `docs` | Documentation | `doc` |
|
|
155
|
+
| `fmt` | Formatting | |
|
|
209
156
|
|
|
210
|
-
|
|
157
|
+
Work types from your config are merged with these defaults by key — your entries override or extend, they don't replace the full set.
|
|
211
158
|
|
|
212
|
-
|
|
213
|
-
with:
|
|
214
|
-
node-version: '24'
|
|
215
|
-
cache: 'pnpm'
|
|
159
|
+
## Commit format
|
|
216
160
|
|
|
217
|
-
|
|
161
|
+
release-kit parses commits in these formats:
|
|
218
162
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
fi
|
|
226
|
-
pnpm run release:prepare $ARGS
|
|
227
|
-
VERSION=$(node -p "require('./package.json').version")
|
|
228
|
-
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
|
|
163
|
+
```
|
|
164
|
+
type: description # e.g., feat: add utility
|
|
165
|
+
type(scope): description # e.g., fix(parser): handle edge case
|
|
166
|
+
workspace|type: description # e.g., arrays|feat: add compact function
|
|
167
|
+
!type: description # breaking change (triggers major bump)
|
|
168
|
+
```
|
|
229
169
|
|
|
230
|
-
|
|
231
|
-
id: check
|
|
232
|
-
run: |
|
|
233
|
-
if git diff --quiet; then
|
|
234
|
-
echo "changed=false" >> "$GITHUB_OUTPUT"
|
|
235
|
-
echo "No release-worthy changes found."
|
|
236
|
-
else
|
|
237
|
-
echo "changed=true" >> "$GITHUB_OUTPUT"
|
|
238
|
-
fi
|
|
170
|
+
The `workspace|type:` format scopes a commit to a specific workspace in a monorepo. Use `workspaceAliases` in your config to map shorthand names to canonical workspace names.
|
|
239
171
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
172
|
+
## Using `component()` for manual configuration
|
|
173
|
+
|
|
174
|
+
If you need to build a `MonorepoReleaseConfig` manually (e.g., for the legacy script-based approach), the exported `component()` helper creates a `ComponentConfig` from a workspace-relative path:
|
|
175
|
+
|
|
176
|
+
```typescript
|
|
177
|
+
import { component } from '@williamthorsen/release-kit';
|
|
178
|
+
|
|
179
|
+
// Accepts the full workspace-relative path
|
|
180
|
+
component('packages/arrays');
|
|
181
|
+
// => {
|
|
182
|
+
// dir: 'arrays',
|
|
183
|
+
// tagPrefix: 'arrays-v',
|
|
184
|
+
// packageFiles: ['packages/arrays/package.json'],
|
|
185
|
+
// changelogPaths: ['packages/arrays'],
|
|
186
|
+
// paths: ['packages/arrays/**'],
|
|
187
|
+
// }
|
|
188
|
+
|
|
189
|
+
// Custom tag prefix
|
|
190
|
+
component('libs/core', 'core-v');
|
|
249
191
|
```
|
|
250
192
|
|
|
193
|
+
The `dir` field is derived from `path.basename()`, so `packages/arrays` and `libs/arrays` both produce `dir: 'arrays'`.
|
|
194
|
+
|
|
195
|
+
## GitHub Actions workflow
|
|
196
|
+
|
|
197
|
+
The `init` command scaffolds a workflow that delegates to a reusable release workflow. For repos that need a self-contained workflow:
|
|
198
|
+
|
|
251
199
|
### Monorepo
|
|
252
200
|
|
|
253
201
|
```yaml
|
|
254
|
-
# .github/workflows/release.yaml
|
|
255
202
|
name: Release
|
|
256
203
|
|
|
257
204
|
on:
|
|
@@ -287,7 +234,7 @@ jobs:
|
|
|
287
234
|
|
|
288
235
|
- uses: actions/setup-node@v4
|
|
289
236
|
with:
|
|
290
|
-
node-version: '
|
|
237
|
+
node-version: '22'
|
|
291
238
|
cache: 'pnpm'
|
|
292
239
|
|
|
293
240
|
- run: pnpm install
|
|
@@ -301,7 +248,7 @@ jobs:
|
|
|
301
248
|
if [ -n "${{ inputs.bump }}" ]; then
|
|
302
249
|
ARGS="$ARGS --bump=${{ inputs.bump }}"
|
|
303
250
|
fi
|
|
304
|
-
|
|
251
|
+
npx @williamthorsen/release-kit prepare $ARGS
|
|
305
252
|
|
|
306
253
|
- name: Check for changes
|
|
307
254
|
id: check
|
|
@@ -313,18 +260,13 @@ jobs:
|
|
|
313
260
|
echo "changed=true" >> "$GITHUB_OUTPUT"
|
|
314
261
|
fi
|
|
315
262
|
|
|
316
|
-
- name:
|
|
263
|
+
- name: Read release tags
|
|
317
264
|
if: steps.check.outputs.changed == 'true'
|
|
318
265
|
id: tags
|
|
319
266
|
run: |
|
|
320
|
-
TAGS
|
|
321
|
-
for pkg in $(git diff --name-only -- 'packages/*/package.json'); do
|
|
322
|
-
DIR=$(echo "$pkg" | cut -d/ -f2)
|
|
323
|
-
VERSION=$(node -p "require('./$pkg').version")
|
|
324
|
-
TAGS="$TAGS ${DIR}-v${VERSION}"
|
|
325
|
-
done
|
|
267
|
+
TAGS=$(cat /tmp/release-kit/.release-tags | tr '\n' ' ')
|
|
326
268
|
echo "tags=$TAGS" >> "$GITHUB_OUTPUT"
|
|
327
|
-
echo "Releasing
|
|
269
|
+
echo "Releasing: $TAGS"
|
|
328
270
|
|
|
329
271
|
- name: Commit, tag, and push
|
|
330
272
|
if: steps.check.outputs.changed == 'true'
|
|
@@ -339,21 +281,44 @@ jobs:
|
|
|
339
281
|
git push origin main ${{ steps.tags.outputs.tags }}
|
|
340
282
|
```
|
|
341
283
|
|
|
284
|
+
### Single-package repo
|
|
285
|
+
|
|
286
|
+
The same workflow without the `only` input. Replace the prepare step with:
|
|
287
|
+
|
|
288
|
+
```yaml
|
|
289
|
+
- name: Run release preparation
|
|
290
|
+
run: |
|
|
291
|
+
ARGS=""
|
|
292
|
+
if [ -n "${{ inputs.bump }}" ]; then
|
|
293
|
+
ARGS="--bump=${{ inputs.bump }}"
|
|
294
|
+
fi
|
|
295
|
+
npx @williamthorsen/release-kit prepare $ARGS
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
And the tag step with:
|
|
299
|
+
|
|
300
|
+
```yaml
|
|
301
|
+
- name: Read release tag
|
|
302
|
+
if: steps.check.outputs.changed == 'true'
|
|
303
|
+
id: tags
|
|
304
|
+
run: |
|
|
305
|
+
TAG=$(cat /tmp/release-kit/.release-tags)
|
|
306
|
+
echo "tag=$TAG" >> "$GITHUB_OUTPUT"
|
|
307
|
+
```
|
|
308
|
+
|
|
342
309
|
## Triggering a release
|
|
343
310
|
|
|
344
311
|
```sh
|
|
345
|
-
#
|
|
346
|
-
gh workflow run release.yaml
|
|
347
|
-
gh workflow run release.yaml -f bump=minor
|
|
348
|
-
|
|
349
|
-
# Monorepo: all components
|
|
312
|
+
# All components
|
|
350
313
|
gh workflow run release.yaml
|
|
351
314
|
|
|
352
|
-
#
|
|
353
|
-
gh workflow run release.yaml -f only=
|
|
354
|
-
gh workflow run release.yaml -f only=
|
|
315
|
+
# Specific component(s)
|
|
316
|
+
gh workflow run release.yaml -f only=arrays
|
|
317
|
+
gh workflow run release.yaml -f only=arrays,strings -f bump=minor
|
|
355
318
|
```
|
|
356
319
|
|
|
320
|
+
Or use the GitHub UI: Actions > Release > Run workflow.
|
|
321
|
+
|
|
357
322
|
## cliff.toml setup
|
|
358
323
|
|
|
359
324
|
The package includes a `cliff.toml.template` with a generic git-cliff configuration that:
|
|
@@ -377,13 +342,37 @@ This package shells out to two external tools:
|
|
|
377
342
|
- **`git`** — must be available on `PATH`. Used to find tags and retrieve commit history.
|
|
378
343
|
- **`git-cliff`** — must be available on `PATH`. Add `git-cliff` as a dev dependency to make it available in CI.
|
|
379
344
|
|
|
345
|
+
## Legacy script-based approach
|
|
346
|
+
|
|
347
|
+
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.
|
|
348
|
+
|
|
349
|
+
```typescript
|
|
350
|
+
// .github/scripts/release.config.ts
|
|
351
|
+
import type { MonorepoReleaseConfig } from '@williamthorsen/release-kit';
|
|
352
|
+
import { component } from '@williamthorsen/release-kit';
|
|
353
|
+
|
|
354
|
+
export const config: MonorepoReleaseConfig = {
|
|
355
|
+
components: [component('packages/arrays'), component('packages/strings')],
|
|
356
|
+
formatCommand: 'pnpm run fmt',
|
|
357
|
+
};
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
```typescript
|
|
361
|
+
// .github/scripts/release-prepare.ts
|
|
362
|
+
import { runReleasePrepare } from '@williamthorsen/release-kit';
|
|
363
|
+
import { config } from './release.config.ts';
|
|
364
|
+
|
|
365
|
+
runReleasePrepare(config);
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
The key difference: the script-based approach requires manually listing every component, while the CLI auto-discovers them from `pnpm-workspace.yaml`.
|
|
369
|
+
|
|
380
370
|
## Migration from changesets
|
|
381
371
|
|
|
382
372
|
1. Add `@williamthorsen/release-kit` and `git-cliff` as dev dependencies.
|
|
383
373
|
2. Remove `@changesets/cli` from dev dependencies.
|
|
384
374
|
3. Delete the `.changeset/` directory.
|
|
385
|
-
4.
|
|
386
|
-
5.
|
|
387
|
-
6. Copy `cliff.toml.template` to your repo root as `cliff.toml
|
|
388
|
-
7.
|
|
389
|
-
8. Create an initial version tag for each package (e.g., `git tag v1.0.0` or `git tag my-lib-v1.0.0`).
|
|
375
|
+
4. Run `npx @williamthorsen/release-kit init` to scaffold workflow and config files.
|
|
376
|
+
5. Remove `changeset:*` scripts from `package.json` (no replacement needed — the CLI handles everything).
|
|
377
|
+
6. Copy `cliff.toml.template` to your repo root as `cliff.toml` (if `init` didn't create one).
|
|
378
|
+
7. Create an initial version tag for each package (e.g., `git tag v1.0.0` or `git tag arrays-v1.0.0`).
|
package/dist/esm/.cache
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
0ede8bfb18cd7eb611431537e6a16d4476ee70169599c97626bb6f6fc4349bbf
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { initCommand } from "../init/initCommand.js";
|
|
3
|
+
import { prepareCommand } from "../prepareCommand.js";
|
|
3
4
|
function showUsage() {
|
|
4
5
|
console.info(`
|
|
5
6
|
Usage: release-kit <command> [options]
|
|
6
7
|
|
|
7
8
|
Commands:
|
|
9
|
+
prepare Run release preparation (auto-discovers workspaces)
|
|
8
10
|
init Initialize release-kit in the current repository
|
|
9
11
|
|
|
10
12
|
Options:
|
|
@@ -17,13 +19,26 @@ function showInitHelp() {
|
|
|
17
19
|
Usage: release-kit init [options]
|
|
18
20
|
|
|
19
21
|
Initialize release-kit in the current repository.
|
|
20
|
-
Scaffolds workflow
|
|
22
|
+
Scaffolds workflow and config files.
|
|
21
23
|
|
|
22
24
|
Options:
|
|
23
25
|
--dry-run Preview changes without writing files
|
|
24
26
|
--help, -h Show this help message
|
|
25
27
|
`);
|
|
26
28
|
}
|
|
29
|
+
function showPrepareHelp() {
|
|
30
|
+
console.info(`
|
|
31
|
+
Usage: release-kit prepare [options]
|
|
32
|
+
|
|
33
|
+
Run release preparation with automatic workspace discovery.
|
|
34
|
+
|
|
35
|
+
Options:
|
|
36
|
+
--dry-run Run without modifying any files
|
|
37
|
+
--bump=major|minor|patch Override the bump type for all components
|
|
38
|
+
--only=name1,name2 Only process the named components (comma-separated, monorepo only)
|
|
39
|
+
--help, -h Show this help message
|
|
40
|
+
`);
|
|
41
|
+
}
|
|
27
42
|
const args = process.argv.slice(2);
|
|
28
43
|
const command = args[0];
|
|
29
44
|
const flags = args.slice(1);
|
|
@@ -31,6 +46,14 @@ if (command === "--help" || command === "-h" || command === void 0) {
|
|
|
31
46
|
showUsage();
|
|
32
47
|
process.exit(0);
|
|
33
48
|
}
|
|
49
|
+
if (command === "prepare") {
|
|
50
|
+
if (flags.some((f) => f === "--help" || f === "-h")) {
|
|
51
|
+
showPrepareHelp();
|
|
52
|
+
process.exit(0);
|
|
53
|
+
}
|
|
54
|
+
await prepareCommand(flags);
|
|
55
|
+
process.exit(0);
|
|
56
|
+
}
|
|
34
57
|
if (command === "init") {
|
|
35
58
|
if (flags.some((f) => f === "--help" || f === "-h")) {
|
|
36
59
|
showInitHelp();
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { basename } from "node:path";
|
|
2
|
+
function component(workspacePath, tagPrefix) {
|
|
3
|
+
const dir = basename(workspacePath);
|
|
4
|
+
const prefix = tagPrefix ?? `${dir}-v`;
|
|
5
|
+
return {
|
|
6
|
+
dir,
|
|
7
|
+
tagPrefix: prefix,
|
|
8
|
+
packageFiles: [`${workspacePath}/package.json`],
|
|
9
|
+
changelogPaths: [workspacePath],
|
|
10
|
+
paths: [`${workspacePath}/**`]
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
export {
|
|
14
|
+
component
|
|
15
|
+
};
|