@varlock/bumpy 1.2.1 → 1.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/README.md +52 -38
- package/dist/{add-DF6bawDT.mjs → add-ET1tcdQm.mjs} +8 -8
- package/dist/apply-release-plan-BvZ32LAm.mjs +57 -0
- package/dist/{bump-file-C3S_bzSf.mjs → bump-file-CoaSxqne.mjs} +6 -9
- package/dist/changelog-BIkNBJ15.mjs +110 -0
- package/dist/{changelog-github-DZSHX3Tb.mjs → changelog-github-BAtgxeXv.mjs} +30 -14
- package/dist/{check-BJL-YDWz.mjs → check-C80o_gJK.mjs} +7 -7
- package/dist/{ci-C88ecvIP.mjs → ci-WJ8kTjeN.mjs} +76 -56
- package/dist/{ci-setup-CARJFhcE.mjs → ci-setup-D1NCzbNH.mjs} +3 -3
- package/dist/cli.mjs +17 -19
- package/dist/{config-D7Umr-fT.mjs → config-D13G4-R8.mjs} +2 -80
- package/dist/{generate-D93b3NAD.mjs → generate-BJq--oCu.mjs} +6 -6
- package/dist/{git-H9S9z6g-.mjs → git-D0__HP86.mjs} +1 -1
- package/dist/index.d.mts +4 -2
- package/dist/index.mjs +10 -8
- package/dist/{init-DJhMaceS.mjs → init-DND7zRGD.mjs} +3 -3
- package/dist/{publish-DGSV607z.mjs → publish-CfZCAlPx.mjs} +49 -13
- package/dist/{publish-pipeline-DiwZZ5AF.mjs → publish-pipeline-BvLIu7WF.mjs} +4 -4
- package/dist/{release-plan-CNOuSI-d.mjs → release-plan-RBjKmavL.mjs} +3 -2
- package/dist/{status-S2ztf_8E.mjs → status-pMfPtt1p.mjs} +7 -7
- package/dist/types-BX4pfmKh.mjs +80 -0
- package/dist/{version-BXrP4TIO.mjs → version-DLU0h1cq.mjs} +9 -9
- package/dist/{workspace-BHsAPUmC.mjs → workspace-BKOAMeki.mjs} +2 -2
- package/package.json +1 -1
- package/dist/apply-release-plan-B1Wwx3HG.mjs +0 -146
- /package/dist/{ai-STKnq09z.mjs → ai-C66IfTzs.mjs} +0 -0
- /package/dist/{clack-C6bVkGxf.mjs → clack-CJT1JFFa.mjs} +0 -0
- /package/dist/{commit-message-BwsowSds.mjs → commit-message-DOIfDxfj.mjs} +0 -0
- /package/dist/{dep-graph-DiLeAhl9.mjs → dep-graph-E-9-eQ2J.mjs} +0 -0
- /package/dist/{names-C-TuOPbd.mjs → names-CBy7d8K_.mjs} +0 -0
- /package/dist/{package-manager-ByJ0wKYh.mjs → package-manager-CClZtIHP.mjs} +0 -0
- /package/dist/{picomatch-DMmqYjgq.mjs → picomatch-TGJi--_I.mjs} +0 -0
- /package/dist/{semver-BJzWIuRz.mjs → semver-DfQyVLM_.mjs} +0 -0
- /package/dist/{shell-CY7OD48z.mjs → shell-u3bYGxNy.mjs} +0 -0
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { n as log, t as colorize } from "./logger-C2dEe5Su.mjs";
|
|
2
|
-
import { a as loadConfig } from "./config-
|
|
3
|
-
import { n as detectWorkspaces } from "./package-manager-
|
|
4
|
-
import { n as discoverWorkspace } from "./workspace-
|
|
5
|
-
import { t as DependencyGraph } from "./dep-graph-
|
|
6
|
-
import { r as runArgsAsync, s as tryRunArgs } from "./shell-
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
2
|
+
import { a as loadConfig } from "./config-D13G4-R8.mjs";
|
|
3
|
+
import { n as detectWorkspaces } from "./package-manager-CClZtIHP.mjs";
|
|
4
|
+
import { n as discoverWorkspace } from "./workspace-BKOAMeki.mjs";
|
|
5
|
+
import { t as DependencyGraph } from "./dep-graph-E-9-eQ2J.mjs";
|
|
6
|
+
import { r as runArgsAsync, s as tryRunArgs } from "./shell-u3bYGxNy.mjs";
|
|
7
|
+
import { i as loadFormatter, n as generateChangelogEntry } from "./changelog-BIkNBJ15.mjs";
|
|
8
|
+
import { c as pushWithTags, o as hasUncommittedChanges, s as listTags } from "./git-D0__HP86.mjs";
|
|
9
|
+
import { t as publishPackages } from "./publish-pipeline-BvLIu7WF.mjs";
|
|
9
10
|
//#region src/core/github-release.ts
|
|
10
11
|
/** Get the current HEAD commit SHA */
|
|
11
12
|
function getHeadSha(rootDir) {
|
|
@@ -24,7 +25,7 @@ async function createIndividualReleases(releases, bumpFiles, rootDir, opts = {})
|
|
|
24
25
|
const headSha = getHeadSha(rootDir);
|
|
25
26
|
for (const release of releases) {
|
|
26
27
|
const tag = `${release.name}@${release.newVersion}`;
|
|
27
|
-
const body = buildReleaseBody(release, bumpFiles);
|
|
28
|
+
const body = opts.formatter ? await generateReleaseBody(release, bumpFiles, opts.formatter) : buildReleaseBody(release, bumpFiles);
|
|
28
29
|
const title = `${release.name} v${release.newVersion}`;
|
|
29
30
|
if (opts.dryRun) {
|
|
30
31
|
log.dim(` Would create GitHub release: ${title}`);
|
|
@@ -58,7 +59,7 @@ async function createAggregateRelease(releases, bumpFiles, rootDir, opts = {}) {
|
|
|
58
59
|
if (releases.length === 0) return;
|
|
59
60
|
const date = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
60
61
|
const { tag, title } = resolveAggregateTagAndTitle(date, listTags(`release-${date}*`, { cwd: rootDir }), opts.title);
|
|
61
|
-
const body = buildAggregateBody(releases, bumpFiles);
|
|
62
|
+
const body = opts.formatter ? await generateAggregateBody(releases, bumpFiles, opts.formatter) : buildAggregateBody(releases, bumpFiles);
|
|
62
63
|
if (opts.dryRun) {
|
|
63
64
|
log.dim(` Would create aggregate GitHub release: ${title}`);
|
|
64
65
|
log.dim(` Tag: ${tag}`);
|
|
@@ -88,6 +89,36 @@ async function createAggregateRelease(releases, bumpFiles, rootDir, opts = {}) {
|
|
|
88
89
|
log.warn(`Failed to create aggregate GitHub release: ${err instanceof Error ? err.message : err}`);
|
|
89
90
|
}
|
|
90
91
|
}
|
|
92
|
+
/** Generate a release body for a single package using the changelog formatter */
|
|
93
|
+
async function generateReleaseBody(release, bumpFiles, formatter) {
|
|
94
|
+
return stripVersionHeading(await generateChangelogEntry(release, bumpFiles, formatter, void 0, "github-release")).trim() || "No changelog entries.";
|
|
95
|
+
}
|
|
96
|
+
/** Generate an aggregate release body using the changelog formatter */
|
|
97
|
+
async function generateAggregateBody(releases, bumpFiles, formatter) {
|
|
98
|
+
const lines = [];
|
|
99
|
+
const groups = [
|
|
100
|
+
["Major Changes", releases.filter((r) => r.type === "major")],
|
|
101
|
+
["Minor Changes", releases.filter((r) => r.type === "minor")],
|
|
102
|
+
["Patch Changes", releases.filter((r) => r.type === "patch")]
|
|
103
|
+
];
|
|
104
|
+
for (const [heading, group] of groups) {
|
|
105
|
+
if (group.length === 0) continue;
|
|
106
|
+
lines.push(`## ${heading}\n`);
|
|
107
|
+
for (const release of group) {
|
|
108
|
+
lines.push(`### ${release.name} v${release.newVersion}\n`);
|
|
109
|
+
const body = stripVersionHeading(await generateChangelogEntry(release, bumpFiles, formatter, void 0, "github-release")).trim();
|
|
110
|
+
if (body) lines.push(body);
|
|
111
|
+
else if (release.isDependencyBump) lines.push("- Updated dependencies");
|
|
112
|
+
else if (release.isCascadeBump) lines.push("- Version bump via cascade rule");
|
|
113
|
+
lines.push("");
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return lines.join("\n").trim() || "No changelog entries.";
|
|
117
|
+
}
|
|
118
|
+
/** Strip the leading ## version heading and date sub-heading from a changelog entry */
|
|
119
|
+
function stripVersionHeading(entry) {
|
|
120
|
+
return entry.replace(/^## .+\n/, "").replace(/^<sub>.+<\/sub>\n/, "").replace(/^_.+_\n/, "");
|
|
121
|
+
}
|
|
91
122
|
function buildReleaseBody(release, bumpFiles) {
|
|
92
123
|
const lines = [];
|
|
93
124
|
const relevant = bumpFiles.filter((bf) => release.bumpFiles.includes(bf.id));
|
|
@@ -148,7 +179,7 @@ async function publishCommand(rootDir, opts) {
|
|
|
148
179
|
}
|
|
149
180
|
let toPublish = await findUnpublishedPackages(packages, config);
|
|
150
181
|
if (opts.filter) {
|
|
151
|
-
const { matchGlob } = await import("./config-
|
|
182
|
+
const { matchGlob } = await import("./config-D13G4-R8.mjs").then((n) => n.t);
|
|
152
183
|
const patterns = opts.filter.split(",").map((p) => p.trim());
|
|
153
184
|
toPublish = toPublish.filter((r) => patterns.some((p) => matchGlob(r.name, p)));
|
|
154
185
|
}
|
|
@@ -187,11 +218,16 @@ async function publishCommand(rootDir, opts) {
|
|
|
187
218
|
const aggConfig = config.aggregateRelease;
|
|
188
219
|
const isAggregate = aggConfig === true || typeof aggConfig === "object" && aggConfig.enabled;
|
|
189
220
|
const aggTitle = typeof aggConfig === "object" ? aggConfig.title : void 0;
|
|
221
|
+
const formatter = config.changelog !== false ? await loadFormatter(config.changelog, rootDir) : void 0;
|
|
190
222
|
if (isAggregate) await createAggregateRelease(publishedReleases, releasePlan.bumpFiles, rootDir, {
|
|
191
223
|
dryRun: opts.dryRun,
|
|
192
|
-
title: aggTitle
|
|
224
|
+
title: aggTitle,
|
|
225
|
+
formatter
|
|
226
|
+
});
|
|
227
|
+
else await createIndividualReleases(publishedReleases, releasePlan.bumpFiles, rootDir, {
|
|
228
|
+
dryRun: opts.dryRun,
|
|
229
|
+
formatter
|
|
193
230
|
});
|
|
194
|
-
else await createIndividualReleases(publishedReleases, releasePlan.bumpFiles, rootDir, { dryRun: opts.dryRun });
|
|
195
231
|
}
|
|
196
232
|
}
|
|
197
233
|
/**
|
|
@@ -220,7 +256,7 @@ async function findUnpublishedPackages(packages, _config) {
|
|
|
220
256
|
return unpublished;
|
|
221
257
|
}
|
|
222
258
|
async function checkIfPublished(name, version, pkgConfig) {
|
|
223
|
-
const { runAsync, runArgsAsync, tryRunArgs } = await import("./shell-
|
|
259
|
+
const { runAsync, runArgsAsync, tryRunArgs } = await import("./shell-u3bYGxNy.mjs").then((n) => n.a);
|
|
224
260
|
if (pkgConfig?.checkPublished) try {
|
|
225
261
|
return (await runAsync(pkgConfig.checkPublished)).trim() === version;
|
|
226
262
|
} catch {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { n as log, t as colorize } from "./logger-C2dEe5Su.mjs";
|
|
2
2
|
import { a as readJson, u as updateJsonNestedField } from "./fs-DnDogVn-.mjs";
|
|
3
|
-
import { r as resolveCatalogDep } from "./package-manager-
|
|
4
|
-
import { i as runAsync, o as sq, r as runArgsAsync, s as tryRunArgs } from "./shell-
|
|
5
|
-
import { r as stripProtocol } from "./semver-
|
|
6
|
-
import { l as tagExists, t as createTag } from "./git-
|
|
3
|
+
import { r as resolveCatalogDep } from "./package-manager-CClZtIHP.mjs";
|
|
4
|
+
import { i as runAsync, o as sq, r as runArgsAsync, s as tryRunArgs } from "./shell-u3bYGxNy.mjs";
|
|
5
|
+
import { r as stripProtocol } from "./semver-DfQyVLM_.mjs";
|
|
6
|
+
import { l as tagExists, t as createTag } from "./git-D0__HP86.mjs";
|
|
7
7
|
import { resolve } from "node:path";
|
|
8
8
|
import { unlink } from "node:fs/promises";
|
|
9
9
|
import { appendFileSync, existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { c as maxBump, n as DEFAULT_BUMP_RULES, o as bumpLevel, s as hasCascade } from "./types-BX4pfmKh.mjs";
|
|
2
|
+
import { s as matchGlob } from "./config-D13G4-R8.mjs";
|
|
3
|
+
import { n as satisfies, t as bumpVersion } from "./semver-DfQyVLM_.mjs";
|
|
3
4
|
//#region src/core/release-plan.ts
|
|
4
5
|
/**
|
|
5
6
|
* Build a release plan from pending bump files, the dependency graph, and config.
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { n as log, t as colorize } from "./logger-C2dEe5Su.mjs";
|
|
2
|
-
import { a as loadConfig } from "./config-
|
|
3
|
-
import { t as discoverPackages } from "./workspace-
|
|
4
|
-
import { t as DependencyGraph } from "./dep-graph-
|
|
5
|
-
import { r as readBumpFiles, t as filterBranchBumpFiles } from "./bump-file-
|
|
6
|
-
import { t as assembleReleasePlan } from "./release-plan-
|
|
7
|
-
import { i as getCurrentBranch, r as getChangedFiles } from "./git-
|
|
2
|
+
import { a as loadConfig } from "./config-D13G4-R8.mjs";
|
|
3
|
+
import { t as discoverPackages } from "./workspace-BKOAMeki.mjs";
|
|
4
|
+
import { t as DependencyGraph } from "./dep-graph-E-9-eQ2J.mjs";
|
|
5
|
+
import { r as readBumpFiles, t as filterBranchBumpFiles } from "./bump-file-CoaSxqne.mjs";
|
|
6
|
+
import { t as assembleReleasePlan } from "./release-plan-RBjKmavL.mjs";
|
|
7
|
+
import { i as getCurrentBranch, r as getChangedFiles } from "./git-D0__HP86.mjs";
|
|
8
8
|
//#region src/commands/status.ts
|
|
9
9
|
async function statusCommand(rootDir, opts) {
|
|
10
10
|
const config = await loadConfig(rootDir);
|
|
@@ -31,7 +31,7 @@ async function statusCommand(rootDir, opts) {
|
|
|
31
31
|
releases = releases.filter((r) => types.includes(r.type));
|
|
32
32
|
}
|
|
33
33
|
if (opts.filter) {
|
|
34
|
-
const { matchGlob } = await import("./config-
|
|
34
|
+
const { matchGlob } = await import("./config-D13G4-R8.mjs").then((n) => n.t);
|
|
35
35
|
const patterns = opts.filter.split(",").map((p) => p.trim());
|
|
36
36
|
releases = releases.filter((r) => patterns.some((p) => matchGlob(r.name, p)));
|
|
37
37
|
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
//#region src/types.ts
|
|
2
|
+
const BUMP_LEVELS = {
|
|
3
|
+
patch: 0,
|
|
4
|
+
minor: 1,
|
|
5
|
+
major: 2
|
|
6
|
+
};
|
|
7
|
+
function bumpLevel(type) {
|
|
8
|
+
return BUMP_LEVELS[type];
|
|
9
|
+
}
|
|
10
|
+
function maxBump(a, b) {
|
|
11
|
+
if (!a) return b;
|
|
12
|
+
return bumpLevel(a) >= bumpLevel(b) ? a : b;
|
|
13
|
+
}
|
|
14
|
+
const DEFAULT_BUMP_RULES = {
|
|
15
|
+
dependencies: {
|
|
16
|
+
trigger: "patch",
|
|
17
|
+
bumpAs: "patch"
|
|
18
|
+
},
|
|
19
|
+
peerDependencies: {
|
|
20
|
+
trigger: "major",
|
|
21
|
+
bumpAs: "match"
|
|
22
|
+
},
|
|
23
|
+
devDependencies: false,
|
|
24
|
+
optionalDependencies: {
|
|
25
|
+
trigger: "minor",
|
|
26
|
+
bumpAs: "patch"
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
const DEP_TYPES = [
|
|
30
|
+
"dependencies",
|
|
31
|
+
"devDependencies",
|
|
32
|
+
"peerDependencies",
|
|
33
|
+
"optionalDependencies"
|
|
34
|
+
];
|
|
35
|
+
const DEFAULT_PUBLISH_CONFIG = {
|
|
36
|
+
packManager: "auto",
|
|
37
|
+
publishManager: "npm",
|
|
38
|
+
publishArgs: [],
|
|
39
|
+
protocolResolution: "pack"
|
|
40
|
+
};
|
|
41
|
+
const DEFAULT_CONFIG = {
|
|
42
|
+
baseBranch: "main",
|
|
43
|
+
access: "public",
|
|
44
|
+
versionCommitMessage: void 0,
|
|
45
|
+
changedFilePatterns: ["**"],
|
|
46
|
+
changelog: "default",
|
|
47
|
+
fixed: [],
|
|
48
|
+
linked: [],
|
|
49
|
+
ignore: [],
|
|
50
|
+
include: [],
|
|
51
|
+
updateInternalDependencies: "out-of-range",
|
|
52
|
+
dependencyBumpRules: {},
|
|
53
|
+
privatePackages: {
|
|
54
|
+
version: false,
|
|
55
|
+
tag: false
|
|
56
|
+
},
|
|
57
|
+
allowCustomCommands: false,
|
|
58
|
+
packages: {},
|
|
59
|
+
publish: { ...DEFAULT_PUBLISH_CONFIG },
|
|
60
|
+
aggregateRelease: false,
|
|
61
|
+
gitUser: {
|
|
62
|
+
name: "bumpy-bot",
|
|
63
|
+
email: "276066384+bumpy-bot@users.noreply.github.com"
|
|
64
|
+
},
|
|
65
|
+
versionPr: {
|
|
66
|
+
title: "🐸 Versioned release",
|
|
67
|
+
branch: "bumpy/version-packages",
|
|
68
|
+
preamble: [
|
|
69
|
+
`<a href="https://bumpy.varlock.dev"><img src="https://raw.githubusercontent.com/dmno-dev/bumpy/main/images/frog-clipboard.png" alt="bumpy-frog" width="60" align="left" style="image-rendering: pixelated;" title="Hi! I'm bumpy!" /></a>`,
|
|
70
|
+
"",
|
|
71
|
+
`This PR was created and will be kept in sync by [bumpy](https://bumpy.varlock.dev) based on your bump files (in \`.bumpy/\`). Merge it when you are ready to release the packages listed below:`,
|
|
72
|
+
"<br clear=\"left\" />"
|
|
73
|
+
].join("\n")
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
function hasCascade(r) {
|
|
77
|
+
return "cascade" in r && Object.keys(r.cascade).length > 0;
|
|
78
|
+
}
|
|
79
|
+
//#endregion
|
|
80
|
+
export { DEP_TYPES as a, maxBump as c, DEFAULT_PUBLISH_CONFIG as i, DEFAULT_BUMP_RULES as n, bumpLevel as o, DEFAULT_CONFIG as r, hasCascade as s, BUMP_LEVELS as t };
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { n as log, t as colorize } from "./logger-C2dEe5Su.mjs";
|
|
2
|
-
import { a as loadConfig } from "./config-
|
|
3
|
-
import { n as detectWorkspaces } from "./package-manager-
|
|
4
|
-
import { t as discoverPackages } from "./workspace-
|
|
5
|
-
import { t as DependencyGraph } from "./dep-graph-
|
|
6
|
-
import { n as runArgs, s as tryRunArgs } from "./shell-
|
|
7
|
-
import { r as readBumpFiles } from "./bump-file-
|
|
8
|
-
import { t as assembleReleasePlan } from "./release-plan-
|
|
9
|
-
import { t as applyReleasePlan } from "./apply-release-plan-
|
|
10
|
-
import { t as resolveCommitMessage } from "./commit-message-
|
|
2
|
+
import { a as loadConfig } from "./config-D13G4-R8.mjs";
|
|
3
|
+
import { n as detectWorkspaces } from "./package-manager-CClZtIHP.mjs";
|
|
4
|
+
import { t as discoverPackages } from "./workspace-BKOAMeki.mjs";
|
|
5
|
+
import { t as DependencyGraph } from "./dep-graph-E-9-eQ2J.mjs";
|
|
6
|
+
import { n as runArgs, s as tryRunArgs } from "./shell-u3bYGxNy.mjs";
|
|
7
|
+
import { r as readBumpFiles } from "./bump-file-CoaSxqne.mjs";
|
|
8
|
+
import { t as assembleReleasePlan } from "./release-plan-RBjKmavL.mjs";
|
|
9
|
+
import { t as applyReleasePlan } from "./apply-release-plan-BvZ32LAm.mjs";
|
|
10
|
+
import { t as resolveCommitMessage } from "./commit-message-DOIfDxfj.mjs";
|
|
11
11
|
//#region src/commands/version.ts
|
|
12
12
|
async function versionCommand(rootDir, opts = {}) {
|
|
13
13
|
const config = await loadConfig(rootDir);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { a as readJson, n as exists } from "./fs-DnDogVn-.mjs";
|
|
2
|
-
import { i as isPackageManaged, o as loadPackageConfig } from "./config-
|
|
3
|
-
import { n as detectWorkspaces } from "./package-manager-
|
|
2
|
+
import { i as isPackageManaged, o as loadPackageConfig } from "./config-D13G4-R8.mjs";
|
|
3
|
+
import { n as detectWorkspaces } from "./package-manager-CClZtIHP.mjs";
|
|
4
4
|
import { relative, resolve } from "node:path";
|
|
5
5
|
import { readdir, stat } from "node:fs/promises";
|
|
6
6
|
//#region src/core/workspace.ts
|
package/package.json
CHANGED
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
import { n as log } from "./logger-C2dEe5Su.mjs";
|
|
2
|
-
import { a as readJson, c as removeFile, f as writeText, i as listFiles, l as updateJsonFields, n as exists, s as readText, u as updateJsonNestedField } from "./fs-DnDogVn-.mjs";
|
|
3
|
-
import { r as getBumpyDir } from "./config-D7Umr-fT.mjs";
|
|
4
|
-
import { relative, resolve } from "node:path";
|
|
5
|
-
import { realpathSync } from "node:fs";
|
|
6
|
-
//#region src/core/changelog.ts
|
|
7
|
-
/** Default formatter — version heading, date, bullet points */
|
|
8
|
-
const defaultFormatter = (ctx) => {
|
|
9
|
-
const { release, bumpFiles, date } = ctx;
|
|
10
|
-
const lines = [];
|
|
11
|
-
lines.push(`## ${release.newVersion}`);
|
|
12
|
-
lines.push("");
|
|
13
|
-
lines.push(`_${date}_`);
|
|
14
|
-
lines.push("");
|
|
15
|
-
const relevantBumpFiles = bumpFiles.filter((bf) => release.bumpFiles.includes(bf.id));
|
|
16
|
-
if (relevantBumpFiles.length > 0) {
|
|
17
|
-
for (const bf of relevantBumpFiles) if (bf.summary) {
|
|
18
|
-
const summaryLines = bf.summary.split("\n");
|
|
19
|
-
lines.push(`- ${summaryLines[0]}`);
|
|
20
|
-
for (let i = 1; i < summaryLines.length; i++) if (summaryLines[i].trim()) lines.push(` ${summaryLines[i]}`);
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
if (release.isDependencyBump && relevantBumpFiles.length === 0) lines.push("- Updated dependencies");
|
|
24
|
-
if (release.isCascadeBump && !release.isDependencyBump && relevantBumpFiles.length === 0) lines.push("- Version bump via cascade rule");
|
|
25
|
-
lines.push("");
|
|
26
|
-
return lines.join("\n");
|
|
27
|
-
};
|
|
28
|
-
const BUILTIN_FORMATTERS = {
|
|
29
|
-
default: defaultFormatter,
|
|
30
|
-
github: async () => {
|
|
31
|
-
const { createGithubFormatter } = await import("./changelog-github-DZSHX3Tb.mjs");
|
|
32
|
-
return createGithubFormatter();
|
|
33
|
-
}
|
|
34
|
-
};
|
|
35
|
-
/**
|
|
36
|
-
* Load a changelog formatter from config.
|
|
37
|
-
* Supports: "default", "./path/to/formatter.ts", or a module name.
|
|
38
|
-
*/
|
|
39
|
-
async function loadFormatter(changelog, rootDir) {
|
|
40
|
-
const [name, options] = Array.isArray(changelog) ? changelog : [changelog, {}];
|
|
41
|
-
if (name === "github") {
|
|
42
|
-
const { createGithubFormatter } = await import("./changelog-github-DZSHX3Tb.mjs");
|
|
43
|
-
return createGithubFormatter(options);
|
|
44
|
-
}
|
|
45
|
-
if (typeof name === "string" && BUILTIN_FORMATTERS[name]) {
|
|
46
|
-
const builtin = BUILTIN_FORMATTERS[name];
|
|
47
|
-
if (typeof builtin === "function" && builtin.length === 0) return builtin();
|
|
48
|
-
return builtin;
|
|
49
|
-
}
|
|
50
|
-
if (typeof name === "string") try {
|
|
51
|
-
let modulePath;
|
|
52
|
-
if (name.startsWith(".")) {
|
|
53
|
-
modulePath = resolve(rootDir, name);
|
|
54
|
-
try {
|
|
55
|
-
modulePath = realpathSync(modulePath);
|
|
56
|
-
} catch {}
|
|
57
|
-
const rel = relative(realpathSync(rootDir), modulePath);
|
|
58
|
-
if (rel.startsWith("..") || resolve("/", rel) === resolve("/")) throw new Error(`Changelog formatter path "${name}" resolves outside the project root`);
|
|
59
|
-
} else modulePath = name;
|
|
60
|
-
const mod = await import(modulePath);
|
|
61
|
-
const exported = mod.default || mod.changelogFormatter;
|
|
62
|
-
if (typeof exported === "function") {
|
|
63
|
-
const result = exported(options);
|
|
64
|
-
if (typeof result === "function") return result;
|
|
65
|
-
return exported;
|
|
66
|
-
}
|
|
67
|
-
throw new Error(`Changelog module "${name}" does not export a function`);
|
|
68
|
-
} catch (err) {
|
|
69
|
-
log.warn(`Failed to load changelog formatter "${name}": ${err instanceof Error ? err.message : err}`);
|
|
70
|
-
log.warn("Falling back to default formatter");
|
|
71
|
-
return defaultFormatter;
|
|
72
|
-
}
|
|
73
|
-
return defaultFormatter;
|
|
74
|
-
}
|
|
75
|
-
/** Generate a changelog entry using the configured formatter */
|
|
76
|
-
async function generateChangelogEntry(release, bumpFiles, formatter = defaultFormatter, date = (/* @__PURE__ */ new Date()).toISOString().split("T")[0]) {
|
|
77
|
-
return formatter({
|
|
78
|
-
release,
|
|
79
|
-
bumpFiles,
|
|
80
|
-
date
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
/** Prepend a new entry to an existing CHANGELOG.md content */
|
|
84
|
-
function prependToChangelog(existingContent, newEntry) {
|
|
85
|
-
const headerMatch = existingContent.match(/^# /m);
|
|
86
|
-
if (headerMatch && headerMatch.index !== void 0) {
|
|
87
|
-
const afterTitle = existingContent.indexOf("\n##");
|
|
88
|
-
if (afterTitle !== -1) return existingContent.slice(0, afterTitle + 1) + "\n" + newEntry + existingContent.slice(afterTitle + 1);
|
|
89
|
-
return existingContent.trimEnd() + "\n\n" + newEntry;
|
|
90
|
-
}
|
|
91
|
-
return "# Changelog\n\n" + newEntry;
|
|
92
|
-
}
|
|
93
|
-
//#endregion
|
|
94
|
-
//#region src/core/apply-release-plan.ts
|
|
95
|
-
/** Apply the release plan: bump versions, update changelogs, delete bump files */
|
|
96
|
-
async function applyReleasePlan(releasePlan, packages, rootDir, config) {
|
|
97
|
-
const releaseMap = new Map(releasePlan.releases.map((r) => [r.name, r]));
|
|
98
|
-
const formatter = config.changelog !== false ? await loadFormatter(config.changelog, rootDir) : null;
|
|
99
|
-
for (const release of releasePlan.releases) {
|
|
100
|
-
const pkgJsonPath = resolve(packages.get(release.name).dir, "package.json");
|
|
101
|
-
const pkgJson = await readJson(pkgJsonPath);
|
|
102
|
-
await updateJsonFields(pkgJsonPath, { version: release.newVersion });
|
|
103
|
-
for (const depField of [
|
|
104
|
-
"dependencies",
|
|
105
|
-
"devDependencies",
|
|
106
|
-
"peerDependencies",
|
|
107
|
-
"optionalDependencies"
|
|
108
|
-
]) {
|
|
109
|
-
const deps = pkgJson[depField];
|
|
110
|
-
if (!deps) continue;
|
|
111
|
-
for (const [depName, range] of Object.entries(deps)) {
|
|
112
|
-
const depRelease = releaseMap.get(depName);
|
|
113
|
-
if (!depRelease) continue;
|
|
114
|
-
await updateJsonNestedField(pkgJsonPath, depField, depName, updateRange(range, depRelease.newVersion));
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
if (formatter) for (const release of releasePlan.releases) {
|
|
119
|
-
const changelogPath = resolve(packages.get(release.name).dir, "CHANGELOG.md");
|
|
120
|
-
const entry = await generateChangelogEntry(release, releasePlan.bumpFiles, formatter);
|
|
121
|
-
let existingContent = "";
|
|
122
|
-
if (await exists(changelogPath)) existingContent = await readText(changelogPath);
|
|
123
|
-
await writeText(changelogPath, prependToChangelog(existingContent, entry));
|
|
124
|
-
}
|
|
125
|
-
const bumpyDir = getBumpyDir(rootDir);
|
|
126
|
-
const allBumpFiles = await listFiles(bumpyDir, ".md");
|
|
127
|
-
for (const file of allBumpFiles) {
|
|
128
|
-
if (file === "README.md") continue;
|
|
129
|
-
await removeFile(resolve(bumpyDir, file));
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
/** Update a version range to include a new version, preserving the range prefix */
|
|
133
|
-
function updateRange(range, newVersion) {
|
|
134
|
-
let protocol = "";
|
|
135
|
-
let cleanRange = range;
|
|
136
|
-
const protoMatch = range.match(/^(workspace:|catalog:)/);
|
|
137
|
-
if (protoMatch) {
|
|
138
|
-
protocol = protoMatch[1];
|
|
139
|
-
cleanRange = range.slice(protocol.length);
|
|
140
|
-
}
|
|
141
|
-
const prefix = cleanRange.match(/^(\^|~|>=|>|<=|<|=)?/)?.[1] ?? "^";
|
|
142
|
-
if (cleanRange === "*" || cleanRange === "" || cleanRange === "^" || cleanRange === "~") return range;
|
|
143
|
-
return `${protocol}${prefix}${newVersion}`;
|
|
144
|
-
}
|
|
145
|
-
//#endregion
|
|
146
|
-
export { prependToChangelog as a, loadFormatter as i, defaultFormatter as n, generateChangelogEntry as r, applyReleasePlan as t };
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|