@williamthorsen/release-kit 4.7.0 → 5.0.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 +80 -0
- package/README.md +310 -40
- package/cliff.toml.template +2 -1
- package/dist/esm/.cache +1 -1
- package/dist/esm/bin/release-kit.js +67 -12
- package/dist/esm/buildDependencyGraph.d.ts +3 -3
- package/dist/esm/buildDependencyGraph.js +10 -10
- package/dist/esm/buildReleaseSummary.js +4 -4
- 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/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/defaults.js +5 -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/generateChangelogJson.js +37 -1
- 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 +9 -3
- package/dist/esm/index.js +12 -3
- package/dist/esm/init/detectRepoType.js +1 -2
- 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 +40 -10
- package/dist/esm/injectReleaseNotesIntoReadme.d.ts +6 -1
- package/dist/esm/injectReleaseNotesIntoReadme.js +20 -7
- package/dist/esm/loadConfig.d.ts +2 -1
- package/dist/esm/loadConfig.js +65 -12
- 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 +75 -27
- 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/publishCommand.js +8 -13
- package/dist/esm/pushCommand.d.ts +1 -0
- package/dist/esm/pushCommand.js +47 -0
- package/dist/esm/pushRelease.d.ts +11 -0
- package/dist/esm/pushRelease.js +26 -0
- 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 +72 -30
- package/dist/esm/releasePrepareMono.js +235 -112
- package/dist/esm/renderReleaseNotes.d.ts +1 -0
- package/dist/esm/renderReleaseNotes.js +29 -2
- package/dist/esm/reportPrepare.js +100 -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/sync-labels/templates.js +1 -1
- package/dist/esm/tagCommand.js +1 -1
- package/dist/esm/types.d.ts +22 -7
- package/dist/esm/validateConfig.js +179 -36
- 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 +2 -2
- 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/githubReleaseCommand.d.ts +0 -1
- package/dist/esm/githubReleaseCommand.js +0 -35
|
@@ -6,9 +6,13 @@ function isNoTagError(err) {
|
|
|
6
6
|
function errorMessage(err) {
|
|
7
7
|
return err instanceof Error ? err.message : String(err);
|
|
8
8
|
}
|
|
9
|
-
function findLatestTag(
|
|
9
|
+
function findLatestTag(tagPrefixes) {
|
|
10
|
+
if (tagPrefixes.length === 0) {
|
|
11
|
+
throw new Error("findLatestTag: tagPrefixes must contain at least one entry");
|
|
12
|
+
}
|
|
13
|
+
const matchArgs = tagPrefixes.map((prefix) => `--match=${prefix}*`);
|
|
10
14
|
try {
|
|
11
|
-
const tagResult = execFileSync("git", ["describe", "--tags", "--abbrev=0",
|
|
15
|
+
const tagResult = execFileSync("git", ["describe", "--tags", "--abbrev=0", ...matchArgs], {
|
|
12
16
|
encoding: "utf8",
|
|
13
17
|
stdio: ["pipe", "pipe", "pipe"]
|
|
14
18
|
}).trim();
|
|
@@ -35,8 +39,8 @@ function parseLogOutput(logOutput) {
|
|
|
35
39
|
}
|
|
36
40
|
return commits;
|
|
37
41
|
}
|
|
38
|
-
function getCommitsSinceTarget(
|
|
39
|
-
const tag = findLatestTag(
|
|
42
|
+
function getCommitsSinceTarget(tagPrefixes, paths) {
|
|
43
|
+
const tag = findLatestTag(tagPrefixes);
|
|
40
44
|
const range = tag === void 0 ? "HEAD" : `${tag}..HEAD`;
|
|
41
45
|
const format = `%s${FIELD_SEPARATOR}%H`;
|
|
42
46
|
const args = ["log", range, `--pretty=format:${format}`];
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -1,32 +1,36 @@
|
|
|
1
1
|
export type { CreateTagsOptions } from './createTags.ts';
|
|
2
2
|
export type { PackageManager } from './detectPackageManager.ts';
|
|
3
3
|
export type { GenerateChangelogOptions } from './generateChangelogs.ts';
|
|
4
|
+
export type { RetiredPackagePreviewEntry } from './previewTagPrefixes.ts';
|
|
4
5
|
export type { PublishOptions } from './publish.ts';
|
|
5
6
|
export type { ReleasePrepareOptions } from './releasePrepare.ts';
|
|
6
7
|
export type { ResolvedTag } from './resolveReleaseTags.ts';
|
|
7
8
|
export type { LabelDefinition, SyncLabelsConfig } from './sync-labels/types.ts';
|
|
8
|
-
export type { BumpResult, ChangelogAudience, ChangelogEntry, ChangelogItem, ChangelogJsonConfig, ChangelogSection, Commit,
|
|
9
|
+
export type { BumpResult, ChangelogAudience, ChangelogEntry, ChangelogItem, ChangelogJsonConfig, ChangelogSection, Commit, LegacyIdentity, MonorepoReleaseConfig, ParsedCommit, PrepareResult, ReleaseConfig, ReleaseKitConfig, ReleaseNotesConfig, ReleaseType, RetiredPackage, VersionPatterns, WorkspaceConfig, WorkspaceOverride, WorkspacePrepareResult, WorkTypeConfig, } from './types.ts';
|
|
9
10
|
export { DEFAULT_CHANGELOG_JSON_CONFIG, DEFAULT_RELEASE_NOTES_CONFIG, DEFAULT_VERSION_PATTERNS, DEFAULT_WORK_TYPES, } from './defaults.ts';
|
|
10
11
|
export { buildReleaseSummary } from './buildReleaseSummary.ts';
|
|
11
12
|
export { bumpAllVersions } from './bumpAllVersions.ts';
|
|
12
13
|
export { bumpVersion } from './bumpVersion.ts';
|
|
13
14
|
export { commitCommand } from './commitCommand.ts';
|
|
14
|
-
export { component } from './component.ts';
|
|
15
15
|
export type { CreateGithubReleaseOptions } from './createGithubRelease.ts';
|
|
16
16
|
export { createGithubRelease, createGithubReleases } from './createGithubRelease.ts';
|
|
17
17
|
export { createTags } from './createTags.ts';
|
|
18
18
|
export { deleteFileIfExists } from './deleteFileIfExists.ts';
|
|
19
|
+
export { deriveWorkspaceConfig } from './deriveWorkspaceConfig.ts';
|
|
19
20
|
export { detectPackageManager } from './detectPackageManager.ts';
|
|
20
21
|
export { determineBumpType } from './determineBumpType.ts';
|
|
21
22
|
export { discoverWorkspaces } from './discoverWorkspaces.ts';
|
|
22
23
|
export { generateChangelogJson, generateSyntheticChangelogJson } from './generateChangelogJson.ts';
|
|
23
24
|
export { generateChangelog, generateChangelogs } from './generateChangelogs.ts';
|
|
24
25
|
export { getCommitsSinceTarget } from './getCommitsSinceTarget.ts';
|
|
25
|
-
export {
|
|
26
|
+
export type { RenderedInjectedReadme } from './injectReleaseNotesIntoReadme.ts';
|
|
27
|
+
export { injectReleaseNotesIntoReadme, renderInjectedReadme, resolveReadmePath, } from './injectReleaseNotesIntoReadme.ts';
|
|
26
28
|
export { injectSection } from './injectSection.ts';
|
|
27
29
|
export { COMMIT_PREPROCESSOR_PATTERNS, parseCommitMessage } from './parseCommitMessage.ts';
|
|
28
30
|
export { RELEASE_SUMMARY_FILE, RELEASE_TAGS_FILE, writeReleaseTags } from './prepareCommand.ts';
|
|
29
31
|
export { publishPackage } from './publish.ts';
|
|
32
|
+
export type { PushReleaseOptions } from './pushRelease.ts';
|
|
33
|
+
export { pushRelease } from './pushRelease.ts';
|
|
30
34
|
export { releasePrepare } from './releasePrepare.ts';
|
|
31
35
|
export { releasePrepareMono } from './releasePrepareMono.ts';
|
|
32
36
|
export type { RenderOptions } from './renderReleaseNotes.ts';
|
|
@@ -35,3 +39,5 @@ export { reportPrepare } from './reportPrepare.ts';
|
|
|
35
39
|
export { resolveCommandTags } from './resolveCommandTags.ts';
|
|
36
40
|
export { resolveReleaseTags } from './resolveReleaseTags.ts';
|
|
37
41
|
export { stripScope } from './stripScope.ts';
|
|
42
|
+
export type { PreviewFileResult, WriteReleaseNotesPreviewsOptions, WriteReleaseNotesPreviewsResult, } from './writeReleaseNotesPreviews.ts';
|
|
43
|
+
export { writeReleaseNotesPreviews } from './writeReleaseNotesPreviews.ts';
|
package/dist/esm/index.js
CHANGED
|
@@ -8,21 +8,26 @@ import { buildReleaseSummary } from "./buildReleaseSummary.js";
|
|
|
8
8
|
import { bumpAllVersions } from "./bumpAllVersions.js";
|
|
9
9
|
import { bumpVersion } from "./bumpVersion.js";
|
|
10
10
|
import { commitCommand } from "./commitCommand.js";
|
|
11
|
-
import { component } from "./component.js";
|
|
12
11
|
import { createGithubRelease, createGithubReleases } from "./createGithubRelease.js";
|
|
13
12
|
import { createTags } from "./createTags.js";
|
|
14
13
|
import { deleteFileIfExists } from "./deleteFileIfExists.js";
|
|
14
|
+
import { deriveWorkspaceConfig } from "./deriveWorkspaceConfig.js";
|
|
15
15
|
import { detectPackageManager } from "./detectPackageManager.js";
|
|
16
16
|
import { determineBumpType } from "./determineBumpType.js";
|
|
17
17
|
import { discoverWorkspaces } from "./discoverWorkspaces.js";
|
|
18
18
|
import { generateChangelogJson, generateSyntheticChangelogJson } from "./generateChangelogJson.js";
|
|
19
19
|
import { generateChangelog, generateChangelogs } from "./generateChangelogs.js";
|
|
20
20
|
import { getCommitsSinceTarget } from "./getCommitsSinceTarget.js";
|
|
21
|
-
import {
|
|
21
|
+
import {
|
|
22
|
+
injectReleaseNotesIntoReadme,
|
|
23
|
+
renderInjectedReadme,
|
|
24
|
+
resolveReadmePath
|
|
25
|
+
} from "./injectReleaseNotesIntoReadme.js";
|
|
22
26
|
import { injectSection } from "./injectSection.js";
|
|
23
27
|
import { COMMIT_PREPROCESSOR_PATTERNS, parseCommitMessage } from "./parseCommitMessage.js";
|
|
24
28
|
import { RELEASE_SUMMARY_FILE, RELEASE_TAGS_FILE, writeReleaseTags } from "./prepareCommand.js";
|
|
25
29
|
import { publishPackage } from "./publish.js";
|
|
30
|
+
import { pushRelease } from "./pushRelease.js";
|
|
26
31
|
import { releasePrepare } from "./releasePrepare.js";
|
|
27
32
|
import { releasePrepareMono } from "./releasePrepareMono.js";
|
|
28
33
|
import { matchesAudience, renderReleaseNotesMulti, renderReleaseNotesSingle } from "./renderReleaseNotes.js";
|
|
@@ -30,6 +35,7 @@ import { reportPrepare } from "./reportPrepare.js";
|
|
|
30
35
|
import { resolveCommandTags } from "./resolveCommandTags.js";
|
|
31
36
|
import { resolveReleaseTags } from "./resolveReleaseTags.js";
|
|
32
37
|
import { stripScope } from "./stripScope.js";
|
|
38
|
+
import { writeReleaseNotesPreviews } from "./writeReleaseNotesPreviews.js";
|
|
33
39
|
export {
|
|
34
40
|
COMMIT_PREPROCESSOR_PATTERNS,
|
|
35
41
|
DEFAULT_CHANGELOG_JSON_CONFIG,
|
|
@@ -42,11 +48,11 @@ export {
|
|
|
42
48
|
bumpAllVersions,
|
|
43
49
|
bumpVersion,
|
|
44
50
|
commitCommand,
|
|
45
|
-
component,
|
|
46
51
|
createGithubRelease,
|
|
47
52
|
createGithubReleases,
|
|
48
53
|
createTags,
|
|
49
54
|
deleteFileIfExists,
|
|
55
|
+
deriveWorkspaceConfig,
|
|
50
56
|
detectPackageManager,
|
|
51
57
|
determineBumpType,
|
|
52
58
|
discoverWorkspaces,
|
|
@@ -60,8 +66,10 @@ export {
|
|
|
60
66
|
matchesAudience,
|
|
61
67
|
parseCommitMessage,
|
|
62
68
|
publishPackage,
|
|
69
|
+
pushRelease,
|
|
63
70
|
releasePrepare,
|
|
64
71
|
releasePrepareMono,
|
|
72
|
+
renderInjectedReadme,
|
|
65
73
|
renderReleaseNotesMulti,
|
|
66
74
|
renderReleaseNotesSingle,
|
|
67
75
|
reportPrepare,
|
|
@@ -69,5 +77,6 @@ export {
|
|
|
69
77
|
resolveReadmePath,
|
|
70
78
|
resolveReleaseTags,
|
|
71
79
|
stripScope,
|
|
80
|
+
writeReleaseNotesPreviews,
|
|
72
81
|
writeReleaseTags
|
|
73
82
|
};
|
|
@@ -4,13 +4,12 @@ function detectRepoType() {
|
|
|
4
4
|
if (existsSync("pnpm-workspace.yaml")) {
|
|
5
5
|
return "monorepo";
|
|
6
6
|
}
|
|
7
|
-
|
|
7
|
+
if (existsSync("package.json")) {
|
|
8
8
|
const raw = readFileSync("package.json", "utf8");
|
|
9
9
|
const pkg = parseJsonRecord(raw);
|
|
10
10
|
if (pkg !== void 0 && Array.isArray(pkg.workspaces)) {
|
|
11
11
|
return "monorepo";
|
|
12
12
|
}
|
|
13
|
-
} catch {
|
|
14
13
|
}
|
|
15
14
|
return "single-package";
|
|
16
15
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { printError, printStep, printSuccess, reportWriteResult } from "@williamthorsen/
|
|
1
|
+
import { printError, printStep, printSuccess, reportWriteResult } from "@williamthorsen/nmr-core";
|
|
2
2
|
import { hasPackageJson, isGitRepo, usesPnpm } from "./checks.js";
|
|
3
3
|
import { detectRepoType } from "./detectRepoType.js";
|
|
4
4
|
import { scaffoldFiles } from "./scaffold.js";
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from "node:fs";
|
|
2
2
|
import { resolve } from "node:path";
|
|
3
|
-
import { writeFileWithCheck } from "@williamthorsen/
|
|
4
|
-
import {
|
|
5
|
-
import { publishWorkflow, releaseConfigScript, releaseWorkflow } from "./templates.js";
|
|
3
|
+
import { findPackageRoot, writeFileWithCheck } from "@williamthorsen/nmr-core";
|
|
4
|
+
import { createGithubReleaseWorkflow, publishWorkflow, releaseConfigScript, releaseWorkflow } from "./templates.js";
|
|
6
5
|
function copyCliffTemplate(dryRun, overwrite) {
|
|
7
6
|
const destPath = ".config/git-cliff.toml";
|
|
8
7
|
const root = findPackageRoot(import.meta.url);
|
|
@@ -21,8 +20,12 @@ function copyCliffTemplate(dryRun, overwrite) {
|
|
|
21
20
|
}
|
|
22
21
|
function scaffoldFiles({ repoType, dryRun, overwrite, withConfig }) {
|
|
23
22
|
const results = [
|
|
24
|
-
writeFileWithCheck(".github/workflows/release.yaml",
|
|
25
|
-
|
|
23
|
+
writeFileWithCheck(".github/workflows/create-github-release.yaml", createGithubReleaseWorkflow(repoType), {
|
|
24
|
+
dryRun,
|
|
25
|
+
overwrite
|
|
26
|
+
}),
|
|
27
|
+
writeFileWithCheck(".github/workflows/publish.yaml", publishWorkflow(repoType), { dryRun, overwrite }),
|
|
28
|
+
writeFileWithCheck(".github/workflows/release.yaml", releaseWorkflow(repoType), { dryRun, overwrite })
|
|
26
29
|
];
|
|
27
30
|
if (withConfig) {
|
|
28
31
|
results.push(
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { RepoType } from './detectRepoType.ts';
|
|
2
2
|
export declare function releaseConfigScript(repoType: RepoType): string;
|
|
3
3
|
export declare function publishWorkflow(repoType: RepoType): string;
|
|
4
|
+
export declare function createGithubReleaseWorkflow(repoType: RepoType): string;
|
|
4
5
|
export declare function releaseWorkflow(repoType: RepoType): string;
|
|
@@ -3,8 +3,12 @@ function releaseConfigScript(repoType) {
|
|
|
3
3
|
return `import type { ReleaseKitConfig } from '@williamthorsen/release-kit';
|
|
4
4
|
|
|
5
5
|
const config: ReleaseKitConfig = {
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
releaseNotes: {
|
|
7
|
+
shouldInjectIntoReadme: true,
|
|
8
|
+
},
|
|
9
|
+
|
|
10
|
+
// Uncomment to exclude workspaces from release processing:
|
|
11
|
+
// workspaces: [
|
|
8
12
|
// { dir: 'my-package', shouldExclude: true },
|
|
9
13
|
// ],
|
|
10
14
|
|
|
@@ -23,6 +27,10 @@ export default config;
|
|
|
23
27
|
return `import type { ReleaseKitConfig } from '@williamthorsen/release-kit';
|
|
24
28
|
|
|
25
29
|
const config: ReleaseKitConfig = {
|
|
30
|
+
releaseNotes: {
|
|
31
|
+
shouldInjectIntoReadme: true,
|
|
32
|
+
},
|
|
33
|
+
|
|
26
34
|
// Formatting: prettier is auto-detected. Set formatCommand to override.
|
|
27
35
|
|
|
28
36
|
// Uncomment to override the default version patterns:
|
|
@@ -36,7 +44,7 @@ export default config;
|
|
|
36
44
|
`;
|
|
37
45
|
}
|
|
38
46
|
function publishWorkflow(repoType) {
|
|
39
|
-
const tagPattern = repoType === "monorepo" ? "'*-v[0-9]*'" : "'v[0-9]*'";
|
|
47
|
+
const tagPattern = repoType === "monorepo" ? "'*-v[0-9]*.[0-9]*.[0-9]*'" : "'v[0-9]*.[0-9]*.[0-9]*'";
|
|
40
48
|
return `# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
|
|
41
49
|
name: Publish
|
|
42
50
|
|
|
@@ -51,9 +59,30 @@ permissions:
|
|
|
51
59
|
|
|
52
60
|
jobs:
|
|
53
61
|
publish:
|
|
54
|
-
uses: williamthorsen/node-monorepo-tools/.github/workflows/publish.reusable.yaml@publish-
|
|
62
|
+
uses: williamthorsen/node-monorepo-tools/.github/workflows/publish.reusable.yaml@workflow/publish-v1
|
|
63
|
+
with:
|
|
64
|
+
provenance: true
|
|
65
|
+
tags: \${{ github.ref_name }}
|
|
66
|
+
`;
|
|
67
|
+
}
|
|
68
|
+
function createGithubReleaseWorkflow(repoType) {
|
|
69
|
+
const tagPattern = repoType === "monorepo" ? "'*-v[0-9]*.[0-9]*.[0-9]*'" : "'v[0-9]*.[0-9]*.[0-9]*'";
|
|
70
|
+
return `# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
|
|
71
|
+
name: Create GitHub Release
|
|
72
|
+
|
|
73
|
+
on:
|
|
74
|
+
push:
|
|
75
|
+
tags:
|
|
76
|
+
- ${tagPattern}
|
|
77
|
+
|
|
78
|
+
permissions:
|
|
79
|
+
contents: write
|
|
80
|
+
|
|
81
|
+
jobs:
|
|
82
|
+
create-github-release:
|
|
83
|
+
uses: williamthorsen/node-monorepo-tools/.github/workflows/create-github-release.reusable.yaml@workflow/create-github-release-v1
|
|
55
84
|
with:
|
|
56
|
-
|
|
85
|
+
tag: \${{ github.ref_name }}
|
|
57
86
|
`;
|
|
58
87
|
}
|
|
59
88
|
function releaseWorkflow(repoType) {
|
|
@@ -65,7 +94,7 @@ on:
|
|
|
65
94
|
workflow_dispatch:
|
|
66
95
|
inputs:
|
|
67
96
|
only:
|
|
68
|
-
description: '
|
|
97
|
+
description: 'Workspaces to release (comma-separated, leave empty for all)'
|
|
69
98
|
required: false
|
|
70
99
|
type: string
|
|
71
100
|
bump:
|
|
@@ -78,7 +107,7 @@ on:
|
|
|
78
107
|
- minor
|
|
79
108
|
- major
|
|
80
109
|
force:
|
|
81
|
-
description: 'Force a
|
|
110
|
+
description: 'Force a release even when there are no commits since the last tag (requires --bump)'
|
|
82
111
|
required: false
|
|
83
112
|
type: boolean
|
|
84
113
|
default: false
|
|
@@ -89,7 +118,7 @@ permissions:
|
|
|
89
118
|
|
|
90
119
|
jobs:
|
|
91
120
|
release:
|
|
92
|
-
uses: williamthorsen/node-monorepo-tools/.github/workflows/release.reusable.yaml@release-
|
|
121
|
+
uses: williamthorsen/node-monorepo-tools/.github/workflows/release.reusable.yaml@workflow/release-v1
|
|
93
122
|
with:
|
|
94
123
|
only: \${{ inputs.only }}
|
|
95
124
|
bump: \${{ inputs.bump }}
|
|
@@ -112,7 +141,7 @@ on:
|
|
|
112
141
|
- minor
|
|
113
142
|
- major
|
|
114
143
|
force:
|
|
115
|
-
description: 'Force a
|
|
144
|
+
description: 'Force a release even when there are no commits since the last tag (requires --bump)'
|
|
116
145
|
required: false
|
|
117
146
|
type: boolean
|
|
118
147
|
default: false
|
|
@@ -123,13 +152,14 @@ permissions:
|
|
|
123
152
|
|
|
124
153
|
jobs:
|
|
125
154
|
release:
|
|
126
|
-
uses: williamthorsen/node-monorepo-tools/.github/workflows/release.reusable.yaml@release-
|
|
155
|
+
uses: williamthorsen/node-monorepo-tools/.github/workflows/release.reusable.yaml@workflow/release-v1
|
|
127
156
|
with:
|
|
128
157
|
bump: \${{ inputs.bump }}
|
|
129
158
|
force: \${{ inputs.force }}
|
|
130
159
|
`;
|
|
131
160
|
}
|
|
132
161
|
export {
|
|
162
|
+
createGithubReleaseWorkflow,
|
|
133
163
|
publishWorkflow,
|
|
134
164
|
releaseConfigScript,
|
|
135
165
|
releaseWorkflow
|
|
@@ -1,2 +1,7 @@
|
|
|
1
|
-
export
|
|
1
|
+
export interface RenderedInjectedReadme {
|
|
2
|
+
injectedReadme: string;
|
|
3
|
+
releaseNotesMarkdown: string;
|
|
4
|
+
}
|
|
5
|
+
export declare function renderInjectedReadme(readme: string, changelogJsonPath: string, tag: string, sectionOrder?: string[]): RenderedInjectedReadme | undefined;
|
|
6
|
+
export declare function injectReleaseNotesIntoReadme(readmePath: string, changelogJsonPath: string, tag: string, sectionOrder?: string[]): string | undefined;
|
|
2
7
|
export declare function resolveReadmePath(workspacePath: string): string | undefined;
|
|
@@ -3,12 +3,11 @@ import { join } from "node:path";
|
|
|
3
3
|
import { extractVersion, readChangelogEntries } from "./changelogJsonUtils.js";
|
|
4
4
|
import { injectSection } from "./injectSection.js";
|
|
5
5
|
import { matchesAudience, renderReleaseNotesSingle } from "./renderReleaseNotes.js";
|
|
6
|
-
function
|
|
6
|
+
function renderInjectedReadme(readme, changelogJsonPath, tag, sectionOrder) {
|
|
7
7
|
if (!existsSync(changelogJsonPath)) {
|
|
8
8
|
console.warn(`Warning: ${changelogJsonPath} not found; skipping README injection`);
|
|
9
9
|
return void 0;
|
|
10
10
|
}
|
|
11
|
-
const originalReadme = readFileSync(readmePath, "utf8");
|
|
12
11
|
const version = extractVersion(tag);
|
|
13
12
|
const entries = readChangelogEntries(changelogJsonPath);
|
|
14
13
|
if (entries === void 0) {
|
|
@@ -20,16 +19,29 @@ function injectReleaseNotesIntoReadme(readmePath, changelogJsonPath, tag) {
|
|
|
20
19
|
console.warn(`Warning: no changelog entry for version ${version}; skipping README injection`);
|
|
21
20
|
return void 0;
|
|
22
21
|
}
|
|
23
|
-
const
|
|
22
|
+
const renderedSections = renderReleaseNotesSingle(entry, {
|
|
24
23
|
filter: matchesAudience("all"),
|
|
25
|
-
includeHeading: false
|
|
24
|
+
includeHeading: false,
|
|
25
|
+
...sectionOrder === void 0 ? {} : { sectionOrder }
|
|
26
26
|
});
|
|
27
|
-
if (
|
|
27
|
+
if (renderedSections.trimEnd().length === 0) {
|
|
28
28
|
console.warn(`Warning: no user-facing release notes for version ${version}; skipping README injection`);
|
|
29
29
|
return void 0;
|
|
30
30
|
}
|
|
31
|
-
const
|
|
32
|
-
|
|
31
|
+
const labeledHeading = `## Release notes \u2014 v${version} (${entry.date})`;
|
|
32
|
+
const releaseNotesMarkdown = `${labeledHeading}
|
|
33
|
+
|
|
34
|
+
${renderedSections.trimEnd()}`;
|
|
35
|
+
const injectedReadme = injectSection(readme, "release-notes", releaseNotesMarkdown);
|
|
36
|
+
return { injectedReadme, releaseNotesMarkdown };
|
|
37
|
+
}
|
|
38
|
+
function injectReleaseNotesIntoReadme(readmePath, changelogJsonPath, tag, sectionOrder) {
|
|
39
|
+
const originalReadme = readFileSync(readmePath, "utf8");
|
|
40
|
+
const rendered = renderInjectedReadme(originalReadme, changelogJsonPath, tag, sectionOrder);
|
|
41
|
+
if (rendered === void 0) {
|
|
42
|
+
return void 0;
|
|
43
|
+
}
|
|
44
|
+
writeFileSync(readmePath, rendered.injectedReadme, "utf8");
|
|
33
45
|
return originalReadme;
|
|
34
46
|
}
|
|
35
47
|
function resolveReadmePath(workspacePath) {
|
|
@@ -38,5 +50,6 @@ function resolveReadmePath(workspacePath) {
|
|
|
38
50
|
}
|
|
39
51
|
export {
|
|
40
52
|
injectReleaseNotesIntoReadme,
|
|
53
|
+
renderInjectedReadme,
|
|
41
54
|
resolveReadmePath
|
|
42
55
|
};
|
package/dist/esm/loadConfig.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import type { MonorepoReleaseConfig, ReleaseConfig, ReleaseKitConfig } from './types.ts';
|
|
1
|
+
import type { MonorepoReleaseConfig, ReleaseConfig, ReleaseKitConfig, WorkTypeConfig } from './types.ts';
|
|
2
2
|
export declare const CONFIG_FILE_PATH = ".config/release-kit.config.ts";
|
|
3
3
|
export declare function loadConfig(): Promise<unknown>;
|
|
4
4
|
export declare function mergeMonorepoConfig(discoveredPaths: string[], userConfig: ReleaseKitConfig | undefined): MonorepoReleaseConfig;
|
|
5
5
|
export declare function mergeSinglePackageConfig(userConfig: ReleaseKitConfig | undefined): ReleaseConfig;
|
|
6
|
+
export declare function resolveWorkTypes(userWorkTypes?: Record<string, WorkTypeConfig>): Record<string, WorkTypeConfig>;
|
package/dist/esm/loadConfig.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { existsSync } from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
import { component } from "./component.js";
|
|
4
3
|
import {
|
|
5
4
|
DEFAULT_CHANGELOG_JSON_CONFIG,
|
|
6
5
|
DEFAULT_RELEASE_NOTES_CONFIG,
|
|
7
6
|
DEFAULT_VERSION_PATTERNS,
|
|
8
7
|
DEFAULT_WORK_TYPES
|
|
9
8
|
} from "./defaults.js";
|
|
9
|
+
import { deriveWorkspaceConfig } from "./deriveWorkspaceConfig.js";
|
|
10
10
|
import { isRecord } from "./typeGuards.js";
|
|
11
11
|
const CONFIG_FILE_PATH = ".config/release-kit.config.ts";
|
|
12
12
|
async function loadConfig() {
|
|
@@ -29,20 +29,31 @@ async function loadConfig() {
|
|
|
29
29
|
return resolved;
|
|
30
30
|
}
|
|
31
31
|
function mergeMonorepoConfig(discoveredPaths, userConfig) {
|
|
32
|
-
let
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
32
|
+
let workspaces = discoveredPaths.map((workspacePath) => deriveWorkspaceConfig(workspacePath));
|
|
33
|
+
assertUniqueTagPrefixes(workspaces);
|
|
34
|
+
if (userConfig?.workspaces !== void 0) {
|
|
35
|
+
const overrides = new Map(userConfig.workspaces.map((w) => [w.dir, w]));
|
|
36
|
+
workspaces = workspaces.filter((w) => {
|
|
37
|
+
const override = overrides.get(w.dir);
|
|
37
38
|
return override?.shouldExclude !== true;
|
|
39
|
+
}).map((w) => {
|
|
40
|
+
const override = overrides.get(w.dir);
|
|
41
|
+
if (override?.legacyIdentities === void 0) {
|
|
42
|
+
return w;
|
|
43
|
+
}
|
|
44
|
+
assertLegacyIdentityDoesNotMatchCurrent(w.dir, w.name, w.tagPrefix, override.legacyIdentities);
|
|
45
|
+
return { ...w, legacyIdentities: override.legacyIdentities.map((identity) => ({ ...identity })) };
|
|
38
46
|
});
|
|
39
47
|
}
|
|
40
|
-
|
|
48
|
+
if (userConfig?.retiredPackages !== void 0) {
|
|
49
|
+
assertRetiredPackagesDoNotCollideWithActive(workspaces, userConfig.retiredPackages);
|
|
50
|
+
}
|
|
51
|
+
const workTypes = resolveWorkTypes(userConfig?.workTypes);
|
|
41
52
|
const versionPatterns = userConfig?.versionPatterns === void 0 ? { ...DEFAULT_VERSION_PATTERNS } : { ...userConfig.versionPatterns };
|
|
42
53
|
const changelogJson = mergeChangelogJsonConfig(userConfig?.changelogJson);
|
|
43
54
|
const releaseNotes = mergeReleaseNotesConfig(userConfig?.releaseNotes);
|
|
44
55
|
const result = {
|
|
45
|
-
|
|
56
|
+
workspaces,
|
|
46
57
|
workTypes,
|
|
47
58
|
versionPatterns,
|
|
48
59
|
changelogJson,
|
|
@@ -63,7 +74,7 @@ function mergeMonorepoConfig(discoveredPaths, userConfig) {
|
|
|
63
74
|
return result;
|
|
64
75
|
}
|
|
65
76
|
function mergeSinglePackageConfig(userConfig) {
|
|
66
|
-
const workTypes = userConfig?.workTypes
|
|
77
|
+
const workTypes = resolveWorkTypes(userConfig?.workTypes);
|
|
67
78
|
const versionPatterns = userConfig?.versionPatterns === void 0 ? { ...DEFAULT_VERSION_PATTERNS } : { ...userConfig.versionPatterns };
|
|
68
79
|
const changelogJson = mergeChangelogJsonConfig(userConfig?.changelogJson);
|
|
69
80
|
const releaseNotes = mergeReleaseNotesConfig(userConfig?.releaseNotes);
|
|
@@ -90,6 +101,9 @@ function mergeSinglePackageConfig(userConfig) {
|
|
|
90
101
|
}
|
|
91
102
|
return result;
|
|
92
103
|
}
|
|
104
|
+
function resolveWorkTypes(userWorkTypes) {
|
|
105
|
+
return userWorkTypes === void 0 ? { ...DEFAULT_WORK_TYPES } : { ...DEFAULT_WORK_TYPES, ...userWorkTypes };
|
|
106
|
+
}
|
|
93
107
|
function mergeChangelogJsonConfig(partial) {
|
|
94
108
|
if (partial === void 0) {
|
|
95
109
|
return { ...DEFAULT_CHANGELOG_JSON_CONFIG };
|
|
@@ -100,18 +114,57 @@ function mergeChangelogJsonConfig(partial) {
|
|
|
100
114
|
devOnlySections: partial.devOnlySections ?? [...DEFAULT_CHANGELOG_JSON_CONFIG.devOnlySections]
|
|
101
115
|
};
|
|
102
116
|
}
|
|
117
|
+
function assertLegacyIdentityDoesNotMatchCurrent(dir, currentName, currentTagPrefix, legacyIdentities) {
|
|
118
|
+
for (const identity of legacyIdentities) {
|
|
119
|
+
if (identity.name === currentName && identity.tagPrefix === currentTagPrefix) {
|
|
120
|
+
throw new Error(
|
|
121
|
+
`Workspace '${dir}': legacyIdentities must not match the current identity (name='${currentName}', tagPrefix='${currentTagPrefix}'). The current identity is always searched; listing it again is a no-op.`
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
function assertRetiredPackagesDoNotCollideWithActive(workspaces, retiredPackages) {
|
|
127
|
+
const workspaceByDerivedPrefix = /* @__PURE__ */ new Map();
|
|
128
|
+
for (const workspace of workspaces) {
|
|
129
|
+
workspaceByDerivedPrefix.set(workspace.tagPrefix, workspace);
|
|
130
|
+
}
|
|
131
|
+
for (const retired of retiredPackages) {
|
|
132
|
+
const active = workspaceByDerivedPrefix.get(retired.tagPrefix);
|
|
133
|
+
if (active !== void 0) {
|
|
134
|
+
throw new Error(
|
|
135
|
+
`retiredPackages: tagPrefix '${retired.tagPrefix}' collides with active workspace '${active.dir}' (derived prefix '${active.tagPrefix}'). A retired package's tagPrefix cannot belong to an active workspace.`
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
function assertUniqueTagPrefixes(workspaces) {
|
|
141
|
+
const pathsByPrefix = /* @__PURE__ */ new Map();
|
|
142
|
+
for (const workspace of workspaces) {
|
|
143
|
+
const existing = pathsByPrefix.get(workspace.tagPrefix);
|
|
144
|
+
if (existing === void 0) {
|
|
145
|
+
pathsByPrefix.set(workspace.tagPrefix, [workspace.workspacePath]);
|
|
146
|
+
} else {
|
|
147
|
+
existing.push(workspace.workspacePath);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
for (const [prefix, paths] of pathsByPrefix) {
|
|
151
|
+
if (paths.length > 1) {
|
|
152
|
+
throw new Error(`Duplicate tag prefix '${prefix}' for workspaces: ${paths.join(", ")}`);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
103
156
|
function mergeReleaseNotesConfig(partial) {
|
|
104
157
|
if (partial === void 0) {
|
|
105
158
|
return { ...DEFAULT_RELEASE_NOTES_CONFIG };
|
|
106
159
|
}
|
|
107
160
|
return {
|
|
108
|
-
shouldInjectIntoReadme: partial.shouldInjectIntoReadme ?? DEFAULT_RELEASE_NOTES_CONFIG.shouldInjectIntoReadme
|
|
109
|
-
shouldCreateGithubRelease: partial.shouldCreateGithubRelease ?? DEFAULT_RELEASE_NOTES_CONFIG.shouldCreateGithubRelease
|
|
161
|
+
shouldInjectIntoReadme: partial.shouldInjectIntoReadme ?? DEFAULT_RELEASE_NOTES_CONFIG.shouldInjectIntoReadme
|
|
110
162
|
};
|
|
111
163
|
}
|
|
112
164
|
export {
|
|
113
165
|
CONFIG_FILE_PATH,
|
|
114
166
|
loadConfig,
|
|
115
167
|
mergeMonorepoConfig,
|
|
116
|
-
mergeSinglePackageConfig
|
|
168
|
+
mergeSinglePackageConfig,
|
|
169
|
+
resolveWorkTypes
|
|
117
170
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function parseRequestedTags(flagValue: string | undefined): string[] | undefined;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { WriteResult } from '@williamthorsen/
|
|
1
|
+
import type { WriteResult } from '@williamthorsen/nmr-core';
|
|
2
2
|
import type { ReleaseType } from './types.ts';
|
|
3
3
|
export declare const RELEASE_TAGS_FILE = "tmp/.release-tags";
|
|
4
4
|
export declare const RELEASE_SUMMARY_FILE = "tmp/.release-summary";
|
|
@@ -8,6 +8,8 @@ export declare function parseArgs(argv: string[]): {
|
|
|
8
8
|
noGitChecks: boolean;
|
|
9
9
|
bumpOverride: ReleaseType | undefined;
|
|
10
10
|
only: string[] | undefined;
|
|
11
|
+
setVersion: string | undefined;
|
|
12
|
+
withReleaseNotes: boolean;
|
|
11
13
|
};
|
|
12
14
|
export declare function writeReleaseTags(tags: string[], dryRun: boolean): WriteResult | undefined;
|
|
13
15
|
export declare function prepareCommand(argv: string[]): Promise<void>;
|