@williamthorsen/release-kit 7.0.0 → 8.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 CHANGED
@@ -2,6 +2,24 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## 8.0.1 — 2026-07-18
6
+
7
+ ### 🐛 Bug fixes
8
+
9
+ - Skip private packages cleanly in publish and create-github-release (#477)
10
+
11
+ Fixes an issue where a workspace marked private in its `package.json` could break a release: `release-kit publish` failed on it, and `release-kit create-github-release` created an unwanted public GitHub Release for it. Both commands now skip private workspaces cleanly: publish reports the skip and continues instead of failing the run, and create-github-release produces no Release for a private package. Any publishable packages released alongside it still publish and still get their Releases. Marking a workspace private is now all it takes to exclude it from both publishing and GitHub Releases.
12
+
13
+ ## 8.0.0 — 2026-07-13
14
+
15
+ ### 🎉 Features
16
+
17
+ - 🚨 **Breaking:** Fail a package that declares types but ships none (#467)
18
+
19
+ `nmr attw` now fails a package that claims to ship type declarations but ships none. Such a package used to pass, leaving every TypeScript consumer of it silently typed as `any`.
20
+
21
+ A package that ships working declarations found only by sitting beside its JavaScript entry point escapes the check, since it declares nothing. Add a `types` entry to bring it under the check.
22
+
5
23
  ## 7.0.0 — 2026-07-01
6
24
 
7
25
  ### 🎉 Features
package/README.md CHANGED
@@ -5,13 +5,13 @@ 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 — v7.0.0 (2026-07-01)
8
+ ## Release notes — v8.0.1 (2026-07-18)
9
9
 
10
- ### 🎉 Features
10
+ ### 🐛 Bug fixes
11
11
 
12
- - 🚨 **Breaking:** Rebuild nmr-compile on a unified tsc emit (#455)
12
+ - Skip private packages cleanly in publish and create-github-release (#477)
13
13
 
14
- `nmr` now compiles a package's JavaScript and type declarations in one step, rewriting every import form — static, re-export, dynamic `import()`, bare side-effect, and tsconfig `paths` aliases — to runnable `.js` in both outputs. It now requires TypeScript 5.7 or newer as a peer dependency.
14
+ Fixes an issue where a workspace marked private in its `package.json` could break a release: `release-kit publish` failed on it, and `release-kit create-github-release` created an unwanted public GitHub Release for it. Both commands now skip private workspaces cleanly: publish reports the skip and continues instead of failing the run, and create-github-release produces no Release for a private package. Any publishable packages released alongside it still publish and still get their Releases. Marking a workspace private is now all it takes to exclude it from both publishing and GitHub Releases.
15
15
  <!-- /section:release-notes -->
16
16
 
17
17
  ## Installation
@@ -624,22 +624,24 @@ Publish packages that have release tags on HEAD. The publish workflow's reusable
624
624
 
625
625
  #### Publishability filter
626
626
 
627
- `publish` operates only on workspaces where `package.json#private` is absent or `false`. A workspace marked `private: true` is "versioned but not published": it can still be tagged by `release-kit tag`, get a `CHANGELOG.md` entry, and get a GitHub Release via `release-kit create-github-release` — only the registry publish step is skipped. Other commands ignore this filter and operate on private workspaces unchanged.
627
+ `publish` and `create-github-release` operate only on workspaces where `package.json#private` is absent or `false`. A workspace marked `private: true` is "versioned but not published": it can still be tagged by `release-kit tag` and get a `CHANGELOG.md` entry, but it is skipped by both `release-kit publish` (no registry publish) and `release-kit create-github-release` (no GitHub Release). `private: true` alone routes a workspace out of publish and announce — no extra release config is required. Other commands ignore this filter and operate on private workspaces unchanged.
628
628
 
629
- The filter behaves differently depending on whether `--tags` is provided:
629
+ An unpublishable tag is always skipped cleanly, never fatal. For `release-kit publish`, whether the skip is announced depends on how the tag was resolved:
630
630
 
631
631
  - **Without `--tags`** (implicit resolution): unpublishable tags on HEAD are silently filtered. The pre-publish listing shows only the publishable subset. If the filter empties the set, `release-kit publish` prints `Nothing to publish.` and exits 0.
632
- - **With `--tags`** (explicit naming): if any named tag points at an unpublishable workspace, `release-kit publish` exits 1 with one error line per unpublishable tag, citing `package.json#private`. Explicit naming surfaces the contradiction rather than silently dropping the tag.
632
+ - **With `--tags`** (explicit naming): each named tag pointing at an unpublishable workspace is skipped with a warning, and any publishable tags named in the same command still publish.
633
633
 
634
- Example output when an explicit tag is unpublishable:
634
+ `release-kit create-github-release` skips unpublishable workspaces with a warning regardless of `--tags`; an all-private tag set is a clean no-op.
635
+
636
+ Example warning when an explicit tag is unpublishable:
635
637
 
636
638
  ```
637
- Error: basic-v1.0.0 (packages/basic) cannot be published: package.json#private is true.
639
+ Skipping basic-v1.0.0 (packages/basic): package.json#private is true.
638
640
  ```
639
641
 
640
642
  ### `release-kit create-github-release`
641
643
 
642
- 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.
644
+ Create GitHub Releases from `changelog.json` for tags on HEAD. Independent of `npm publish`: invoking this command creates Releases for publishable packages whether or not they were published to a registry. Private workspaces are skipped (see [Publishability filter](#publishability-filter)).
643
645
 
644
646
  | Flag | Description |
645
647
  | ---------------------- | ------------------------------------------------------------------------- |
@@ -142,7 +142,8 @@ function showCreateGithubReleaseHelp() {
142
142
  console.info(`
143
143
  Usage: release-kit create-github-release [options]
144
144
 
145
- Create GitHub Releases from changelog.json for tags on HEAD.
145
+ Create GitHub Releases from changelog.json for tags on HEAD. Private
146
+ (package.json#private) workspaces are skipped with a warning and get no Release.
146
147
 
147
148
  Options:
148
149
  --dry-run Preview without creating releases
@@ -241,7 +242,8 @@ Usage: release-kit publish [options]
241
242
 
242
243
  Publish packages that have release tags on HEAD. Operates only on workspaces where
243
244
  package.json#private is absent or false. Without --tags, unpublishable workspaces are
244
- silently filtered out. With --tags, naming an unpublishable tag is an error.
245
+ silently filtered out. With --tags, an unpublishable tag is skipped with a warning while
246
+ any publishable tags still publish.
245
247
 
246
248
  Options:
247
249
  --dry-run Preview without publishing
@@ -1,5 +1,6 @@
1
1
  import { parseArgsOrExit, reportError } from '@williamthorsen/nmr-core';
2
2
  import { createGithubReleases } from "./createGithubRelease.js";
3
+ import { formatPrivateSkip } from "./formatPrivateSkip.js";
3
4
  import { parseRequestedTags } from "./parseRequestedTags.js";
4
5
  import { resolveCommandTags } from "./resolveCommandTags.js";
5
6
  import { resolveReleaseNotesConfig } from "./resolveReleaseNotesConfig.js";
@@ -12,10 +13,19 @@ export async function createGithubReleaseCommand(argv) {
12
13
  const { dryRun } = parsed.flags;
13
14
  const requestedTags = parseRequestedTags(parsed.flags.tags);
14
15
  const resolvedTags = await resolveCommandTags(requestedTags);
16
+ const publishableTags = resolvedTags.filter((resolvedTag) => resolvedTag.isPublishable);
17
+ for (const resolvedTag of resolvedTags) {
18
+ if (!resolvedTag.isPublishable) {
19
+ console.warn(formatPrivateSkip(resolvedTag));
20
+ }
21
+ }
22
+ if (publishableTags.length === 0) {
23
+ return;
24
+ }
15
25
  const { changelogJsonOutputPath, sectionOrder } = await resolveReleaseNotesConfig({ strictLoad: true });
16
26
  let outcome;
17
27
  try {
18
- outcome = createGithubReleases(resolvedTags, changelogJsonOutputPath, dryRun, sectionOrder);
28
+ outcome = createGithubReleases(publishableTags, changelogJsonOutputPath, dryRun, sectionOrder);
19
29
  }
20
30
  catch (error) {
21
31
  reportError(`Failed to create GitHub Releases: ${error instanceof Error ? error.message : String(error)}`);
@@ -0,0 +1,2 @@
1
+ import type { ResolvedTag } from './resolveReleaseTags.js';
2
+ export declare function formatPrivateSkip(resolvedTag: Pick<ResolvedTag, 'tag' | 'workspacePath'>): string;
@@ -0,0 +1,3 @@
1
+ export function formatPrivateSkip(resolvedTag) {
2
+ return `Skipping ${resolvedTag.tag} (${resolvedTag.workspacePath}): package.json#private is true.`;
3
+ }
@@ -3,6 +3,7 @@ import { join } from 'node:path';
3
3
  import { parseArgsOrExit, reportError } from '@williamthorsen/nmr-core';
4
4
  import { assertCleanWorkingTree } from "./assertCleanWorkingTree.js";
5
5
  import { detectPackageManager } from "./detectPackageManager.js";
6
+ import { formatPrivateSkip } from "./formatPrivateSkip.js";
6
7
  import { injectReleaseNotesIntoReadme, resolveReadmePath } from "./injectReleaseNotesIntoReadme.js";
7
8
  import { parseRequestedTags } from "./parseRequestedTags.js";
8
9
  import { publishPackage } from "./publish.js";
@@ -82,11 +83,10 @@ function filterPublishableTags(resolvedTags, isExplicit) {
82
83
  for (const tag of resolvedTags) {
83
84
  (tag.isPublishable ? publishable : unpublishable).push(tag);
84
85
  }
85
- if (isExplicit && unpublishable.length > 0) {
86
- for (const { tag, workspacePath } of unpublishable) {
87
- reportError(`${tag} (${workspacePath}) cannot be published: package.json#private is true.`);
86
+ if (isExplicit) {
87
+ for (const resolvedTag of unpublishable) {
88
+ console.warn(formatPrivateSkip(resolvedTag));
88
89
  }
89
- process.exit(1);
90
90
  }
91
91
  return publishable;
92
92
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@williamthorsen/release-kit",
3
- "version": "7.0.0",
3
+ "version": "8.0.1",
4
4
  "description": "Version-bumping and changelog-generation toolkit for release workflows",
5
5
  "keywords": [],
6
6
  "homepage": "https://github.com/williamthorsen/node-monorepo-tools/tree/main/packages/release-kit#readme",
@@ -17,6 +17,7 @@
17
17
  "type": "module",
18
18
  "exports": {
19
19
  ".": {
20
+ "types": "./dist/esm/index.d.ts",
20
21
  "import": "./dist/esm/index.js"
21
22
  }
22
23
  },
@@ -38,7 +39,7 @@
38
39
  "semver": "7.8.5",
39
40
  "yaml": "2.9.0",
40
41
  "zod": "4.4.3",
41
- "@williamthorsen/nmr-core": "0.6.0"
42
+ "@williamthorsen/nmr-core": "0.7.0"
42
43
  },
43
44
  "devDependencies": {
44
45
  "@types/semver": "7.7.1",
package/dist/esm/.cache DELETED
@@ -1 +0,0 @@
1
- bdf7751e6eabd018a208cdf137b867bd284af3f4ee3beea07ca4d1a39197e00e