@williamthorsen/release-kit 10.4.0 → 10.4.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.
@@ -1,6 +1,6 @@
1
1
  /** @noformat — @generated. Do not edit. Compiled by rdy. */
2
2
  /* eslint-disable */
3
- export const __readyupVersion = "0.28.0";
3
+ export const __readyupVersion = "0.29.0";
4
4
 
5
5
 
6
6
  // .readyup/kits/default.ts
@@ -52,7 +52,7 @@ function detectRepoType() {
52
52
 
53
53
  // .readyup/kits/default.ts
54
54
  function getMinVersion() {
55
- const picked = { "version": "10.4.0" };
55
+ const picked = { "version": "10.4.1" };
56
56
  if (typeof picked["version"] !== "string") {
57
57
  throw new TypeError("release-kit/package.json: 'version' must be a string");
58
58
  }
@@ -1,6 +1,6 @@
1
1
  /** @noformat — @generated. Do not edit. Compiled by rdy. */
2
2
  /* eslint-disable */
3
- export const __readyupVersion = "0.28.0";
3
+ export const __readyupVersion = "0.29.0";
4
4
 
5
5
 
6
6
  // .readyup/kits/npm-auto-publish.ts
@@ -13,7 +13,7 @@
13
13
  "path": "kits/default.ts"
14
14
  },
15
15
  {
16
- "hash": "07509c48",
16
+ "hash": "bbdcc849",
17
17
  "kind": "inline",
18
18
  "path": "../package.json",
19
19
  "paths": [
@@ -38,10 +38,10 @@
38
38
  ],
39
39
  "name": "default",
40
40
  "path": "kits/default.js",
41
- "readyupVersion": "0.28.0",
41
+ "readyupVersion": "0.29.0",
42
42
  "source": "kits/default.ts",
43
43
  "sourceHash": "fe239d01",
44
- "targetHash": "5413984b"
44
+ "targetHash": "6ba7f24f"
45
45
  },
46
46
  {
47
47
  "checklists": [
@@ -58,10 +58,10 @@
58
58
  ],
59
59
  "name": "npm-auto-publish",
60
60
  "path": "kits/npm-auto-publish.js",
61
- "readyupVersion": "0.28.0",
61
+ "readyupVersion": "0.29.0",
62
62
  "source": "kits/npm-auto-publish.ts",
63
63
  "sourceHash": "ac484613",
64
- "targetHash": "0636c995"
64
+ "targetHash": "c7b01e0b"
65
65
  }
66
66
  ]
67
67
  }
package/CHANGELOG.md CHANGED
@@ -2,6 +2,18 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## 10.4.1 — 2026-08-18
6
+
7
+ ### 🐛 Bug fixes
8
+
9
+ - Accept `--only` under a project block, skipping the project release (#702)
10
+
11
+ Fixes an issue where `release-kit prepare --only` exited with an error in any repo whose config declares a `project` block, which left the `only` dispatch input that `release-kit init` scaffolds into `release.yaml` unusable. A narrowed run now releases the named workspaces and skips the project release, reporting the skip and the selection that caused it as a warning.
12
+
13
+ - Route release-notes preview warnings through the prepare plan (#705)
14
+
15
+ Fixes an issue where `release-kit prepare --with-release-notes` printed its diagnostics to stderr ahead of the release report, and described a skipped release-notes preview as a skipped README injection. The messages now render as `⚠️` lines inside the report and are worded for release-notes previews; a skip belonging to one workspace names that workspace.
16
+
5
17
  ## 10.4.0 — 2026-08-17
6
18
 
7
19
  ### 🎉 Features
package/README.md CHANGED
@@ -5,15 +5,17 @@ Version-bumping and changelog-generation toolkit for release workflows.
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 from `git-cliff --context` output rendered in-process (with optional [editorial overrides](#editorial-overrides)).
6
6
 
7
7
  <!-- section:release-notes -->
8
- ## Release notes — v10.4.0 (2026-08-17)
8
+ ## Release notes — v10.4.1 (2026-08-18)
9
9
 
10
- ### 🎉 Features
10
+ ### 🐛 Bug fixes
11
11
 
12
- - Let a project release cover repo-root paths (#685)
12
+ - Accept `--only` under a project block, skipping the project release (#702)
13
13
 
14
- Extends `release-kit`'s project release to a repo whose content lives at the root. Such a repo declares `project: { paths: ['**'] }` and gets the root `CHANGELOG.md`, the root `.meta/changelog.json`, the `--with-release-notes` previews under root `docs/`, the root `package.json` bump, and the project tag that the stage produces.
14
+ Fixes an issue where `release-kit prepare --only` exited with an error in any repo whose config declares a `project` block, which left the `only` dispatch input that `release-kit init` scaffolds into `release.yaml` unusable. A narrowed run now releases the named workspaces and skips the project release, reporting the skip and the selection that caused it as a warning.
15
15
 
16
- `paths` scopes any project release's window, not only the whole-tree case, and the project tier of `release-kit validate-overrides` with it. A declared value replaces the workspace union rather than extending it; omitting `paths` resolves to that union, so existing consumers see no change.
16
+ - Route release-notes preview warnings through the prepare plan (#705)
17
+
18
+ Fixes an issue where `release-kit prepare --with-release-notes` printed its diagnostics to stderr ahead of the release report, and described a skipped release-notes preview as a skipped README injection. The messages now render as `⚠️` lines inside the report and are worded for release-notes previews; a skip belonging to one workspace names that workspace.
17
19
  <!-- /section:release-notes -->
18
20
 
19
21
  ## Installation
@@ -262,7 +264,7 @@ CLI flag interactions:
262
264
  - `--dry-run` previews project artifacts alongside workspace artifacts; no files are written.
263
265
  - `--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.
264
266
  - `--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.
265
- - `--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.
267
+ - `--only` narrows the run to the named workspaces and skips the project release, which is reported as a warning. The project release rolls up every contributing workspace, and `--only` changes which workspaces those are, so rolling up a narrowed set would release a project version covering work the run excluded. Run a full `prepare` (no `--only`) to include the project release.
266
268
  - `--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.
267
269
 
268
270
  `--bump` and `--force` are orthogonal: `--bump` is purely a level chooser; `--force` is purely a release trigger. Examples:
@@ -468,7 +470,7 @@ Per-entry fields are all optional, but at least one must be present per entry:
468
470
  Keys can be either the full 40-character commit SHA or a non-ambiguous prefix. The matcher walks every `ChangelogItem.hash` value present in the entry tree and resolves each override key to its set of matching hashes:
469
471
 
470
472
  - **Exact prefix match (1 hit)** — the override applies. A 7-character prefix is usually unambiguous within a single repo's history; longer prefixes are always safe.
471
- - **No matches (0 hits)** — the override is treated as a stale reference (probably from a rebase or branch deletion) and a warning is logged. The release continues.
473
+ - **No matches (0 hits)** — the override is treated as a stale reference (probably from a rebase or branch deletion) and prepare reports a warning. The release continues.
472
474
  - **Ambiguous prefix (2+ hits)** — the release aborts with an error naming the key and the matching hashes. Lengthen the prefix or use the full SHA.
473
475
 
474
476
  Override application errors abort the run with a non-zero exit; warnings (zero-match keys) are non-fatal and surface on `PrepareResult.warnings`.
@@ -581,9 +583,9 @@ Run release preparation with automatic workspace discovery.
581
583
  | ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
582
584
  | `--dry-run` | Preview changes without writing files |
583
585
  | `--bump=major\|minor\|patch` | Override the bump type for all workspaces |
584
- | `--set-version=X.Y.Z` | Set an explicit canonical semver version; bypasses commit-derived bumps. Requires `--only` in monorepo mode (rejected when a `project` block is configured). |
586
+ | `--set-version=X.Y.Z` | Set an explicit canonical semver version; bypasses commit-derived bumps. In monorepo mode it requires `--only`, and is rejected when a `project` block is configured. |
585
587
  | `--force` | Release even when no commits or no bump-worthy commits exist since the last tag. In monorepo/project mode, defaults to patch (combine with `--bump=X` for a different level); in single-package mode, a bare `--force` is rejected — pass `--bump=major\|minor\|patch`. |
586
- | `--only=name1,name2` | Only process the named workspaces (monorepo only; rejected when a `project` block is configured) |
588
+ | `--only=name1,name2` | Only process the named workspaces (monorepo only). When a `project` block is configured, the project release is skipped. |
587
589
  | `--with-release-notes` | Write per-workspace release-notes previews under `<workspacePath>/docs/` |
588
590
  | `--help`, `-h` | Show help |
589
591
 
@@ -596,7 +598,7 @@ Workspace names for `--only` match the package directory name (e.g., `arrays`, `
596
598
  - `<workspacePath>/docs/README.v<version>.md` — the workspace `README.md` with release notes injected at the `<!-- section:release-notes -->` marker.
597
599
  - `<workspacePath>/docs/RELEASE_NOTES.v<version>.md` — the standalone release notes for this version.
598
600
 
599
- 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.
601
+ The publish-time inject-and-revert lifecycle is unchanged; previews are additive, deterministic, and safe to regenerate. When `changelogJson.enabled` is `false`, prepare reports a warning and skips preview generation. In dry-run mode, planned writes are logged and no files are created.
600
602
 
601
603
  Because preview filenames are versioned, committing them will accumulate files over time. The recommended `.gitignore` entry for monorepos is:
602
604
 
@@ -1,2 +1,2 @@
1
- export declare const prepareHelpText = "\nUsage: release-kit prepare [options]\n\nRun release preparation with automatic workspace discovery.\n\nOptions:\n --dry-run Run without modifying any files\n --bump=major|minor|patch Override the bump type for all workspaces\n --set-version=X.Y.Z Set an explicit version; bypasses commit-derived bumps.\n Requires --only in monorepo mode (rejected when a 'project' block is configured).\n --force Release even when no commits or no bump-worthy commits exist\n since the last tag. In monorepo and project mode, defaults to\n patch when --bump is not given; use --bump=X for a different\n level. In single-package mode, a bare --force is rejected \u2014\n pass --bump=major|minor|patch.\n --no-git-checks, -n Skip the clean-working-tree check\n --only=name1,name2 Only process the named workspaces (comma-separated, monorepo only;\n rejected when a 'project' block is configured)\n --with-release-notes Also write per-workspace release-notes previews under <workspacePath>/docs/\n (docs/README.v<version>.md and docs/RELEASE_NOTES.v<version>.md).\n Recommended .gitignore entry: packages/*/docs/*.v*.md (or docs/*.v*.md).\n --help, -h Show this help message\n";
1
+ export declare const prepareHelpText = "\nUsage: release-kit prepare [options]\n\nRun release preparation with automatic workspace discovery.\n\nOptions:\n --dry-run Run without modifying any files\n --bump=major|minor|patch Override the bump type for all workspaces\n --set-version=X.Y.Z Set an explicit version; bypasses commit-derived bumps. In monorepo\n mode it requires --only, and is rejected when a 'project' block is configured.\n --force Release even when no commits or no bump-worthy commits exist\n since the last tag. In monorepo and project mode, defaults to\n patch when --bump is not given; use --bump=X for a different\n level. In single-package mode, a bare --force is rejected \u2014\n pass --bump=major|minor|patch.\n --no-git-checks, -n Skip the clean-working-tree check\n --only=name1,name2 Only process the named workspaces (comma-separated, monorepo only).\n When a 'project' block is configured, the project release is skipped.\n --with-release-notes Also write per-workspace release-notes previews under <workspacePath>/docs/\n (docs/README.v<version>.md and docs/RELEASE_NOTES.v<version>.md).\n Recommended .gitignore entry: packages/*/docs/*.v*.md (or docs/*.v*.md).\n --help, -h Show this help message\n";
2
2
  export declare function showPrepareHelp(): void;
@@ -6,16 +6,16 @@ Run release preparation with automatic workspace discovery.
6
6
  Options:
7
7
  --dry-run Run without modifying any files
8
8
  --bump=major|minor|patch Override the bump type for all workspaces
9
- --set-version=X.Y.Z Set an explicit version; bypasses commit-derived bumps.
10
- Requires --only in monorepo mode (rejected when a 'project' block is configured).
9
+ --set-version=X.Y.Z Set an explicit version; bypasses commit-derived bumps. In monorepo
10
+ mode it requires --only, and is rejected when a 'project' block is configured.
11
11
  --force Release even when no commits or no bump-worthy commits exist
12
12
  since the last tag. In monorepo and project mode, defaults to
13
13
  patch when --bump is not given; use --bump=X for a different
14
14
  level. In single-package mode, a bare --force is rejected —
15
15
  pass --bump=major|minor|patch.
16
16
  --no-git-checks, -n Skip the clean-working-tree check
17
- --only=name1,name2 Only process the named workspaces (comma-separated, monorepo only;
18
- rejected when a 'project' block is configured)
17
+ --only=name1,name2 Only process the named workspaces (comma-separated, monorepo only).
18
+ When a 'project' block is configured, the project release is skipped.
19
19
  --with-release-notes Also write per-workspace release-notes previews under <workspacePath>/docs/
20
20
  (docs/README.v<version>.md and docs/RELEASE_NOTES.v<version>.md).
21
21
  Recommended .gitignore entry: packages/*/docs/*.v*.md (or docs/*.v*.md).
@@ -3,7 +3,16 @@ export interface RenderedInjectedReadme {
3
3
  injectedReadme: string;
4
4
  releaseNotesMarkdown: string;
5
5
  }
6
- export declare function renderInjectedReadmeFromEntries(readme: string, entries: readonly ChangelogEntry[], tag: string, sectionOrder?: string[]): RenderedInjectedReadme | undefined;
6
+ export type RenderInjectedReadmeSkipReason = 'no-entry' | 'empty-body';
7
+ export type RenderInjectedReadmeResult = {
8
+ status: 'rendered';
9
+ rendered: RenderedInjectedReadme;
10
+ } | {
11
+ status: 'skipped';
12
+ reason: RenderInjectedReadmeSkipReason;
13
+ version: string;
14
+ };
15
+ export declare function renderInjectedReadmeFromEntries(readme: string, entries: readonly ChangelogEntry[], tag: string, sectionOrder?: string[]): RenderInjectedReadmeResult;
7
16
  export declare function renderInjectedReadme(readme: string, changelogJsonPath: string, tag: string, sectionOrder?: string[]): RenderedInjectedReadme | undefined;
8
17
  export declare function injectReleaseNotesIntoReadme(readmePath: string, changelogJsonPath: string, tag: string, sectionOrder?: string[]): string | undefined;
9
18
  export declare function resolveReadmePath(workspacePath: string): string | undefined;
@@ -7,8 +7,7 @@ export function renderInjectedReadmeFromEntries(readme, entries, tag, sectionOrd
7
7
  const version = extractVersion(tag);
8
8
  const entry = entries.find((e) => e.version === version);
9
9
  if (entry === undefined) {
10
- console.warn(`Warning: no changelog entry for version ${version}; skipping README injection`);
11
- return undefined;
10
+ return { status: 'skipped', reason: 'no-entry', version };
12
11
  }
13
12
  const renderedSections = renderReleaseNotesSingle(entry, {
14
13
  filter: matchesAudience('all'),
@@ -16,13 +15,12 @@ export function renderInjectedReadmeFromEntries(readme, entries, tag, sectionOrd
16
15
  ...(sectionOrder !== undefined && { sectionOrder }),
17
16
  });
18
17
  if (renderedSections.trimEnd().length === 0) {
19
- console.warn(`Warning: no user-facing release notes for version ${version}; skipping README injection`);
20
- return undefined;
18
+ return { status: 'skipped', reason: 'empty-body', version };
21
19
  }
22
20
  const labeledHeading = `## Release notes — v${version} (${entry.date})`;
23
21
  const releaseNotesMarkdown = `${labeledHeading}\n\n${renderedSections.trimEnd()}`;
24
22
  const injectedReadme = injectSection(readme, 'release-notes', releaseNotesMarkdown);
25
- return { injectedReadme, releaseNotesMarkdown };
23
+ return { status: 'rendered', rendered: { injectedReadme, releaseNotesMarkdown } };
26
24
  }
27
25
  export function renderInjectedReadme(readme, changelogJsonPath, tag, sectionOrder) {
28
26
  if (!existsSync(changelogJsonPath)) {
@@ -34,7 +32,12 @@ export function renderInjectedReadme(readme, changelogJsonPath, tag, sectionOrde
34
32
  console.warn(`Warning: could not parse ${changelogJsonPath}; skipping README injection`);
35
33
  return undefined;
36
34
  }
37
- return renderInjectedReadmeFromEntries(readme, entries, tag, sectionOrder);
35
+ const result = renderInjectedReadmeFromEntries(readme, entries, tag, sectionOrder);
36
+ if (result.status === 'skipped') {
37
+ console.warn(`Warning: ${describeRenderSkip(result.reason, result.version)}; skipping README injection`);
38
+ return undefined;
39
+ }
40
+ return result.rendered;
38
41
  }
39
42
  export function injectReleaseNotesIntoReadme(readmePath, changelogJsonPath, tag, sectionOrder) {
40
43
  const originalReadme = readFileSync(readmePath, 'utf8');
@@ -49,3 +52,8 @@ export function resolveReadmePath(workspacePath) {
49
52
  const readmePath = join(workspacePath, 'README.md');
50
53
  return existsSync(readmePath) ? readmePath : undefined;
51
54
  }
55
+ function describeRenderSkip(reason, version) {
56
+ return reason === 'no-entry'
57
+ ? `no changelog entry for version ${version}`
58
+ : `no user-facing release notes for version ${version}`;
59
+ }
@@ -2,16 +2,18 @@ import { existsSync, readFileSync } from 'node:fs';
2
2
  import path from 'node:path';
3
3
  import { describeError } from '@williamthorsen/toolbelt.errors';
4
4
  import { extractVersion } from "./changelogJsonUtils.js";
5
- import { renderInjectedReadmeFromEntries } from "./injectReleaseNotesIntoReadme.js";
5
+ import { renderInjectedReadmeFromEntries, } from "./injectReleaseNotesIntoReadme.js";
6
6
  export function planReleaseNotesPreviews(options) {
7
7
  const { workspacePath, tag, entries, sectionOrder } = options;
8
8
  const warnings = [];
9
9
  const readmePath = path.join(workspacePath, 'README.md');
10
10
  const readme = readWorkspaceReadme(readmePath, warnings);
11
- const rendered = renderInjectedReadmeFromEntries(readme.content, entries, tag, sectionOrder);
12
- if (rendered === undefined) {
11
+ const result = renderInjectedReadmeFromEntries(readme.content, entries, tag, sectionOrder);
12
+ if (result.status === 'skipped') {
13
+ warnings.push(describePreviewSkip(workspacePath, result.reason, result.version));
13
14
  return { writes: [], warnings };
14
15
  }
16
+ const { rendered } = result;
15
17
  if (!readme.exists && !readme.unreadable) {
16
18
  warnings.push(`${readmePath} not found; skipping injected-README preview but still writing standalone release notes`);
17
19
  }
@@ -29,6 +31,12 @@ export function planReleaseNotesPreviews(options) {
29
31
  });
30
32
  return { writes, warnings };
31
33
  }
34
+ function describePreviewSkip(workspacePath, reason, version) {
35
+ const cause = reason === 'no-entry'
36
+ ? `no changelog entry for version ${version}`
37
+ : `no user-facing release notes for version ${version}`;
38
+ return `${workspacePath}: ${cause}; skipping release-notes previews`;
39
+ }
32
40
  function readWorkspaceReadme(readmePath, warnings) {
33
41
  if (!existsSync(readmePath)) {
34
42
  return { content: '', exists: false, unreadable: false };
@@ -137,12 +137,6 @@ function runMonorepoMode(discoveredPaths, userConfig, options, only, setVersion,
137
137
  'contributing workspace. To use --set-version, run on a config without a `project` block.');
138
138
  process.exit(1);
139
139
  }
140
- if (only !== undefined && config.project !== undefined) {
141
- reportError('--only cannot be combined with a project release. ' +
142
- 'To release a single workspace, use a config without a `project` block, ' +
143
- 'or run a full `prepare` (no --only) to include the project release.');
144
- process.exit(1);
145
- }
146
140
  if (only !== undefined) {
147
141
  const knownNames = config.workspaces.map((w) => w.dir);
148
142
  for (const name of only) {
@@ -183,7 +177,7 @@ function runMonorepoMode(discoveredPaths, userConfig, options, only, setVersion,
183
177
  process.exit(1);
184
178
  }
185
179
  }
186
- runAndReport(() => releasePrepareMono(config, options), dryRun);
180
+ runAndReport(() => releasePrepareMono(config, { ...options, ...(only !== undefined && { only }) }), dryRun);
187
181
  }
188
182
  async function loadAndValidateConfig() {
189
183
  let rawConfig;
@@ -4,6 +4,7 @@ export interface ReleasePrepareOptions {
4
4
  force?: boolean;
5
5
  bumpOverride?: ReleaseType;
6
6
  setVersion?: string;
7
+ only?: string[];
7
8
  withReleaseNotes?: boolean;
8
9
  }
9
10
  export declare function releasePrepare(config: ReleaseConfig, options: ReleasePrepareOptions): ReleasePlan;
@@ -83,17 +83,17 @@ export function releasePrepare(config, options) {
83
83
  }
84
84
  writes.push(...bump.writes);
85
85
  const newTag = `${config.tagPrefix}${bump.newVersion}`;
86
- const overrideWarnings = [];
86
+ const planWarnings = [];
87
87
  const changelogs = planSinglePackageChangelogs({
88
88
  config,
89
89
  commits,
90
90
  newTag,
91
91
  newVersion: bump.newVersion,
92
92
  overrides,
93
- overrideWarnings,
93
+ overrideWarnings: planWarnings,
94
94
  });
95
95
  const { changelogFiles, changelogJsonFiles } = changelogs;
96
- const previewWrites = planSinglePackagePreviews(withReleaseNotes === true, config, newTag, changelogs.entries, overrideWarnings);
96
+ const previewWrites = planSinglePackagePreviews(withReleaseNotes === true, config, newTag, changelogs.entries, planWarnings);
97
97
  writes.push(...changelogs.writes, ...previewWrites);
98
98
  const formatCommandStr = config.formatCommand ?? (hasPrettierConfig() ? 'npx prettier --write' : undefined);
99
99
  let formatCommand;
@@ -125,8 +125,8 @@ export function releasePrepare(config, options) {
125
125
  summary: buildReleaseSummary({ workspaces: [released] }),
126
126
  formatCommand,
127
127
  };
128
- if (overrideWarnings.length > 0) {
129
- plan.warnings = overrideWarnings;
128
+ if (planWarnings.length > 0) {
129
+ plan.warnings = planWarnings;
130
130
  }
131
131
  return plan;
132
132
  }
@@ -229,7 +229,7 @@ function planSinglePackagePreviews(withReleaseNotes, config, newTag, entries, wa
229
229
  return [];
230
230
  }
231
231
  if (!config.changelogJson.enabled) {
232
- console.warn('Warning: --with-release-notes requires changelogJson.enabled; skipping preview generation');
232
+ warnings.push('--with-release-notes requires changelogJson.enabled; skipping preview generation');
233
233
  return [];
234
234
  }
235
235
  if (config.changelogPaths.length === 0) {
@@ -25,10 +25,11 @@ import { renderChangelogMarkdown } from "./renderChangelogMarkdown.js";
25
25
  import { deriveSectionOrder } from "./resolveReleaseNotesConfig.js";
26
26
  import { refreshGitCliffCache } from "./runGitCliff.js";
27
27
  export function releasePrepareMono(config, options) {
28
- const { withReleaseNotes } = options;
28
+ const { only, withReleaseNotes } = options;
29
29
  const writes = [];
30
+ const warnings = [];
30
31
  if (withReleaseNotes === true && !config.changelogJson.enabled) {
31
- console.warn('Warning: --with-release-notes requires changelogJson.enabled; skipping preview generation');
32
+ warnings.push('--with-release-notes requires changelogJson.enabled; skipping preview generation');
32
33
  }
33
34
  const sectionOrder = deriveSectionOrder(resolveWorkTypes(config.workTypes));
34
35
  const overrideContext = createOverrideContext(config.workspaces);
@@ -43,7 +44,6 @@ export function releasePrepareMono(config, options) {
43
44
  const graph = buildDependencyGraph(config.workspaces);
44
45
  const fullReleaseSet = propagateBumps(directBumps, graph, currentVersions);
45
46
  const { sorted: sortedDirs, cyclicDirs } = topologicalSort(fullReleaseSet, graph);
46
- const warnings = [];
47
47
  if (cyclicDirs.length > 0) {
48
48
  warnings.push(`Circular workspace dependencies detected among: ${cyclicDirs.join(', ')}. ` +
49
49
  'Propagation metadata may be incomplete for these workspaces.');
@@ -77,17 +77,23 @@ export function releasePrepareMono(config, options) {
77
77
  });
78
78
  let project;
79
79
  if (config.project !== undefined) {
80
- project = tryStage('project release stage', () => releasePrepareProject({
81
- config,
82
- options,
83
- modifiedFiles,
84
- writes,
85
- tags,
86
- warnings,
87
- rootOverrides: overrideContext.project,
88
- overrideWarnings: overrideContext.overrideWarnings,
89
- globalMatchedRootKeys: overrideContext.globalMatchedRootKeys,
90
- }));
80
+ if (only === undefined) {
81
+ project = tryStage('project release stage', () => releasePrepareProject({
82
+ config,
83
+ options,
84
+ modifiedFiles,
85
+ writes,
86
+ tags,
87
+ warnings,
88
+ rootOverrides: overrideContext.project,
89
+ overrideWarnings: overrideContext.overrideWarnings,
90
+ globalMatchedRootKeys: overrideContext.globalMatchedRootKeys,
91
+ }));
92
+ }
93
+ else {
94
+ warnings.push(`Project release skipped: --only narrows this run to ${only.join(', ')}. ` +
95
+ 'Run `release-kit prepare` without --only to include the project release.');
96
+ }
91
97
  }
92
98
  const formatCommand = planFormatCommand(config, tags, modifiedFiles);
93
99
  for (const overrideKey of overrideContext.project.keys()) {
@@ -22,6 +22,7 @@ function formatSingleWorkspace(result, options) {
22
22
  formatPolicyViolations(lines, workspace.policyViolations);
23
23
  if (workspace.status === 'skipped') {
24
24
  lines.push(`⏭️ ${workspace.skipReason}`);
25
+ formatWarnings(lines, result);
25
26
  return lines.join('\n');
26
27
  }
27
28
  if (workspace.setVersion !== undefined) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@williamthorsen/release-kit",
3
- "version": "10.4.0",
3
+ "version": "10.4.1",
4
4
  "description": "Version-bumping and changelog-generation toolkit for release workflows",
5
5
  "keywords": [
6
6
  "changelog",
@@ -60,7 +60,7 @@
60
60
  "@types/semver": "7.8.0",
61
61
  "@williamthorsen/toolbelt.testing": "0.3.0",
62
62
  "@williamthorsen/toolbelt.vitest": "0.4.0",
63
- "readyup": "0.28.0",
63
+ "readyup": "0.29.0",
64
64
  "smol-toml": "1.7.1"
65
65
  },
66
66
  "engines": {