@williamthorsen/release-kit 10.2.1 → 10.3.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/.readyup/kits/default.js +78 -55
- package/.readyup/kits/npm-auto-publish.js +169 -57
- package/.readyup/manifest.json +6 -6
- package/CHANGELOG.md +54 -0
- package/README.md +18 -6
- package/bin/release-kit.js +1 -1
- package/dist/esm/bin/release-kit.js +4 -4
- package/dist/esm/buildChangelogEntries.js +17 -15
- package/dist/esm/buildDependencyGraph.js +6 -2
- package/dist/esm/buildReleaseSummary.d.ts +1 -1
- package/dist/esm/changelogJsonFile.d.ts +1 -3
- package/dist/esm/changelogJsonFile.js +4 -18
- package/dist/esm/changelogJsonUtils.js +7 -7
- package/dist/esm/changelogOverrides.js +13 -12
- package/dist/esm/checkWorkTypesDrift.js +1 -1
- package/dist/esm/commitCommand.js +3 -13
- package/dist/esm/createTags.js +3 -14
- package/dist/esm/deriveWorkspaceConfig.js +3 -3
- package/dist/esm/detectPackageManager.js +2 -2
- package/dist/esm/detectUndeclaredTagPrefixes.js +1 -1
- package/dist/esm/discoverWorkspaces.js +1 -1
- package/dist/esm/getCommitsSinceTarget.js +2 -2
- package/dist/esm/help/prepareHelp.d.ts +1 -1
- package/dist/esm/help/prepareHelp.js +2 -2
- package/dist/esm/init/checks.js +1 -1
- package/dist/esm/init/detectRepoType.js +1 -1
- package/dist/esm/injectReleaseNotesIntoReadme.d.ts +2 -0
- package/dist/esm/injectReleaseNotesIntoReadme.js +13 -10
- package/dist/esm/loadConfig.js +8 -6
- package/dist/esm/planReleaseNotesPreviews.d.ts +13 -0
- package/dist/esm/planReleaseNotesPreviews.js +43 -0
- package/dist/esm/planVersionBump.d.ts +9 -0
- package/dist/esm/planVersionBump.js +54 -0
- package/dist/esm/prepareCommand.d.ts +0 -4
- package/dist/esm/prepareCommand.js +51 -45
- package/dist/esm/propagateBumps.js +1 -1
- package/dist/esm/releaseFiles.d.ts +4 -0
- package/dist/esm/releaseFiles.js +34 -0
- package/dist/esm/releasePlan.d.ts +10 -0
- package/dist/esm/releasePlan.js +53 -0
- package/dist/esm/releasePrepare.d.ts +3 -3
- package/dist/esm/releasePrepare.js +53 -54
- package/dist/esm/releasePrepareMono.d.ts +3 -2
- package/dist/esm/releasePrepareMono.js +50 -53
- package/dist/esm/releasePrepareProject.d.ts +3 -0
- package/dist/esm/releasePrepareProject.js +33 -37
- package/dist/esm/renderChangelogMarkdown.d.ts +0 -7
- package/dist/esm/renderChangelogMarkdown.js +0 -13
- package/dist/esm/reportPrepare.d.ts +5 -1
- package/dist/esm/reportPrepare.js +37 -17
- package/dist/esm/sync-labels/generateCommand.js +4 -2
- package/dist/esm/sync-labels/presets.js +5 -5
- package/dist/esm/sync-labels/resolveLabels.js +5 -3
- package/dist/esm/syncWorkTypes.js +1 -1
- package/dist/esm/types.d.ts +4 -9
- package/dist/esm/validateConfig.js +11 -11
- package/dist/esm/workTypesData.d.ts +1 -1
- package/dist/esm/workTypesUtils.js +1 -1
- package/package.json +3 -3
- package/dist/esm/bumpAllVersions.d.ts +0 -3
- package/dist/esm/bumpAllVersions.js +0 -61
- package/dist/esm/writeReleaseNotesPreviews.d.ts +0 -18
- package/dist/esm/writeReleaseNotesPreviews.js +0 -63
package/dist/esm/types.d.ts
CHANGED
|
@@ -39,11 +39,6 @@ export interface PropagationSource {
|
|
|
39
39
|
packageName: string;
|
|
40
40
|
newVersion: string;
|
|
41
41
|
}
|
|
42
|
-
export interface BumpResult {
|
|
43
|
-
currentVersion: string;
|
|
44
|
-
newVersion: string;
|
|
45
|
-
files: string[];
|
|
46
|
-
}
|
|
47
42
|
export interface PolicyViolation {
|
|
48
43
|
commitHash: string;
|
|
49
44
|
commitSubject: string;
|
|
@@ -64,6 +59,7 @@ export interface ReleasedWorkspaceResult {
|
|
|
64
59
|
tag: string;
|
|
65
60
|
bumpedFiles: string[];
|
|
66
61
|
changelogFiles: string[];
|
|
62
|
+
previewFiles?: string[];
|
|
67
63
|
commits?: Commit[];
|
|
68
64
|
bumpOverride?: ReleaseType;
|
|
69
65
|
propagatedFrom?: PropagationSource[];
|
|
@@ -93,6 +89,7 @@ export interface ReleasedProjectResult {
|
|
|
93
89
|
tag: string;
|
|
94
90
|
bumpedFiles: string[];
|
|
95
91
|
changelogFiles: string[];
|
|
92
|
+
previewFiles?: string[];
|
|
96
93
|
commits: Commit[];
|
|
97
94
|
bumpOverride?: ReleaseType;
|
|
98
95
|
}
|
|
@@ -111,10 +108,8 @@ export interface PrepareResult {
|
|
|
111
108
|
tags: string[];
|
|
112
109
|
formatCommand?: {
|
|
113
110
|
command: string;
|
|
114
|
-
executed: boolean;
|
|
115
111
|
files: string[];
|
|
116
112
|
} | undefined;
|
|
117
|
-
dryRun: boolean;
|
|
118
113
|
warnings?: string[] | undefined;
|
|
119
114
|
project?: ProjectPrepareResult | undefined;
|
|
120
115
|
}
|
|
@@ -167,8 +162,8 @@ export declare const versionPatternsSchema: z.ZodObject<{
|
|
|
167
162
|
minor: z.ZodArray<z.ZodString>;
|
|
168
163
|
}, z.core.$strict>;
|
|
169
164
|
export declare const breakingPolicyValueSchema: z.ZodEnum<{
|
|
170
|
-
optional: "optional";
|
|
171
165
|
forbidden: "forbidden";
|
|
166
|
+
optional: "optional";
|
|
172
167
|
required: "required";
|
|
173
168
|
}>;
|
|
174
169
|
export declare const labelSpecSchema: z.ZodObject<{
|
|
@@ -186,8 +181,8 @@ export declare const repoLabelsSchema: z.ZodObject<{
|
|
|
186
181
|
export type RepoLabelsConfig = z.infer<typeof repoLabelsSchema>;
|
|
187
182
|
export declare const releaseKitConfigSchema: z.ZodObject<{
|
|
188
183
|
breakingPolicies: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodEnum<{
|
|
189
|
-
optional: "optional";
|
|
190
184
|
forbidden: "forbidden";
|
|
185
|
+
optional: "optional";
|
|
191
186
|
required: "required";
|
|
192
187
|
}>>>;
|
|
193
188
|
changelogJson: z.ZodOptional<z.ZodObject<{
|
|
@@ -30,25 +30,25 @@ function preprocessDeprecatedKeys(raw) {
|
|
|
30
30
|
return { cleaned: raw, deprecationErrors: [] };
|
|
31
31
|
const errors = [];
|
|
32
32
|
const cleaned = { ...raw };
|
|
33
|
-
if (isRecord(cleaned
|
|
33
|
+
if (isRecord(cleaned['releaseNotes']) && Object.hasOwn(cleaned['releaseNotes'], 'shouldCreateGithubRelease')) {
|
|
34
34
|
errors.push('releaseNotes.shouldCreateGithubRelease is no longer supported. Adoption is now signaled by installing the create-github-release workflow. Remove this field from your config; see README for the updated workflow.');
|
|
35
|
-
const releaseNotesCopy = { ...cleaned
|
|
36
|
-
delete releaseNotesCopy
|
|
37
|
-
cleaned
|
|
35
|
+
const releaseNotesCopy = { ...cleaned['releaseNotes'] };
|
|
36
|
+
delete releaseNotesCopy['shouldCreateGithubRelease'];
|
|
37
|
+
cleaned['releaseNotes'] = releaseNotesCopy;
|
|
38
38
|
}
|
|
39
|
-
if (Array.isArray(cleaned
|
|
40
|
-
cleaned
|
|
39
|
+
if (Array.isArray(cleaned['workspaces'])) {
|
|
40
|
+
cleaned['workspaces'] = cleaned['workspaces'].map((ws, i) => {
|
|
41
41
|
if (!isRecord(ws))
|
|
42
42
|
return ws;
|
|
43
43
|
const wsCopy = { ...ws };
|
|
44
|
-
if ('tagPrefix'
|
|
45
|
-
const dir = typeof wsCopy
|
|
44
|
+
if (Object.hasOwn(wsCopy, 'tagPrefix')) {
|
|
45
|
+
const dir = typeof wsCopy['dir'] === 'string' && wsCopy['dir'] !== '' ? wsCopy['dir'] : '<dir>';
|
|
46
46
|
errors.push(`workspaces[${i}]: 'tagPrefix' is no longer supported; remove it to use the default '${dir}-v'`);
|
|
47
|
-
delete wsCopy
|
|
47
|
+
delete wsCopy['tagPrefix'];
|
|
48
48
|
}
|
|
49
|
-
if ('legacyTagPrefixes'
|
|
49
|
+
if (Object.hasOwn(wsCopy, 'legacyTagPrefixes')) {
|
|
50
50
|
errors.push(`workspaces[${i}]: 'legacyTagPrefixes' is no longer supported; use 'legacyIdentities: [{ name, tagPrefix }, ...]' instead`);
|
|
51
|
-
delete wsCopy
|
|
51
|
+
delete wsCopy['legacyTagPrefixes'];
|
|
52
52
|
}
|
|
53
53
|
return wsCopy;
|
|
54
54
|
});
|
|
@@ -11,7 +11,7 @@ export function errorMessage(error) {
|
|
|
11
11
|
return error instanceof Error ? error.message : String(error);
|
|
12
12
|
}
|
|
13
13
|
export function buildFetchInit() {
|
|
14
|
-
const token = process.env
|
|
14
|
+
const token = process.env['GITHUB_TOKEN'];
|
|
15
15
|
if (token === undefined || token === '') {
|
|
16
16
|
return undefined;
|
|
17
17
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@williamthorsen/release-kit",
|
|
3
|
-
"version": "10.
|
|
3
|
+
"version": "10.3.0",
|
|
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",
|
|
@@ -44,11 +44,11 @@
|
|
|
44
44
|
"semver": "7.8.5",
|
|
45
45
|
"yaml": "2.9.0",
|
|
46
46
|
"zod": "4.4.3",
|
|
47
|
-
"@williamthorsen/nmr-core": "0.9.
|
|
47
|
+
"@williamthorsen/nmr-core": "0.9.3"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
50
|
"@types/semver": "7.7.1",
|
|
51
|
-
"readyup": "0.
|
|
51
|
+
"readyup": "0.24.0",
|
|
52
52
|
"smol-toml": "1.7.1"
|
|
53
53
|
},
|
|
54
54
|
"engines": {
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import type { BumpResult, ReleaseType } from './types.js';
|
|
2
|
-
export declare function bumpAllVersions(packageFiles: readonly string[], releaseType: ReleaseType, dryRun: boolean): BumpResult;
|
|
3
|
-
export declare function setAllVersions(packageFiles: readonly string[], newVersion: string, dryRun: boolean): BumpResult;
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import { readFileSync, writeFileSync } from 'node:fs';
|
|
2
|
-
import { bumpVersion } from "./bumpVersion.js";
|
|
3
|
-
function isPackageJson(value) {
|
|
4
|
-
return typeof value === 'object' && value !== null && 'version' in value && typeof value.version === 'string';
|
|
5
|
-
}
|
|
6
|
-
export function bumpAllVersions(packageFiles, releaseType, dryRun) {
|
|
7
|
-
const firstFile = packageFiles[0];
|
|
8
|
-
if (firstFile === undefined) {
|
|
9
|
-
throw new Error('No package files specified');
|
|
10
|
-
}
|
|
11
|
-
const firstPkg = readPackageJson(firstFile);
|
|
12
|
-
const currentVersion = firstPkg.version;
|
|
13
|
-
const newVersion = bumpVersion(currentVersion, releaseType);
|
|
14
|
-
writeVersionToAllFiles(packageFiles, firstFile, firstPkg, newVersion, dryRun);
|
|
15
|
-
return { currentVersion, newVersion, files: [...packageFiles] };
|
|
16
|
-
}
|
|
17
|
-
export function setAllVersions(packageFiles, newVersion, dryRun) {
|
|
18
|
-
const firstFile = packageFiles[0];
|
|
19
|
-
if (firstFile === undefined) {
|
|
20
|
-
throw new Error('No package files specified');
|
|
21
|
-
}
|
|
22
|
-
const firstPkg = readPackageJson(firstFile);
|
|
23
|
-
const currentVersion = firstPkg.version;
|
|
24
|
-
writeVersionToAllFiles(packageFiles, firstFile, firstPkg, newVersion, dryRun);
|
|
25
|
-
return { currentVersion, newVersion, files: [...packageFiles] };
|
|
26
|
-
}
|
|
27
|
-
function writeVersionToAllFiles(packageFiles, firstFile, firstPkg, newVersion, dryRun) {
|
|
28
|
-
for (const filePath of packageFiles) {
|
|
29
|
-
if (dryRun) {
|
|
30
|
-
continue;
|
|
31
|
-
}
|
|
32
|
-
const pkg = filePath === firstFile ? firstPkg : readPackageJson(filePath);
|
|
33
|
-
pkg.version = newVersion;
|
|
34
|
-
try {
|
|
35
|
-
writeFileSync(filePath, JSON.stringify(pkg, null, 2) + '\n', 'utf8');
|
|
36
|
-
}
|
|
37
|
-
catch (error) {
|
|
38
|
-
throw new Error(`Failed to write ${filePath}: ${error instanceof Error ? error.message : String(error)}`);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
function readPackageJson(filePath) {
|
|
43
|
-
let content;
|
|
44
|
-
try {
|
|
45
|
-
content = readFileSync(filePath, 'utf8');
|
|
46
|
-
}
|
|
47
|
-
catch (error) {
|
|
48
|
-
throw new Error(`Failed to read ${filePath}: ${error instanceof Error ? error.message : String(error)}`);
|
|
49
|
-
}
|
|
50
|
-
let parsed;
|
|
51
|
-
try {
|
|
52
|
-
parsed = JSON.parse(content);
|
|
53
|
-
}
|
|
54
|
-
catch (error) {
|
|
55
|
-
throw new Error(`Failed to parse JSON in ${filePath}: ${error instanceof Error ? error.message : String(error)}`);
|
|
56
|
-
}
|
|
57
|
-
if (!isPackageJson(parsed)) {
|
|
58
|
-
throw new Error(`No valid 'version' field found in ${filePath}`);
|
|
59
|
-
}
|
|
60
|
-
return parsed;
|
|
61
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
export interface WriteReleaseNotesPreviewsOptions {
|
|
2
|
-
workspacePath: string;
|
|
3
|
-
tag: string;
|
|
4
|
-
changelogJsonPath: string;
|
|
5
|
-
sectionOrder: string[];
|
|
6
|
-
dryRun: boolean;
|
|
7
|
-
}
|
|
8
|
-
export interface PreviewFileResult {
|
|
9
|
-
filePath: string;
|
|
10
|
-
outcome: 'created' | 'overwritten' | 'skipped-no-readme' | 'failed' | 'dry-run';
|
|
11
|
-
error?: string;
|
|
12
|
-
}
|
|
13
|
-
export interface WriteReleaseNotesPreviewsResult {
|
|
14
|
-
injectedReadme?: PreviewFileResult;
|
|
15
|
-
releaseNotes?: PreviewFileResult;
|
|
16
|
-
renderSkipped: boolean;
|
|
17
|
-
}
|
|
18
|
-
export declare function writeReleaseNotesPreviews(options: WriteReleaseNotesPreviewsOptions): WriteReleaseNotesPreviewsResult;
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
import { reportError, writeFileWithCheck } from '@williamthorsen/nmr-core';
|
|
4
|
-
import { extractVersion } from "./changelogJsonUtils.js";
|
|
5
|
-
import { dim } from "./format.js";
|
|
6
|
-
import { renderInjectedReadme } from "./injectReleaseNotesIntoReadme.js";
|
|
7
|
-
export function writeReleaseNotesPreviews(options) {
|
|
8
|
-
const { workspacePath, tag, changelogJsonPath, sectionOrder, dryRun } = options;
|
|
9
|
-
const version = extractVersion(tag);
|
|
10
|
-
const readmePath = path.join(workspacePath, 'README.md');
|
|
11
|
-
let readmeExists = existsSync(readmePath);
|
|
12
|
-
let readmeUnreadable = false;
|
|
13
|
-
let readmeContent = '';
|
|
14
|
-
if (readmeExists) {
|
|
15
|
-
try {
|
|
16
|
-
readmeContent = readFileSync(readmePath, 'utf8');
|
|
17
|
-
}
|
|
18
|
-
catch (error) {
|
|
19
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
20
|
-
console.warn(`Warning: failed to read ${readmePath}: ${message}; skipping injected-README preview`);
|
|
21
|
-
readmeExists = false;
|
|
22
|
-
readmeUnreadable = true;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
const rendered = renderInjectedReadme(readmeContent, changelogJsonPath, tag, sectionOrder);
|
|
26
|
-
if (rendered === undefined) {
|
|
27
|
-
return { renderSkipped: true };
|
|
28
|
-
}
|
|
29
|
-
const docsDir = path.join(workspacePath, 'docs');
|
|
30
|
-
const readmePreviewPath = path.join(docsDir, `README.v${version}.md`);
|
|
31
|
-
const releaseNotesPreviewPath = path.join(docsDir, `RELEASE_NOTES.v${version}.md`);
|
|
32
|
-
let injectedReadme;
|
|
33
|
-
if (readmeExists) {
|
|
34
|
-
injectedReadme = writePreviewFile(readmePreviewPath, rendered.injectedReadme, dryRun);
|
|
35
|
-
}
|
|
36
|
-
else {
|
|
37
|
-
if (!readmeUnreadable) {
|
|
38
|
-
console.warn(`Warning: ${readmePath} not found; skipping injected-README preview but still writing standalone release notes`);
|
|
39
|
-
}
|
|
40
|
-
injectedReadme = { filePath: readmePreviewPath, outcome: 'skipped-no-readme' };
|
|
41
|
-
}
|
|
42
|
-
const releaseNotesContent = rendered.releaseNotesMarkdown.endsWith('\n')
|
|
43
|
-
? rendered.releaseNotesMarkdown
|
|
44
|
-
: `${rendered.releaseNotesMarkdown}\n`;
|
|
45
|
-
const releaseNotes = writePreviewFile(releaseNotesPreviewPath, releaseNotesContent, dryRun);
|
|
46
|
-
return { injectedReadme, releaseNotes, renderSkipped: false };
|
|
47
|
-
}
|
|
48
|
-
function writePreviewFile(filePath, content, dryRun) {
|
|
49
|
-
if (dryRun) {
|
|
50
|
-
console.info(dim(` [dry-run] Would write ${filePath}`));
|
|
51
|
-
return { filePath, outcome: 'dry-run' };
|
|
52
|
-
}
|
|
53
|
-
const result = writeFileWithCheck(filePath, content, { dryRun: false, overwrite: true });
|
|
54
|
-
if (result.outcome === 'failed') {
|
|
55
|
-
reportError(`Failed to write ${filePath}: ${result.error ?? 'unknown error'}`);
|
|
56
|
-
return { filePath, outcome: 'failed', ...(result.error !== undefined && { error: result.error }) };
|
|
57
|
-
}
|
|
58
|
-
if (result.outcome === 'created' || result.outcome === 'overwritten') {
|
|
59
|
-
console.info(dim(` Wrote ${filePath}`));
|
|
60
|
-
return { filePath, outcome: result.outcome };
|
|
61
|
-
}
|
|
62
|
-
return { filePath, outcome: 'failed', error: `unexpected outcome: ${result.outcome}` };
|
|
63
|
-
}
|