@varlock/bumpy 1.13.2 → 1.14.0-rc.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/README.md +3 -1
- package/config-schema.json +43 -0
- package/dist/{add-Dt1hddMt.mjs → add-C9rU_89s.mjs} +4 -4
- package/dist/{apply-release-plan-DD2R7SL2.mjs → apply-release-plan-DxTsUSqa.mjs} +11 -2
- package/dist/{bump-file-B7hmXZlB.mjs → bump-file-mRJeReRJ.mjs} +43 -8
- package/dist/{changelog-CbaET5V6.mjs → changelog-DuFhnJRO.mjs} +3 -3
- package/dist/{changelog-github-DXDnWkrB.mjs → changelog-github-jLOtwuWj.mjs} +2 -2
- package/dist/channels-CFXZkyGd.mjs +75 -0
- package/dist/{check-Dvi0DIqC.mjs → check-DIl9Dz68.mjs} +18 -6
- package/dist/{ci-B7gF6CFP.mjs → ci-ChYmDuwy.mjs} +376 -23
- package/dist/cli.mjs +30 -15
- package/dist/{config-D_4GYDJi.mjs → config-0we4ISZX.mjs} +5 -1
- package/dist/{generate-DohUlhu3.mjs → generate-B2OMt_64.mjs} +3 -3
- package/dist/{git-BWPimLgc.mjs → git-DAWj8LyV.mjs} +12 -1
- package/dist/index.d.mts +46 -4
- package/dist/index.mjs +7 -7
- package/dist/prerelease-B2PVfXkm.mjs +205 -0
- package/dist/{publish-VYBhDYFM.mjs → publish-Ak6jmwi_.mjs} +105 -14
- package/dist/{publish-pipeline-BPedWvKS.mjs → publish-pipeline-BD8mLbL9.mjs} +2 -2
- package/dist/{release-plan-mK7iGeGq.mjs → release-plan-C84pcBi-.mjs} +12 -17
- package/dist/status-DIzi-Iai.mjs +232 -0
- package/dist/{types-Bkh-igOJ.mjs → types-lpiG-Zxh.mjs} +1 -0
- package/dist/version-CMJUopVj.mjs +192 -0
- package/package.json +1 -1
- package/dist/status-DxzKPM8d.mjs +0 -129
- package/dist/version-Cm0nRAFF.mjs +0 -123
- /package/dist/{commit-message-CSWVKPJ-.mjs → commit-message-BwsowSds.mjs} +0 -0
- /package/dist/{init-BCkm6Nfa.mjs → init-DkAY5hjc.mjs} +0 -0
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
import { n as log, t as colorize } from "./logger-BgksGFuf.mjs";
|
|
2
|
+
import { a as loadConfig } from "./config-0we4ISZX.mjs";
|
|
3
|
+
import { i as readBumpFiles, s as discoverPackages, t as filterBranchBumpFiles } from "./bump-file-mRJeReRJ.mjs";
|
|
4
|
+
import { o as DependencyGraph, t as assembleReleasePlan } from "./release-plan-C84pcBi-.mjs";
|
|
5
|
+
import { a as getChangedFiles, o as getCurrentBranch } from "./git-DAWj8LyV.mjs";
|
|
6
|
+
import { channelNames, resolveActiveChannel } from "./channels-CFXZkyGd.mjs";
|
|
7
|
+
import { t as buildChannelReleasePlan } from "./prerelease-B2PVfXkm.mjs";
|
|
8
|
+
//#region src/commands/status.ts
|
|
9
|
+
async function statusCommand(rootDir, opts) {
|
|
10
|
+
const config = await loadConfig(rootDir);
|
|
11
|
+
const packages = await discoverPackages(rootDir, config);
|
|
12
|
+
const depGraph = new DependencyGraph(packages);
|
|
13
|
+
const channel = resolveActiveChannel(rootDir, config, opts.channel);
|
|
14
|
+
if (channel) {
|
|
15
|
+
await channelStatus(rootDir, config, channel, packages, depGraph, opts);
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
const { bumpFiles, errors: parseErrors } = await readBumpFiles(rootDir, { channels: channelNames(config) });
|
|
19
|
+
if (parseErrors.length > 0) for (const err of parseErrors) log.error(err);
|
|
20
|
+
if (bumpFiles.length === 0) {
|
|
21
|
+
if (opts.json) console.log(JSON.stringify({
|
|
22
|
+
bumpFiles: [],
|
|
23
|
+
releases: [],
|
|
24
|
+
packageNames: []
|
|
25
|
+
}, null, 2));
|
|
26
|
+
else if (!opts.packagesOnly) log.info("No pending bump files.");
|
|
27
|
+
process.exit(1);
|
|
28
|
+
}
|
|
29
|
+
const plan = assembleReleasePlan(bumpFiles, packages, depGraph, config);
|
|
30
|
+
let branchBumpFileIds;
|
|
31
|
+
const currentBranch = getCurrentBranch({ cwd: rootDir });
|
|
32
|
+
if (currentBranch && currentBranch !== config.baseBranch) branchBumpFileIds = filterBranchBumpFiles(bumpFiles, getChangedFiles(rootDir, config.baseBranch), rootDir).branchBumpFileIds;
|
|
33
|
+
let releases = plan.releases;
|
|
34
|
+
if (opts.bumpType) {
|
|
35
|
+
const types = opts.bumpType.split(",").map((t) => t.trim());
|
|
36
|
+
releases = releases.filter((r) => types.includes(r.type));
|
|
37
|
+
}
|
|
38
|
+
if (opts.filter) {
|
|
39
|
+
const { matchGlob } = await import("./config-0we4ISZX.mjs").then((n) => n.t);
|
|
40
|
+
const patterns = opts.filter.split(",").map((p) => p.trim());
|
|
41
|
+
releases = releases.filter((r) => patterns.some((p) => matchGlob(r.name, p)));
|
|
42
|
+
}
|
|
43
|
+
if (opts.json) {
|
|
44
|
+
const jsonOutput = {
|
|
45
|
+
bumpFiles: plan.bumpFiles.map((bf) => ({
|
|
46
|
+
id: bf.id,
|
|
47
|
+
summary: bf.summary,
|
|
48
|
+
releases: bf.releases.map((r) => ({
|
|
49
|
+
name: r.name,
|
|
50
|
+
type: r.type
|
|
51
|
+
})),
|
|
52
|
+
...branchBumpFileIds ? { inCurrentBranch: branchBumpFileIds.has(bf.id) } : {}
|
|
53
|
+
})),
|
|
54
|
+
releases: releases.map((r) => {
|
|
55
|
+
const pkg = packages.get(r.name);
|
|
56
|
+
const pkgConfig = pkg?.bumpy || {};
|
|
57
|
+
return {
|
|
58
|
+
name: r.name,
|
|
59
|
+
type: r.type,
|
|
60
|
+
oldVersion: r.oldVersion,
|
|
61
|
+
newVersion: r.newVersion,
|
|
62
|
+
dir: pkg?.relativeDir,
|
|
63
|
+
bumpFiles: r.bumpFiles,
|
|
64
|
+
isDependencyBump: r.isDependencyBump,
|
|
65
|
+
isCascadeBump: r.isCascadeBump,
|
|
66
|
+
...branchBumpFileIds ? { inCurrentBranch: r.bumpFiles.some((id) => branchBumpFileIds.has(id)) } : {},
|
|
67
|
+
publishTargets: getPublishTargets(pkg, pkgConfig, config)
|
|
68
|
+
};
|
|
69
|
+
}),
|
|
70
|
+
packageNames: releases.map((r) => r.name)
|
|
71
|
+
};
|
|
72
|
+
console.log(JSON.stringify(jsonOutput, null, 2));
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
if (opts.packagesOnly) {
|
|
76
|
+
for (const r of releases) console.log(r.name);
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
log.bold(`${bumpFiles.length} bump file(s) pending\n`);
|
|
80
|
+
if (releases.length === 0) {
|
|
81
|
+
log.warn("No packages match the current filters.");
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
const groups = [
|
|
85
|
+
[
|
|
86
|
+
"Major",
|
|
87
|
+
"red",
|
|
88
|
+
releases.filter((r) => r.type === "major")
|
|
89
|
+
],
|
|
90
|
+
[
|
|
91
|
+
"Minor",
|
|
92
|
+
"yellow",
|
|
93
|
+
releases.filter((r) => r.type === "minor")
|
|
94
|
+
],
|
|
95
|
+
[
|
|
96
|
+
"Patch",
|
|
97
|
+
"green",
|
|
98
|
+
releases.filter((r) => r.type === "patch")
|
|
99
|
+
]
|
|
100
|
+
];
|
|
101
|
+
for (const [label, color, group] of groups) {
|
|
102
|
+
if (group.length === 0) continue;
|
|
103
|
+
log.bold(colorize(label, color));
|
|
104
|
+
for (const r of group) printRelease(r, packages);
|
|
105
|
+
console.log();
|
|
106
|
+
}
|
|
107
|
+
if (plan.warnings.length > 0) {
|
|
108
|
+
for (const w of plan.warnings) log.warn(w);
|
|
109
|
+
console.log();
|
|
110
|
+
}
|
|
111
|
+
if (opts.verbose) {
|
|
112
|
+
log.bold("Bump files:");
|
|
113
|
+
for (const bf of plan.bumpFiles) {
|
|
114
|
+
console.log(` ${colorize(bf.id, "cyan")}`);
|
|
115
|
+
for (const r of bf.releases) console.log(` ${r.name}: ${r.type}`);
|
|
116
|
+
if (bf.summary) console.log(` ${colorize(bf.summary.split("\n")[0], "dim")}`);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Status on a prerelease channel: shows the cycle (shipped + pending bump files)
|
|
122
|
+
* and the derived prerelease versions. Counters come from the registry — when it's
|
|
123
|
+
* unreachable, targets render with a ".?" counter placeholder.
|
|
124
|
+
*/
|
|
125
|
+
async function channelStatus(rootDir, config, channel, packages, depGraph, opts) {
|
|
126
|
+
const { bumpFiles, errors: parseErrors } = await readBumpFiles(rootDir, { channels: channelNames(config) });
|
|
127
|
+
for (const err of parseErrors) log.error(err);
|
|
128
|
+
const shipped = bumpFiles.filter((bf) => bf.channel === channel.name);
|
|
129
|
+
const pending = bumpFiles.filter((bf) => bf.channel !== channel.name);
|
|
130
|
+
if (bumpFiles.length === 0) {
|
|
131
|
+
if (opts.json) console.log(JSON.stringify({
|
|
132
|
+
channel: channel.name,
|
|
133
|
+
bumpFiles: [],
|
|
134
|
+
releases: [],
|
|
135
|
+
packageNames: []
|
|
136
|
+
}, null, 2));
|
|
137
|
+
else if (!opts.packagesOnly) log.info(`No bump files in the "${channel.name}" cycle.`);
|
|
138
|
+
process.exit(1);
|
|
139
|
+
}
|
|
140
|
+
const stablePlan = assembleReleasePlan(bumpFiles, packages, depGraph, config, { prereleasePreid: channel.preid });
|
|
141
|
+
let releases = stablePlan.releases;
|
|
142
|
+
let countersExact = false;
|
|
143
|
+
try {
|
|
144
|
+
const built = await buildChannelReleasePlan(stablePlan, channel, packages, rootDir, { forDisplay: true });
|
|
145
|
+
if (built.plan.releases.length > 0) {
|
|
146
|
+
releases = built.plan.releases;
|
|
147
|
+
countersExact = true;
|
|
148
|
+
}
|
|
149
|
+
} catch {}
|
|
150
|
+
if (!countersExact) releases = releases.map((r) => ({
|
|
151
|
+
...r,
|
|
152
|
+
newVersion: `${r.newVersion}-${channel.preid}.?`
|
|
153
|
+
}));
|
|
154
|
+
if (opts.bumpType) {
|
|
155
|
+
const types = opts.bumpType.split(",").map((t) => t.trim());
|
|
156
|
+
releases = releases.filter((r) => types.includes(r.type));
|
|
157
|
+
}
|
|
158
|
+
if (opts.filter) {
|
|
159
|
+
const { matchGlob } = await import("./config-0we4ISZX.mjs").then((n) => n.t);
|
|
160
|
+
const patterns = opts.filter.split(",").map((p) => p.trim());
|
|
161
|
+
releases = releases.filter((r) => patterns.some((p) => matchGlob(r.name, p)));
|
|
162
|
+
}
|
|
163
|
+
if (opts.json) {
|
|
164
|
+
console.log(JSON.stringify({
|
|
165
|
+
channel: channel.name,
|
|
166
|
+
preid: channel.preid,
|
|
167
|
+
tag: channel.tag,
|
|
168
|
+
bumpFiles: bumpFiles.map((bf) => ({
|
|
169
|
+
id: bf.id,
|
|
170
|
+
summary: bf.summary,
|
|
171
|
+
releases: bf.releases.map((r) => ({
|
|
172
|
+
name: r.name,
|
|
173
|
+
type: r.type
|
|
174
|
+
})),
|
|
175
|
+
shipped: bf.channel === channel.name
|
|
176
|
+
})),
|
|
177
|
+
releases: releases.map((r) => {
|
|
178
|
+
const pkg = packages.get(r.name);
|
|
179
|
+
return {
|
|
180
|
+
name: r.name,
|
|
181
|
+
type: r.type,
|
|
182
|
+
oldVersion: r.oldVersion,
|
|
183
|
+
newVersion: r.newVersion,
|
|
184
|
+
dir: pkg?.relativeDir,
|
|
185
|
+
bumpFiles: r.bumpFiles,
|
|
186
|
+
isDependencyBump: r.isDependencyBump,
|
|
187
|
+
isCascadeBump: r.isCascadeBump,
|
|
188
|
+
publishTargets: getPublishTargets(pkg, pkg?.bumpy || {}, config)
|
|
189
|
+
};
|
|
190
|
+
}),
|
|
191
|
+
packageNames: releases.map((r) => r.name)
|
|
192
|
+
}, null, 2));
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
if (opts.packagesOnly) {
|
|
196
|
+
for (const r of releases) console.log(r.name);
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
log.bold(`Channel "${channel.name}" — preid "-${channel.preid}.N", dist-tag @${channel.tag}\n`);
|
|
200
|
+
printBumpFileGroup(`Shipped on this channel (.bumpy/${channel.name}/)`, shipped);
|
|
201
|
+
printBumpFileGroup("Pending (next prerelease)", pending);
|
|
202
|
+
log.bold(`Cycle releases${countersExact ? "" : colorize(" (registry unreachable — counters unknown)", "dim")}`);
|
|
203
|
+
for (const r of releases) printRelease(r, packages);
|
|
204
|
+
console.log();
|
|
205
|
+
if (stablePlan.warnings.length > 0) for (const w of stablePlan.warnings) log.warn(w);
|
|
206
|
+
}
|
|
207
|
+
function printBumpFileGroup(label, files) {
|
|
208
|
+
log.bold(label);
|
|
209
|
+
if (files.length === 0) console.log(colorize(" (none)", "dim"));
|
|
210
|
+
for (const bf of files) {
|
|
211
|
+
const summary = bf.summary ? colorize(` — ${bf.summary.split("\n")[0]}`, "dim") : "";
|
|
212
|
+
console.log(` ${colorize(`${bf.id}.md`, "cyan")}${summary}`);
|
|
213
|
+
}
|
|
214
|
+
console.log();
|
|
215
|
+
}
|
|
216
|
+
function printRelease(r, packages) {
|
|
217
|
+
const pkg = packages.get(r.name);
|
|
218
|
+
const dir = pkg ? colorize(` (${pkg.relativeDir})`, "dim") : "";
|
|
219
|
+
const suffix = r.isDependencyBump ? colorize(" ← dependency bump", "dim") : r.isCascadeBump ? colorize(" ← cascade", "dim") : "";
|
|
220
|
+
console.log(` ${r.name}: ${r.oldVersion} → ${colorize(r.newVersion, "cyan")}${suffix}${dir}`);
|
|
221
|
+
}
|
|
222
|
+
/** Determine which publish targets a package will use */
|
|
223
|
+
function getPublishTargets(pkg, pkgConfig, _config) {
|
|
224
|
+
if (!pkg) return [];
|
|
225
|
+
if (pkg.private && !pkgConfig.publishCommand) return [];
|
|
226
|
+
const targets = [];
|
|
227
|
+
if (pkgConfig.publishCommand) targets.push({ type: "custom" });
|
|
228
|
+
if (!pkgConfig.publishCommand && !pkgConfig.skipNpmPublish) targets.push({ type: "npm" });
|
|
229
|
+
return targets;
|
|
230
|
+
}
|
|
231
|
+
//#endregion
|
|
232
|
+
export { statusCommand };
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import { n as log, t as colorize } from "./logger-BgksGFuf.mjs";
|
|
2
|
+
import { a as loadConfig } from "./config-0we4ISZX.mjs";
|
|
3
|
+
import { r as detectWorkspaces } from "./package-manager-Db_vTztt.mjs";
|
|
4
|
+
import { i as readBumpFiles, n as moveBumpFilesToChannel, s as discoverPackages } from "./bump-file-mRJeReRJ.mjs";
|
|
5
|
+
import { o as DependencyGraph, t as assembleReleasePlan } from "./release-plan-C84pcBi-.mjs";
|
|
6
|
+
import { n as runArgs, s as tryRunArgs } from "./shell-C8KgKnMQ.mjs";
|
|
7
|
+
import { t as applyReleasePlan } from "./apply-release-plan-DxTsUSqa.mjs";
|
|
8
|
+
import { channelNames, resolveActiveChannel } from "./channels-CFXZkyGd.mjs";
|
|
9
|
+
import { t as resolveCommitMessage } from "./commit-message-BwsowSds.mjs";
|
|
10
|
+
//#region src/commands/version.ts
|
|
11
|
+
async function versionCommand(rootDir, opts = {}) {
|
|
12
|
+
const config = await loadConfig(rootDir);
|
|
13
|
+
const channel = resolveActiveChannel(rootDir, config, opts.channel);
|
|
14
|
+
if (channel) {
|
|
15
|
+
await channelVersion(rootDir, config, channel, { commit: opts.commit });
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
const packages = await discoverPackages(rootDir, config);
|
|
19
|
+
const depGraph = new DependencyGraph(packages);
|
|
20
|
+
const { bumpFiles, errors: parseErrors } = await readBumpFiles(rootDir, { channels: channelNames(config) });
|
|
21
|
+
if (parseErrors.length > 0) {
|
|
22
|
+
for (const err of parseErrors) log.error(err);
|
|
23
|
+
throw new Error("Bump file parse errors must be fixed before versioning.");
|
|
24
|
+
}
|
|
25
|
+
if (bumpFiles.length === 0) {
|
|
26
|
+
log.info("No pending bump files.");
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const plan = assembleReleasePlan(bumpFiles, packages, depGraph, config);
|
|
30
|
+
if (plan.releases.length === 0) {
|
|
31
|
+
log.warn("Bump files found but no packages would be released.");
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
if (plan.warnings.length > 0) {
|
|
35
|
+
for (const w of plan.warnings) log.warn(w);
|
|
36
|
+
console.log();
|
|
37
|
+
}
|
|
38
|
+
log.step("Applying version bumps:");
|
|
39
|
+
for (const r of plan.releases) {
|
|
40
|
+
const tag = r.isDependencyBump ? " (dep)" : r.isCascadeBump ? " (cascade)" : "";
|
|
41
|
+
console.log(` ${r.name}: ${r.oldVersion} → ${colorize(r.newVersion, "cyan")}${tag}`);
|
|
42
|
+
}
|
|
43
|
+
await applyReleasePlan(plan, packages, rootDir, config);
|
|
44
|
+
log.success(`🐸 Updated ${plan.releases.length} package(s)`);
|
|
45
|
+
log.dim(` Deleted ${bumpFiles.length} bump file(s)`);
|
|
46
|
+
await updateLockfile(rootDir);
|
|
47
|
+
if (opts.commit) try {
|
|
48
|
+
runArgs([
|
|
49
|
+
"git",
|
|
50
|
+
"add",
|
|
51
|
+
"-A",
|
|
52
|
+
".bumpy/"
|
|
53
|
+
], { cwd: rootDir });
|
|
54
|
+
for (const r of plan.releases) {
|
|
55
|
+
const pkg = packages.get(r.name);
|
|
56
|
+
runArgs([
|
|
57
|
+
"git",
|
|
58
|
+
"add",
|
|
59
|
+
"--",
|
|
60
|
+
`${pkg.relativeDir}/package.json`
|
|
61
|
+
], { cwd: rootDir });
|
|
62
|
+
runArgs([
|
|
63
|
+
"git",
|
|
64
|
+
"add",
|
|
65
|
+
"--",
|
|
66
|
+
`${pkg.relativeDir}/CHANGELOG.md`
|
|
67
|
+
], { cwd: rootDir });
|
|
68
|
+
}
|
|
69
|
+
for (const lockfile of [
|
|
70
|
+
"bun.lock",
|
|
71
|
+
"bun.lockb",
|
|
72
|
+
"pnpm-lock.yaml",
|
|
73
|
+
"yarn.lock",
|
|
74
|
+
"package-lock.json"
|
|
75
|
+
]) tryRunArgs([
|
|
76
|
+
"git",
|
|
77
|
+
"add",
|
|
78
|
+
"--",
|
|
79
|
+
lockfile
|
|
80
|
+
], { cwd: rootDir });
|
|
81
|
+
runArgs([
|
|
82
|
+
"git",
|
|
83
|
+
"commit",
|
|
84
|
+
"-F",
|
|
85
|
+
"-"
|
|
86
|
+
], {
|
|
87
|
+
cwd: rootDir,
|
|
88
|
+
input: await resolveCommitMessage(config.versionCommitMessage, plan, rootDir)
|
|
89
|
+
});
|
|
90
|
+
log.success("Created git commit");
|
|
91
|
+
} catch (e) {
|
|
92
|
+
log.warn(`Git commit failed: ${e}`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* "Versioning" on a prerelease channel never writes versions or changelogs — those
|
|
97
|
+
* are derived at publish time. It only moves pending bump files (root + other
|
|
98
|
+
* channels' dirs) into this channel's `.bumpy/<channel>/` directory, marking them
|
|
99
|
+
* as shipped on this channel.
|
|
100
|
+
*/
|
|
101
|
+
async function channelVersion(rootDir, config, channel, opts = {}) {
|
|
102
|
+
const packages = await discoverPackages(rootDir, config);
|
|
103
|
+
const depGraph = new DependencyGraph(packages);
|
|
104
|
+
const { bumpFiles, errors: parseErrors } = await readBumpFiles(rootDir, { channels: channelNames(config) });
|
|
105
|
+
if (parseErrors.length > 0) {
|
|
106
|
+
for (const err of parseErrors) log.error(err);
|
|
107
|
+
throw new Error("Bump file parse errors must be fixed before versioning.");
|
|
108
|
+
}
|
|
109
|
+
const pending = bumpFiles.filter((bf) => bf.channel !== channel.name);
|
|
110
|
+
if (pending.length === 0) {
|
|
111
|
+
log.info(`No pending bump files for channel "${channel.name}".`);
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
const cyclePlan = assembleReleasePlan(bumpFiles, packages, depGraph, config, { prereleasePreid: channel.preid });
|
|
115
|
+
if (cyclePlan.warnings.length > 0) {
|
|
116
|
+
for (const w of cyclePlan.warnings) log.warn(w);
|
|
117
|
+
console.log();
|
|
118
|
+
}
|
|
119
|
+
log.step(`Channel "${channel.name}" — moving ${pending.length} bump file(s) into .bumpy/${channel.name}/:`);
|
|
120
|
+
for (const bf of pending) {
|
|
121
|
+
const from = bf.channel ? `.bumpy/${bf.channel}/` : ".bumpy/";
|
|
122
|
+
console.log(` ${from}${bf.id}.md → .bumpy/${channel.name}/${bf.id}.md`);
|
|
123
|
+
}
|
|
124
|
+
console.log();
|
|
125
|
+
log.step("Cycle targets (counters are derived from the registry at publish time):");
|
|
126
|
+
for (const r of cyclePlan.releases) {
|
|
127
|
+
const tag = r.isDependencyBump ? " (dep)" : r.isCascadeBump ? " (cascade)" : "";
|
|
128
|
+
console.log(` ${r.name}: ${r.oldVersion} → ${colorize(`${r.newVersion}-${channel.preid}.x`, "cyan")}${tag}`);
|
|
129
|
+
}
|
|
130
|
+
await moveBumpFilesToChannel(rootDir, pending, channel.name);
|
|
131
|
+
log.success(`🐸 Moved ${pending.length} bump file(s) — no versions written (prereleases are derived, not committed)`);
|
|
132
|
+
if (opts.commit) try {
|
|
133
|
+
runArgs([
|
|
134
|
+
"git",
|
|
135
|
+
"add",
|
|
136
|
+
"-A",
|
|
137
|
+
".bumpy/"
|
|
138
|
+
], { cwd: rootDir });
|
|
139
|
+
const summary = pending.map((bf) => `${bf.id}.md`).join(", ");
|
|
140
|
+
runArgs([
|
|
141
|
+
"git",
|
|
142
|
+
"commit",
|
|
143
|
+
"-F",
|
|
144
|
+
"-"
|
|
145
|
+
], {
|
|
146
|
+
cwd: rootDir,
|
|
147
|
+
input: `Version prerelease (${channel.name})\n\nShipped: ${summary}`
|
|
148
|
+
});
|
|
149
|
+
log.success("Created git commit");
|
|
150
|
+
} catch (e) {
|
|
151
|
+
log.warn(`Git commit failed: ${e}`);
|
|
152
|
+
}
|
|
153
|
+
return {
|
|
154
|
+
cyclePlan,
|
|
155
|
+
movedFiles: pending
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
/** Run the package manager's install to update the lockfile */
|
|
159
|
+
async function updateLockfile(rootDir) {
|
|
160
|
+
const { packageManager } = await detectWorkspaces(rootDir);
|
|
161
|
+
const installArgs = getInstallArgs(packageManager);
|
|
162
|
+
log.step(`Updating lockfile (${installArgs.join(" ")})...`);
|
|
163
|
+
try {
|
|
164
|
+
runArgs(installArgs, { cwd: rootDir });
|
|
165
|
+
log.dim(" Lockfile updated");
|
|
166
|
+
} catch (err) {
|
|
167
|
+
log.warn(` Lockfile update failed: ${err instanceof Error ? err.message : err}`);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
function getInstallArgs(pm) {
|
|
171
|
+
switch (pm) {
|
|
172
|
+
case "pnpm": return [
|
|
173
|
+
"pnpm",
|
|
174
|
+
"install",
|
|
175
|
+
"--lockfile-only"
|
|
176
|
+
];
|
|
177
|
+
case "bun": return ["bun", "install"];
|
|
178
|
+
case "yarn": return [
|
|
179
|
+
"yarn",
|
|
180
|
+
"install",
|
|
181
|
+
"--mode",
|
|
182
|
+
"update-lockfile"
|
|
183
|
+
];
|
|
184
|
+
default: return [
|
|
185
|
+
"npm",
|
|
186
|
+
"install",
|
|
187
|
+
"--package-lock-only"
|
|
188
|
+
];
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
//#endregion
|
|
192
|
+
export { channelVersion, versionCommand };
|
package/package.json
CHANGED
package/dist/status-DxzKPM8d.mjs
DELETED
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
import { n as log, t as colorize } from "./logger-BgksGFuf.mjs";
|
|
2
|
-
import { a as loadConfig } from "./config-D_4GYDJi.mjs";
|
|
3
|
-
import { o as discoverPackages, r as readBumpFiles, t as filterBranchBumpFiles } from "./bump-file-B7hmXZlB.mjs";
|
|
4
|
-
import { a as DependencyGraph, t as assembleReleasePlan } from "./release-plan-mK7iGeGq.mjs";
|
|
5
|
-
import { a as getChangedFiles, o as getCurrentBranch } from "./git-BWPimLgc.mjs";
|
|
6
|
-
//#region src/commands/status.ts
|
|
7
|
-
async function statusCommand(rootDir, opts) {
|
|
8
|
-
const config = await loadConfig(rootDir);
|
|
9
|
-
const packages = await discoverPackages(rootDir, config);
|
|
10
|
-
const depGraph = new DependencyGraph(packages);
|
|
11
|
-
const { bumpFiles, errors: parseErrors } = await readBumpFiles(rootDir);
|
|
12
|
-
if (parseErrors.length > 0) for (const err of parseErrors) log.error(err);
|
|
13
|
-
if (bumpFiles.length === 0) {
|
|
14
|
-
if (opts.json) console.log(JSON.stringify({
|
|
15
|
-
bumpFiles: [],
|
|
16
|
-
releases: [],
|
|
17
|
-
packageNames: []
|
|
18
|
-
}, null, 2));
|
|
19
|
-
else if (!opts.packagesOnly) log.info("No pending bump files.");
|
|
20
|
-
process.exit(1);
|
|
21
|
-
}
|
|
22
|
-
const plan = assembleReleasePlan(bumpFiles, packages, depGraph, config);
|
|
23
|
-
let branchBumpFileIds;
|
|
24
|
-
const currentBranch = getCurrentBranch({ cwd: rootDir });
|
|
25
|
-
if (currentBranch && currentBranch !== config.baseBranch) branchBumpFileIds = filterBranchBumpFiles(bumpFiles, getChangedFiles(rootDir, config.baseBranch), rootDir).branchBumpFileIds;
|
|
26
|
-
let releases = plan.releases;
|
|
27
|
-
if (opts.bumpType) {
|
|
28
|
-
const types = opts.bumpType.split(",").map((t) => t.trim());
|
|
29
|
-
releases = releases.filter((r) => types.includes(r.type));
|
|
30
|
-
}
|
|
31
|
-
if (opts.filter) {
|
|
32
|
-
const { matchGlob } = await import("./config-D_4GYDJi.mjs").then((n) => n.t);
|
|
33
|
-
const patterns = opts.filter.split(",").map((p) => p.trim());
|
|
34
|
-
releases = releases.filter((r) => patterns.some((p) => matchGlob(r.name, p)));
|
|
35
|
-
}
|
|
36
|
-
if (opts.json) {
|
|
37
|
-
const jsonOutput = {
|
|
38
|
-
bumpFiles: plan.bumpFiles.map((bf) => ({
|
|
39
|
-
id: bf.id,
|
|
40
|
-
summary: bf.summary,
|
|
41
|
-
releases: bf.releases.map((r) => ({
|
|
42
|
-
name: r.name,
|
|
43
|
-
type: r.type
|
|
44
|
-
})),
|
|
45
|
-
...branchBumpFileIds ? { inCurrentBranch: branchBumpFileIds.has(bf.id) } : {}
|
|
46
|
-
})),
|
|
47
|
-
releases: releases.map((r) => {
|
|
48
|
-
const pkg = packages.get(r.name);
|
|
49
|
-
const pkgConfig = pkg?.bumpy || {};
|
|
50
|
-
return {
|
|
51
|
-
name: r.name,
|
|
52
|
-
type: r.type,
|
|
53
|
-
oldVersion: r.oldVersion,
|
|
54
|
-
newVersion: r.newVersion,
|
|
55
|
-
dir: pkg?.relativeDir,
|
|
56
|
-
bumpFiles: r.bumpFiles,
|
|
57
|
-
isDependencyBump: r.isDependencyBump,
|
|
58
|
-
isCascadeBump: r.isCascadeBump,
|
|
59
|
-
...branchBumpFileIds ? { inCurrentBranch: r.bumpFiles.some((id) => branchBumpFileIds.has(id)) } : {},
|
|
60
|
-
publishTargets: getPublishTargets(pkg, pkgConfig, config)
|
|
61
|
-
};
|
|
62
|
-
}),
|
|
63
|
-
packageNames: releases.map((r) => r.name)
|
|
64
|
-
};
|
|
65
|
-
console.log(JSON.stringify(jsonOutput, null, 2));
|
|
66
|
-
return;
|
|
67
|
-
}
|
|
68
|
-
if (opts.packagesOnly) {
|
|
69
|
-
for (const r of releases) console.log(r.name);
|
|
70
|
-
return;
|
|
71
|
-
}
|
|
72
|
-
log.bold(`${bumpFiles.length} bump file(s) pending\n`);
|
|
73
|
-
if (releases.length === 0) {
|
|
74
|
-
log.warn("No packages match the current filters.");
|
|
75
|
-
return;
|
|
76
|
-
}
|
|
77
|
-
const groups = [
|
|
78
|
-
[
|
|
79
|
-
"Major",
|
|
80
|
-
"red",
|
|
81
|
-
releases.filter((r) => r.type === "major")
|
|
82
|
-
],
|
|
83
|
-
[
|
|
84
|
-
"Minor",
|
|
85
|
-
"yellow",
|
|
86
|
-
releases.filter((r) => r.type === "minor")
|
|
87
|
-
],
|
|
88
|
-
[
|
|
89
|
-
"Patch",
|
|
90
|
-
"green",
|
|
91
|
-
releases.filter((r) => r.type === "patch")
|
|
92
|
-
]
|
|
93
|
-
];
|
|
94
|
-
for (const [label, color, group] of groups) {
|
|
95
|
-
if (group.length === 0) continue;
|
|
96
|
-
log.bold(colorize(label, color));
|
|
97
|
-
for (const r of group) printRelease(r, packages);
|
|
98
|
-
console.log();
|
|
99
|
-
}
|
|
100
|
-
if (plan.warnings.length > 0) {
|
|
101
|
-
for (const w of plan.warnings) log.warn(w);
|
|
102
|
-
console.log();
|
|
103
|
-
}
|
|
104
|
-
if (opts.verbose) {
|
|
105
|
-
log.bold("Bump files:");
|
|
106
|
-
for (const bf of plan.bumpFiles) {
|
|
107
|
-
console.log(` ${colorize(bf.id, "cyan")}`);
|
|
108
|
-
for (const r of bf.releases) console.log(` ${r.name}: ${r.type}`);
|
|
109
|
-
if (bf.summary) console.log(` ${colorize(bf.summary.split("\n")[0], "dim")}`);
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
function printRelease(r, packages) {
|
|
114
|
-
const pkg = packages.get(r.name);
|
|
115
|
-
const dir = pkg ? colorize(` (${pkg.relativeDir})`, "dim") : "";
|
|
116
|
-
const suffix = r.isDependencyBump ? colorize(" ← dependency bump", "dim") : r.isCascadeBump ? colorize(" ← cascade", "dim") : "";
|
|
117
|
-
console.log(` ${r.name}: ${r.oldVersion} → ${colorize(r.newVersion, "cyan")}${suffix}${dir}`);
|
|
118
|
-
}
|
|
119
|
-
/** Determine which publish targets a package will use */
|
|
120
|
-
function getPublishTargets(pkg, pkgConfig, _config) {
|
|
121
|
-
if (!pkg) return [];
|
|
122
|
-
if (pkg.private && !pkgConfig.publishCommand) return [];
|
|
123
|
-
const targets = [];
|
|
124
|
-
if (pkgConfig.publishCommand) targets.push({ type: "custom" });
|
|
125
|
-
if (!pkgConfig.publishCommand && !pkgConfig.skipNpmPublish) targets.push({ type: "npm" });
|
|
126
|
-
return targets;
|
|
127
|
-
}
|
|
128
|
-
//#endregion
|
|
129
|
-
export { statusCommand };
|
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
import { n as log, t as colorize } from "./logger-BgksGFuf.mjs";
|
|
2
|
-
import { a as loadConfig } from "./config-D_4GYDJi.mjs";
|
|
3
|
-
import { r as detectWorkspaces } from "./package-manager-Db_vTztt.mjs";
|
|
4
|
-
import { o as discoverPackages, r as readBumpFiles } from "./bump-file-B7hmXZlB.mjs";
|
|
5
|
-
import { a as DependencyGraph, t as assembleReleasePlan } from "./release-plan-mK7iGeGq.mjs";
|
|
6
|
-
import { n as runArgs, s as tryRunArgs } from "./shell-C8KgKnMQ.mjs";
|
|
7
|
-
import { t as applyReleasePlan } from "./apply-release-plan-DD2R7SL2.mjs";
|
|
8
|
-
import { t as resolveCommitMessage } from "./commit-message-CSWVKPJ-.mjs";
|
|
9
|
-
//#region src/commands/version.ts
|
|
10
|
-
async function versionCommand(rootDir, opts = {}) {
|
|
11
|
-
const config = await loadConfig(rootDir);
|
|
12
|
-
const packages = await discoverPackages(rootDir, config);
|
|
13
|
-
const depGraph = new DependencyGraph(packages);
|
|
14
|
-
const { bumpFiles, errors: parseErrors } = await readBumpFiles(rootDir);
|
|
15
|
-
if (parseErrors.length > 0) {
|
|
16
|
-
for (const err of parseErrors) log.error(err);
|
|
17
|
-
throw new Error("Bump file parse errors must be fixed before versioning.");
|
|
18
|
-
}
|
|
19
|
-
if (bumpFiles.length === 0) {
|
|
20
|
-
log.info("No pending bump files.");
|
|
21
|
-
return;
|
|
22
|
-
}
|
|
23
|
-
const plan = assembleReleasePlan(bumpFiles, packages, depGraph, config);
|
|
24
|
-
if (plan.releases.length === 0) {
|
|
25
|
-
log.warn("Bump files found but no packages would be released.");
|
|
26
|
-
return;
|
|
27
|
-
}
|
|
28
|
-
if (plan.warnings.length > 0) {
|
|
29
|
-
for (const w of plan.warnings) log.warn(w);
|
|
30
|
-
console.log();
|
|
31
|
-
}
|
|
32
|
-
log.step("Applying version bumps:");
|
|
33
|
-
for (const r of plan.releases) {
|
|
34
|
-
const tag = r.isDependencyBump ? " (dep)" : r.isCascadeBump ? " (cascade)" : "";
|
|
35
|
-
console.log(` ${r.name}: ${r.oldVersion} → ${colorize(r.newVersion, "cyan")}${tag}`);
|
|
36
|
-
}
|
|
37
|
-
await applyReleasePlan(plan, packages, rootDir, config);
|
|
38
|
-
log.success(`🐸 Updated ${plan.releases.length} package(s)`);
|
|
39
|
-
log.dim(` Deleted ${bumpFiles.length} bump file(s)`);
|
|
40
|
-
await updateLockfile(rootDir);
|
|
41
|
-
if (opts.commit) try {
|
|
42
|
-
runArgs([
|
|
43
|
-
"git",
|
|
44
|
-
"add",
|
|
45
|
-
"-A",
|
|
46
|
-
".bumpy/"
|
|
47
|
-
], { cwd: rootDir });
|
|
48
|
-
for (const r of plan.releases) {
|
|
49
|
-
const pkg = packages.get(r.name);
|
|
50
|
-
runArgs([
|
|
51
|
-
"git",
|
|
52
|
-
"add",
|
|
53
|
-
"--",
|
|
54
|
-
`${pkg.relativeDir}/package.json`
|
|
55
|
-
], { cwd: rootDir });
|
|
56
|
-
runArgs([
|
|
57
|
-
"git",
|
|
58
|
-
"add",
|
|
59
|
-
"--",
|
|
60
|
-
`${pkg.relativeDir}/CHANGELOG.md`
|
|
61
|
-
], { cwd: rootDir });
|
|
62
|
-
}
|
|
63
|
-
for (const lockfile of [
|
|
64
|
-
"bun.lock",
|
|
65
|
-
"bun.lockb",
|
|
66
|
-
"pnpm-lock.yaml",
|
|
67
|
-
"yarn.lock",
|
|
68
|
-
"package-lock.json"
|
|
69
|
-
]) tryRunArgs([
|
|
70
|
-
"git",
|
|
71
|
-
"add",
|
|
72
|
-
"--",
|
|
73
|
-
lockfile
|
|
74
|
-
], { cwd: rootDir });
|
|
75
|
-
runArgs([
|
|
76
|
-
"git",
|
|
77
|
-
"commit",
|
|
78
|
-
"-F",
|
|
79
|
-
"-"
|
|
80
|
-
], {
|
|
81
|
-
cwd: rootDir,
|
|
82
|
-
input: await resolveCommitMessage(config.versionCommitMessage, plan, rootDir)
|
|
83
|
-
});
|
|
84
|
-
log.success("Created git commit");
|
|
85
|
-
} catch (e) {
|
|
86
|
-
log.warn(`Git commit failed: ${e}`);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
/** Run the package manager's install to update the lockfile */
|
|
90
|
-
async function updateLockfile(rootDir) {
|
|
91
|
-
const { packageManager } = await detectWorkspaces(rootDir);
|
|
92
|
-
const installArgs = getInstallArgs(packageManager);
|
|
93
|
-
log.step(`Updating lockfile (${installArgs.join(" ")})...`);
|
|
94
|
-
try {
|
|
95
|
-
runArgs(installArgs, { cwd: rootDir });
|
|
96
|
-
log.dim(" Lockfile updated");
|
|
97
|
-
} catch (err) {
|
|
98
|
-
log.warn(` Lockfile update failed: ${err instanceof Error ? err.message : err}`);
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
function getInstallArgs(pm) {
|
|
102
|
-
switch (pm) {
|
|
103
|
-
case "pnpm": return [
|
|
104
|
-
"pnpm",
|
|
105
|
-
"install",
|
|
106
|
-
"--lockfile-only"
|
|
107
|
-
];
|
|
108
|
-
case "bun": return ["bun", "install"];
|
|
109
|
-
case "yarn": return [
|
|
110
|
-
"yarn",
|
|
111
|
-
"install",
|
|
112
|
-
"--mode",
|
|
113
|
-
"update-lockfile"
|
|
114
|
-
];
|
|
115
|
-
default: return [
|
|
116
|
-
"npm",
|
|
117
|
-
"install",
|
|
118
|
-
"--package-lock-only"
|
|
119
|
-
];
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
//#endregion
|
|
123
|
-
export { versionCommand };
|
|
File without changes
|
|
File without changes
|