@varlock/bumpy 0.0.2 → 1.1.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/.claude-plugin/plugin.json +2 -2
- package/config-schema.json +327 -0
- package/dist/add-BmNL5VwL.mjs +323 -0
- package/dist/{ai-CQhUyHAG.mjs → ai-sMYUf3lP.mjs} +21 -4
- package/dist/{apply-release-plan-D6TSrcwX.mjs → apply-release-plan-0kH62jhu.mjs} +35 -26
- package/dist/bump-file-DVqR3k67.mjs +157 -0
- package/dist/{changelog-github-Du62krXi.mjs → changelog-github-DkACMj0j.mjs} +23 -21
- package/dist/check-BjWF6SJm.mjs +65 -0
- package/dist/{ci-D6LQbR38.mjs → ci-DY58ugIi.mjs} +138 -91
- package/dist/{ci-setup-C6FlOfW5.mjs → ci-setup-BQwktQEe.mjs} +3 -3
- package/dist/cli.mjs +36 -41
- package/dist/commit-message-BwsowSds.mjs +23 -0
- package/dist/{config-BkwIEaQg.mjs → config-B-Qg3DZH.mjs} +30 -24
- package/dist/fs-DYR2XuFE.mjs +81 -0
- package/dist/generate-DX46X-rW.mjs +186 -0
- package/dist/{git-CGHVXXKw.mjs → git-YDedMddc.mjs} +54 -2
- package/dist/index.d.mts +68 -39
- package/dist/index.mjs +9 -9
- package/dist/init-DkTPs_WQ.mjs +196 -0
- package/dist/{names-Ck8cun7B.mjs → names-C-TuOPbd.mjs} +1 -1
- package/dist/{js-yaml-DpZfOoD4.mjs → package-manager-Clsmr-9r.mjs} +79 -1
- package/dist/picomatch-DMmqYjgq.mjs +1870 -0
- package/dist/{publish-D_7RqEYL.mjs → publish-CGB4TIKD.mjs} +26 -25
- package/dist/{publish-pipeline-ChnqW8nR.mjs → publish-pipeline-CXuqce1N.mjs} +24 -19
- package/dist/release-plan-JNir7bSM.mjs +264 -0
- package/dist/{semver-BTzYh8vc.mjs → semver-BJzWIuRz.mjs} +13 -3
- package/dist/{shell-Dj7JRD_q.mjs → shell-CY7OD48z.mjs} +20 -2
- package/dist/{status--Q8yAxQ4.mjs → status-EGYqULJg.mjs} +26 -22
- package/dist/{version-cAUkfYPx.mjs → version-BcfidiVX.mjs} +23 -22
- package/dist/{workspace-CxEKakDm.mjs → workspace-DWXlwcH4.mjs} +3 -3
- package/package.json +16 -1
- package/skills/add-change/SKILL.md +18 -14
- package/dist/add-BjyVIUlr.mjs +0 -175
- package/dist/changeset-UCZdSRDv.mjs +0 -108
- package/dist/check-jIwike9F.mjs +0 -51
- package/dist/fs-0AtnPUUe.mjs +0 -51
- package/dist/generate-Btrsn1qi.mjs +0 -177
- package/dist/init-B0q3wEQW.mjs +0 -22
- package/dist/migrate-CfQNwD0T.mjs +0 -121
- package/dist/package-manager-DcI5TdDE.mjs +0 -80
- package/dist/release-plan-BEzwApuK.mjs +0 -173
- /package/dist/{clack-CDRCHrC-.mjs → clack-C6bVkGxf.mjs} +0 -0
- /package/dist/{dep-graph-E-9-eQ2J.mjs → dep-graph-DiLeAhl9.mjs} +0 -0
|
@@ -1,14 +1,42 @@
|
|
|
1
1
|
import { n as log, t as colorize } from "./logger-C2dEe5Su.mjs";
|
|
2
|
-
import { a as loadConfig } from "./config-
|
|
3
|
-
import { t as detectPackageManager } from "./package-manager-
|
|
4
|
-
import { n as discoverWorkspace } from "./workspace-
|
|
5
|
-
import { t as DependencyGraph } from "./dep-graph-
|
|
6
|
-
import { n as
|
|
7
|
-
import { r as
|
|
8
|
-
import { t as assembleReleasePlan } from "./release-plan-
|
|
9
|
-
import {
|
|
10
|
-
import { t as randomName } from "./names-
|
|
2
|
+
import { a as loadConfig } from "./config-B-Qg3DZH.mjs";
|
|
3
|
+
import { t as detectPackageManager } from "./package-manager-Clsmr-9r.mjs";
|
|
4
|
+
import { n as discoverWorkspace } from "./workspace-DWXlwcH4.mjs";
|
|
5
|
+
import { t as DependencyGraph } from "./dep-graph-DiLeAhl9.mjs";
|
|
6
|
+
import { n as runArgs, r as runArgsAsync, s as tryRunArgs } from "./shell-CY7OD48z.mjs";
|
|
7
|
+
import { r as readBumpFiles, t as filterBranchBumpFiles } from "./bump-file-DVqR3k67.mjs";
|
|
8
|
+
import { t as assembleReleasePlan } from "./release-plan-JNir7bSM.mjs";
|
|
9
|
+
import { r as getChangedFiles } from "./git-YDedMddc.mjs";
|
|
10
|
+
import { t as randomName } from "./names-C-TuOPbd.mjs";
|
|
11
|
+
import { t as resolveCommitMessage } from "./commit-message-BwsowSds.mjs";
|
|
12
|
+
import { createHash } from "node:crypto";
|
|
11
13
|
//#region src/commands/ci.ts
|
|
14
|
+
/**
|
|
15
|
+
* Temporarily override GH_TOKEN with BUMPY_GH_TOKEN for a gh CLI call.
|
|
16
|
+
*
|
|
17
|
+
* Use `--pat-pr` / `--pat-comments` flags to opt in. This is useful when
|
|
18
|
+
* BUMPY_GH_TOKEN belongs to a dedicated automation/bot account. If you're
|
|
19
|
+
* using a developer's personal PAT, it's better to leave these flags off so
|
|
20
|
+
* that PRs and comments appear from github-actions[bot] — allowing the
|
|
21
|
+
* developer to still review and approve the PR.
|
|
22
|
+
*/
|
|
23
|
+
function requirePatToken() {
|
|
24
|
+
const token = process.env.BUMPY_GH_TOKEN;
|
|
25
|
+
if (!token) throw new Error("BUMPY_GH_TOKEN must be set when using --pat-pr or --pat-comments");
|
|
26
|
+
return token;
|
|
27
|
+
}
|
|
28
|
+
async function withPatToken(usePat, fn) {
|
|
29
|
+
if (!usePat) return fn();
|
|
30
|
+
const token = requirePatToken();
|
|
31
|
+
const originalGhToken = process.env.GH_TOKEN;
|
|
32
|
+
process.env.GH_TOKEN = token;
|
|
33
|
+
try {
|
|
34
|
+
return await fn();
|
|
35
|
+
} finally {
|
|
36
|
+
if (originalGhToken !== void 0) process.env.GH_TOKEN = originalGhToken;
|
|
37
|
+
else delete process.env.GH_TOKEN;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
12
40
|
/** Validate a git branch name to prevent injection */
|
|
13
41
|
function validateBranchName(name) {
|
|
14
42
|
if (!/^[a-zA-Z0-9_./-]+$/.test(name)) throw new Error(`Invalid branch name: ${name}`);
|
|
@@ -43,14 +71,14 @@ function ensureGitIdentity(rootDir, config) {
|
|
|
43
71
|
}
|
|
44
72
|
}
|
|
45
73
|
/**
|
|
46
|
-
* CI check: report on pending
|
|
74
|
+
* CI check: report on pending bump files.
|
|
47
75
|
* Designed for PR workflows — shows what would be released and optionally comments on the PR.
|
|
48
76
|
*/
|
|
49
77
|
async function ciCheckCommand(rootDir, opts) {
|
|
50
78
|
const config = await loadConfig(rootDir);
|
|
51
79
|
const { packages } = await discoverWorkspace(rootDir, config);
|
|
52
80
|
const depGraph = new DependencyGraph(packages);
|
|
53
|
-
const
|
|
81
|
+
const allBumpFiles = await readBumpFiles(rootDir);
|
|
54
82
|
if (detectPrBranch(rootDir) === config.versionPr.branch) {
|
|
55
83
|
log.dim(" Skipping — this is the version PR branch.");
|
|
56
84
|
return;
|
|
@@ -59,22 +87,26 @@ async function ciCheckCommand(rootDir, opts) {
|
|
|
59
87
|
const shouldComment = opts.comment ?? inCI;
|
|
60
88
|
const prNumber = detectPrNumber();
|
|
61
89
|
const pm = await detectPackageManager(rootDir);
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
90
|
+
const { branchBumpFiles: prBumpFiles, branchBumpFileIds: prBumpFileIds } = filterBranchBumpFiles(allBumpFiles, getChangedFiles(rootDir, config.baseBranch));
|
|
91
|
+
if (prBumpFileIds.size > prBumpFiles.length) {
|
|
92
|
+
log.success("Empty bump file found — no releases needed.");
|
|
93
|
+
if (shouldComment && prNumber) await postOrUpdatePrComment(prNumber, formatNoBumpFilesComment(detectPrBranch(rootDir), pm), rootDir, opts.patComments);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
if (prBumpFiles.length === 0) {
|
|
97
|
+
log.info("No bump files found in this PR.");
|
|
98
|
+
if (shouldComment && prNumber) await postOrUpdatePrComment(prNumber, formatNoBumpFilesComment(detectPrBranch(rootDir), pm), rootDir, opts.patComments);
|
|
68
99
|
if (opts.failOnMissing) process.exit(1);
|
|
69
100
|
return;
|
|
70
101
|
}
|
|
71
|
-
const plan = assembleReleasePlan(
|
|
72
|
-
log.bold(`${
|
|
102
|
+
const plan = assembleReleasePlan(prBumpFiles, packages, depGraph, config);
|
|
103
|
+
log.bold(`${prBumpFiles.length} bump file(s) → ${plan.releases.length} package(s) to release\n`);
|
|
73
104
|
for (const r of plan.releases) {
|
|
74
105
|
const tag = r.isDependencyBump ? " (dep)" : r.isCascadeBump ? " (cascade)" : "";
|
|
75
106
|
console.log(` ${r.name}: ${r.oldVersion} → ${colorize(r.newVersion, "cyan")}${tag}`);
|
|
76
107
|
}
|
|
77
|
-
if (
|
|
108
|
+
if (plan.warnings.length > 0) for (const w of plan.warnings) log.warn(w);
|
|
109
|
+
if (shouldComment && prNumber) await postOrUpdatePrComment(prNumber, formatReleasePlanComment(plan, prBumpFiles, prNumber, detectPrBranch(rootDir), pm, plan.warnings), rootDir, opts.patComments);
|
|
78
110
|
}
|
|
79
111
|
/**
|
|
80
112
|
* CI release: either auto-publish or create a version PR.
|
|
@@ -85,24 +117,24 @@ async function ciReleaseCommand(rootDir, opts) {
|
|
|
85
117
|
ensureGitIdentity(rootDir, config);
|
|
86
118
|
const { packages } = await discoverWorkspace(rootDir, config);
|
|
87
119
|
const depGraph = new DependencyGraph(packages);
|
|
88
|
-
const
|
|
89
|
-
if (
|
|
90
|
-
log.info("No pending
|
|
91
|
-
const { publishCommand } = await import("./publish-
|
|
120
|
+
const bumpFiles = await readBumpFiles(rootDir);
|
|
121
|
+
if (bumpFiles.length === 0) {
|
|
122
|
+
log.info("No pending bump files — checking for unpublished packages...");
|
|
123
|
+
const { publishCommand } = await import("./publish-CGB4TIKD.mjs");
|
|
92
124
|
await publishCommand(rootDir, { tag: opts.tag });
|
|
93
125
|
return;
|
|
94
126
|
}
|
|
95
|
-
const plan = assembleReleasePlan(
|
|
127
|
+
const plan = assembleReleasePlan(bumpFiles, packages, depGraph, config);
|
|
96
128
|
if (plan.releases.length === 0) {
|
|
97
|
-
log.info("
|
|
129
|
+
log.info("Bump files found but no packages would be released.");
|
|
98
130
|
return;
|
|
99
131
|
}
|
|
100
|
-
if (opts.mode === "auto-publish") await autoPublish(rootDir, config, opts.tag);
|
|
101
|
-
else await createVersionPr(rootDir, plan, config, new Map([...packages.values()].map((p) => [p.name, p.relativeDir])), opts.branch);
|
|
132
|
+
if (opts.mode === "auto-publish") await autoPublish(rootDir, config, plan, opts.tag);
|
|
133
|
+
else await createVersionPr(rootDir, plan, config, new Map([...packages.values()].map((p) => [p.name, p.relativeDir])), opts.branch, opts.patPr);
|
|
102
134
|
}
|
|
103
|
-
async function autoPublish(rootDir, config, tag) {
|
|
135
|
+
async function autoPublish(rootDir, config, plan, tag) {
|
|
104
136
|
log.step("Running bumpy version...");
|
|
105
|
-
const { versionCommand } = await import("./version-
|
|
137
|
+
const { versionCommand } = await import("./version-BcfidiVX.mjs");
|
|
106
138
|
await versionCommand(rootDir);
|
|
107
139
|
log.step("Committing version changes...");
|
|
108
140
|
runArgs([
|
|
@@ -118,13 +150,20 @@ async function autoPublish(rootDir, config, tag) {
|
|
|
118
150
|
runArgs([
|
|
119
151
|
"git",
|
|
120
152
|
"commit",
|
|
121
|
-
"-
|
|
122
|
-
"
|
|
153
|
+
"-F",
|
|
154
|
+
"-"
|
|
155
|
+
], {
|
|
156
|
+
cwd: rootDir,
|
|
157
|
+
input: await resolveCommitMessage(config.versionCommitMessage, plan, rootDir)
|
|
158
|
+
});
|
|
159
|
+
runArgs([
|
|
160
|
+
"git",
|
|
161
|
+
"push",
|
|
162
|
+
"--no-verify"
|
|
123
163
|
], { cwd: rootDir });
|
|
124
|
-
runArgs(["git", "push"], { cwd: rootDir });
|
|
125
164
|
}
|
|
126
165
|
log.step("Running bumpy publish...");
|
|
127
|
-
const { publishCommand } = await import("./publish-
|
|
166
|
+
const { publishCommand } = await import("./publish-CGB4TIKD.mjs");
|
|
128
167
|
await publishCommand(rootDir, { tag });
|
|
129
168
|
}
|
|
130
169
|
/**
|
|
@@ -138,7 +177,8 @@ async function autoPublish(rootDir, config, tag) {
|
|
|
138
177
|
* When only the default `GITHUB_TOKEN` is available the push still succeeds,
|
|
139
178
|
* but PR workflows won't be triggered automatically.
|
|
140
179
|
*/
|
|
141
|
-
function pushWithToken(rootDir, branch) {
|
|
180
|
+
function pushWithToken(rootDir, branch, config) {
|
|
181
|
+
if (branch === config.baseBranch || branch === "main" || branch === "master") throw new Error(`Refusing to force-push to "${branch}" — this looks like a base branch, not a version PR branch`);
|
|
142
182
|
const token = process.env.BUMPY_GH_TOKEN;
|
|
143
183
|
const repo = process.env.GITHUB_REPOSITORY;
|
|
144
184
|
const server = process.env.GITHUB_SERVER_URL || "https://github.com";
|
|
@@ -162,7 +202,7 @@ function pushWithToken(rootDir, branch) {
|
|
|
162
202
|
"config",
|
|
163
203
|
"--local",
|
|
164
204
|
"--get-regexp",
|
|
165
|
-
"^
|
|
205
|
+
"^includeif\\.gitdir:"
|
|
166
206
|
], { cwd: rootDir });
|
|
167
207
|
const savedIncludeIfs = [];
|
|
168
208
|
if (includeIfRaw) for (const line of includeIfRaw.split("\n").filter(Boolean)) {
|
|
@@ -194,14 +234,20 @@ function pushWithToken(rootDir, branch) {
|
|
|
194
234
|
"origin",
|
|
195
235
|
authedUrl
|
|
196
236
|
], { cwd: rootDir });
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
237
|
+
try {
|
|
238
|
+
runArgs([
|
|
239
|
+
"git",
|
|
240
|
+
"push",
|
|
241
|
+
"-u",
|
|
242
|
+
"origin",
|
|
243
|
+
branch,
|
|
244
|
+
"--force",
|
|
245
|
+
"--no-verify"
|
|
246
|
+
], { cwd: rootDir });
|
|
247
|
+
} catch (err) {
|
|
248
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
249
|
+
throw new Error(msg.replaceAll(token, "***"));
|
|
250
|
+
}
|
|
205
251
|
} finally {
|
|
206
252
|
if (originalUrl) runArgs([
|
|
207
253
|
"git",
|
|
@@ -233,12 +279,13 @@ function pushWithToken(rootDir, branch) {
|
|
|
233
279
|
"-u",
|
|
234
280
|
"origin",
|
|
235
281
|
branch,
|
|
236
|
-
"--force"
|
|
282
|
+
"--force",
|
|
283
|
+
"--no-verify"
|
|
237
284
|
], { cwd: rootDir });
|
|
238
285
|
if (!token && repo) log.warn("BUMPY_GH_TOKEN is not set — PR checks will not trigger automatically.\n Run `bumpy ci setup` for help.");
|
|
239
286
|
}
|
|
240
287
|
}
|
|
241
|
-
async function createVersionPr(rootDir, plan, config, packageDirs, branchName) {
|
|
288
|
+
async function createVersionPr(rootDir, plan, config, packageDirs, branchName, patPr) {
|
|
242
289
|
const branch = validateBranchName(branchName || config.versionPr.branch);
|
|
243
290
|
const baseBranch = validateBranchName(tryRunArgs([
|
|
244
291
|
"git",
|
|
@@ -282,7 +329,7 @@ async function createVersionPr(rootDir, plan, config, packageDirs, branchName) {
|
|
|
282
329
|
branch
|
|
283
330
|
], { cwd: rootDir });
|
|
284
331
|
log.step("Running bumpy version...");
|
|
285
|
-
const { versionCommand } = await import("./version-
|
|
332
|
+
const { versionCommand } = await import("./version-BcfidiVX.mjs");
|
|
286
333
|
await versionCommand(rootDir);
|
|
287
334
|
runArgs([
|
|
288
335
|
"git",
|
|
@@ -309,18 +356,14 @@ async function createVersionPr(rootDir, plan, config, packageDirs, branchName) {
|
|
|
309
356
|
"-"
|
|
310
357
|
], {
|
|
311
358
|
cwd: rootDir,
|
|
312
|
-
input:
|
|
313
|
-
"Version packages",
|
|
314
|
-
"",
|
|
315
|
-
...plan.releases.map((r) => `${r.name}@${r.newVersion}`)
|
|
316
|
-
].join("\n")
|
|
359
|
+
input: await resolveCommitMessage(config.versionCommitMessage, plan, rootDir)
|
|
317
360
|
});
|
|
318
|
-
pushWithToken(rootDir, branch);
|
|
361
|
+
pushWithToken(rootDir, branch, config);
|
|
319
362
|
const prBody = formatVersionPrBody(plan, config.versionPr.preamble, packageDirs);
|
|
320
363
|
if (existingPr) {
|
|
321
364
|
const validPr = validatePrNumber(existingPr);
|
|
322
365
|
log.step(`Updating existing PR #${validPr}...`);
|
|
323
|
-
await runArgsAsync([
|
|
366
|
+
await withPatToken(!!patPr, () => runArgsAsync([
|
|
324
367
|
"gh",
|
|
325
368
|
"pr",
|
|
326
369
|
"edit",
|
|
@@ -332,12 +375,12 @@ async function createVersionPr(rootDir, plan, config, packageDirs, branchName) {
|
|
|
332
375
|
], {
|
|
333
376
|
cwd: rootDir,
|
|
334
377
|
input: prBody
|
|
335
|
-
});
|
|
336
|
-
log.success(
|
|
378
|
+
}));
|
|
379
|
+
log.success(`🐸 Updated PR #${validPr}`);
|
|
337
380
|
} else {
|
|
338
381
|
log.step("Creating version PR...");
|
|
339
382
|
const prTitle = config.versionPr.title;
|
|
340
|
-
const result = await runArgsAsync([
|
|
383
|
+
const result = await withPatToken(!!patPr, () => runArgsAsync([
|
|
341
384
|
"gh",
|
|
342
385
|
"pr",
|
|
343
386
|
"create",
|
|
@@ -352,8 +395,9 @@ async function createVersionPr(rootDir, plan, config, packageDirs, branchName) {
|
|
|
352
395
|
], {
|
|
353
396
|
cwd: rootDir,
|
|
354
397
|
input: prBody
|
|
355
|
-
});
|
|
356
|
-
log.success(
|
|
398
|
+
}));
|
|
399
|
+
log.success(`🐸 Created PR: ${result}`);
|
|
400
|
+
if (!patPr) pushWithToken(rootDir, branch, config);
|
|
357
401
|
}
|
|
358
402
|
runArgs([
|
|
359
403
|
"git",
|
|
@@ -362,7 +406,7 @@ async function createVersionPr(rootDir, plan, config, packageDirs, branchName) {
|
|
|
362
406
|
], { cwd: rootDir });
|
|
363
407
|
}
|
|
364
408
|
const FROG_IMG_BASE = "https://raw.githubusercontent.com/dmno-dev/bumpy/main/images";
|
|
365
|
-
function
|
|
409
|
+
function buildAddBumpFileLink(prBranch) {
|
|
366
410
|
if (!prBranch) return null;
|
|
367
411
|
const repo = process.env.GITHUB_REPOSITORY;
|
|
368
412
|
if (!repo) return null;
|
|
@@ -383,11 +427,11 @@ function pmRunCommand(pm) {
|
|
|
383
427
|
if (pm === "yarn") return "yarn bumpy";
|
|
384
428
|
return "npx bumpy";
|
|
385
429
|
}
|
|
386
|
-
function formatReleasePlanComment(plan,
|
|
430
|
+
function formatReleasePlanComment(plan, bumpFiles, prNumber, prBranch, pm, warnings = []) {
|
|
387
431
|
const repo = process.env.GITHUB_REPOSITORY;
|
|
388
432
|
const lines = [];
|
|
389
433
|
const preamble = [
|
|
390
|
-
`<a href="https://
|
|
434
|
+
`<a href="https://bumpy.varlock.dev"><img src="${FROG_IMG_BASE}/frog-talking.png" alt="bumpy-frog" width="60" align="left" style="image-rendering: pixelated;" title="Hi! I'm bumpy!" /></a>`,
|
|
391
435
|
"",
|
|
392
436
|
"**The changes in this PR will be included in the next version bump.**",
|
|
393
437
|
"<br clear=\"left\" />"
|
|
@@ -415,10 +459,10 @@ function formatReleasePlanComment(plan, changesets, prNumber, prBranch, pm) {
|
|
|
415
459
|
}
|
|
416
460
|
lines.push("");
|
|
417
461
|
}
|
|
418
|
-
lines.push(`####
|
|
462
|
+
lines.push(`#### Bump files in this PR`);
|
|
419
463
|
lines.push("");
|
|
420
|
-
for (const
|
|
421
|
-
const filename = `${
|
|
464
|
+
for (const bf of bumpFiles) {
|
|
465
|
+
const filename = `${bf.id}.md`;
|
|
422
466
|
const parts = [`\`${filename}\``];
|
|
423
467
|
if (repo) {
|
|
424
468
|
parts.push(`([view diff](https://github.com/${repo}/pull/${prNumber}/files#diff-.bumpy/${filename}))`);
|
|
@@ -427,32 +471,38 @@ function formatReleasePlanComment(plan, changesets, prNumber, prBranch, pm) {
|
|
|
427
471
|
lines.push(`- ${parts.join(" ")}`);
|
|
428
472
|
}
|
|
429
473
|
lines.push("");
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
474
|
+
if (warnings.length > 0) {
|
|
475
|
+
lines.push("#### Warnings");
|
|
476
|
+
lines.push("");
|
|
477
|
+
for (const w of warnings) lines.push(`> ⚠️ ${w}`);
|
|
478
|
+
lines.push("");
|
|
479
|
+
}
|
|
480
|
+
const addLink = buildAddBumpFileLink(prBranch);
|
|
481
|
+
if (addLink) lines.push(`[Click here if you want to add another bump file to this PR](${addLink})\n`);
|
|
482
|
+
else lines.push(`To add another bump file, run \`${pmRunCommand(pm)} add\`\n`);
|
|
433
483
|
lines.push("---");
|
|
434
|
-
lines.push(`_This comment is maintained by [bumpy](https://
|
|
484
|
+
lines.push(`_This comment is maintained by [bumpy](https://bumpy.varlock.dev)._`);
|
|
435
485
|
return lines.join("\n");
|
|
436
486
|
}
|
|
437
|
-
function
|
|
487
|
+
function formatNoBumpFilesComment(prBranch, pm) {
|
|
438
488
|
const runCmd = pmRunCommand(pm);
|
|
439
489
|
const lines = [
|
|
440
|
-
`<a href="https://
|
|
490
|
+
`<a href="https://bumpy.varlock.dev"><img src="${FROG_IMG_BASE}/frog-neutral.png" alt="bumpy-frog" width="60" align="left" style="image-rendering: pixelated;" title="Hi! I'm bumpy!" /></a>`,
|
|
441
491
|
"",
|
|
442
|
-
"Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. **If these changes should result in a version bump, you need to add a
|
|
492
|
+
"Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. **If these changes should result in a version bump, you need to add a bump file.**",
|
|
443
493
|
"<br clear=\"left\" />\n",
|
|
444
|
-
"You can add a
|
|
494
|
+
"You can add a bump file by running:\n",
|
|
445
495
|
"```bash",
|
|
446
496
|
`${runCmd} add`,
|
|
447
497
|
"```"
|
|
448
498
|
];
|
|
449
|
-
const addLink =
|
|
499
|
+
const addLink = buildAddBumpFileLink(prBranch);
|
|
450
500
|
if (addLink) {
|
|
451
501
|
lines.push("");
|
|
452
|
-
lines.push(`Or [click here to add a
|
|
502
|
+
lines.push(`Or [click here to add a bump file](${addLink}) directly on GitHub.`);
|
|
453
503
|
}
|
|
454
504
|
lines.push("\n---");
|
|
455
|
-
lines.push(`_This comment is maintained by [bumpy](https://
|
|
505
|
+
lines.push(`_This comment is maintained by [bumpy](https://bumpy.varlock.dev)._`);
|
|
456
506
|
return lines.join("\n");
|
|
457
507
|
}
|
|
458
508
|
function bumpSectionHeader(type) {
|
|
@@ -465,10 +515,7 @@ function buildDiffLinks(pkgDir) {
|
|
|
465
515
|
return ` <sub>${[`[package.json](#diff-${sha256Hex(pkgJsonPath)})`, `[CHANGELOG.md](#diff-${sha256Hex(changelogPath)})`].join(" · ")}</sub>`;
|
|
466
516
|
}
|
|
467
517
|
function sha256Hex(input) {
|
|
468
|
-
|
|
469
|
-
const hasher = new Bun.CryptoHasher("sha256");
|
|
470
|
-
hasher.update(encoder.encode(input));
|
|
471
|
-
return hasher.digest("hex");
|
|
518
|
+
return createHash("sha256").update(input).digest("hex");
|
|
472
519
|
}
|
|
473
520
|
function formatVersionPrBody(plan, preamble, packageDirs) {
|
|
474
521
|
const lines = [];
|
|
@@ -495,12 +542,12 @@ function formatVersionPrBody(plan, preamble, packageDirs) {
|
|
|
495
542
|
const diffLinks = pkgDir ? buildDiffLinks(pkgDir) : "";
|
|
496
543
|
lines.push(`#### \`${r.name}\` ${r.oldVersion} → **${r.newVersion}**${suffix}${diffLinks}`);
|
|
497
544
|
lines.push("");
|
|
498
|
-
const
|
|
499
|
-
if (
|
|
500
|
-
for (const
|
|
501
|
-
const
|
|
502
|
-
const summaryLines =
|
|
503
|
-
lines.push(`- ${summaryLines[0]}${
|
|
545
|
+
const relevantBumpFiles = plan.bumpFiles.filter((bf) => r.bumpFiles.includes(bf.id));
|
|
546
|
+
if (relevantBumpFiles.length > 0) {
|
|
547
|
+
for (const bf of relevantBumpFiles) if (bf.summary) {
|
|
548
|
+
const bfLink = ` ([bump file](#diff-${sha256Hex(`.bumpy/${bf.id}.md`)}))`;
|
|
549
|
+
const summaryLines = bf.summary.split("\n");
|
|
550
|
+
lines.push(`- ${summaryLines[0]}${bfLink}`);
|
|
504
551
|
for (let i = 1; i < summaryLines.length; i++) if (summaryLines[i].trim()) lines.push(` ${summaryLines[i]}`);
|
|
505
552
|
}
|
|
506
553
|
} else if (r.isDependencyBump) lines.push("- Updated dependencies");
|
|
@@ -511,7 +558,7 @@ function formatVersionPrBody(plan, preamble, packageDirs) {
|
|
|
511
558
|
return lines.join("\n");
|
|
512
559
|
}
|
|
513
560
|
const COMMENT_MARKER = "<!-- bumpy-release-plan -->";
|
|
514
|
-
async function postOrUpdatePrComment(prNumber, body, rootDir) {
|
|
561
|
+
async function postOrUpdatePrComment(prNumber, body, rootDir, usePat = false) {
|
|
515
562
|
const validPr = validatePrNumber(prNumber);
|
|
516
563
|
const markedBody = `${COMMENT_MARKER}\n${body}`;
|
|
517
564
|
try {
|
|
@@ -526,7 +573,7 @@ async function postOrUpdatePrComment(prNumber, body, rootDir) {
|
|
|
526
573
|
`.comments[] | select(.body | startswith("${COMMENT_MARKER}")) | .url | capture("issuecomment-(?<id>[0-9]+)$") | .id`
|
|
527
574
|
], { cwd: rootDir })?.split("\n")[0]?.trim();
|
|
528
575
|
if (commentId) {
|
|
529
|
-
await runArgsAsync([
|
|
576
|
+
await withPatToken(usePat, () => runArgsAsync([
|
|
530
577
|
"gh",
|
|
531
578
|
"api",
|
|
532
579
|
`repos/{owner}/{repo}/issues/comments/${commentId}`,
|
|
@@ -537,10 +584,10 @@ async function postOrUpdatePrComment(prNumber, body, rootDir) {
|
|
|
537
584
|
], {
|
|
538
585
|
cwd: rootDir,
|
|
539
586
|
input: markedBody
|
|
540
|
-
});
|
|
587
|
+
}));
|
|
541
588
|
log.dim(" Updated PR comment");
|
|
542
589
|
} else {
|
|
543
|
-
await runArgsAsync([
|
|
590
|
+
await withPatToken(usePat, () => runArgsAsync([
|
|
544
591
|
"gh",
|
|
545
592
|
"pr",
|
|
546
593
|
"comment",
|
|
@@ -550,7 +597,7 @@ async function postOrUpdatePrComment(prNumber, body, rootDir) {
|
|
|
550
597
|
], {
|
|
551
598
|
cwd: rootDir,
|
|
552
599
|
input: markedBody
|
|
553
|
-
});
|
|
600
|
+
}));
|
|
554
601
|
log.dim(" Posted PR comment");
|
|
555
602
|
}
|
|
556
603
|
} catch (err) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { n as log, o as __toESM, r as require_picocolors } from "./logger-C2dEe5Su.mjs";
|
|
2
|
-
import { t as detectPackageManager } from "./package-manager-
|
|
3
|
-
import {
|
|
4
|
-
import { a as fe, c as ot, i as _t, n as O, o as gt, r as Ot, s as mt, t as unwrap, u as wt } from "./clack-
|
|
2
|
+
import { t as detectPackageManager } from "./package-manager-Clsmr-9r.mjs";
|
|
3
|
+
import { s as tryRunArgs } from "./shell-CY7OD48z.mjs";
|
|
4
|
+
import { a as fe, c as ot, i as _t, n as O, o as gt, r as Ot, s as mt, t as unwrap, u as wt } from "./clack-C6bVkGxf.mjs";
|
|
5
5
|
//#region src/commands/ci-setup.ts
|
|
6
6
|
var import_picocolors = /* @__PURE__ */ __toESM(require_picocolors(), 1);
|
|
7
7
|
const PAT_PERMISSIONS = [
|
package/dist/cli.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { n as log, t as colorize } from "./logger-C2dEe5Su.mjs";
|
|
3
|
-
import { n as findRoot } from "./config-
|
|
3
|
+
import { n as findRoot } from "./config-B-Qg3DZH.mjs";
|
|
4
4
|
//#region src/cli.ts
|
|
5
5
|
const args = process.argv.slice(2);
|
|
6
6
|
const command = args[0];
|
|
@@ -25,13 +25,13 @@ async function main() {
|
|
|
25
25
|
switch (command) {
|
|
26
26
|
case "init": {
|
|
27
27
|
const rootDir = await findRoot();
|
|
28
|
-
const { initCommand } = await import("./init-
|
|
29
|
-
await initCommand(rootDir);
|
|
28
|
+
const { initCommand } = await import("./init-DkTPs_WQ.mjs");
|
|
29
|
+
await initCommand(rootDir, { force: flags.force === true });
|
|
30
30
|
break;
|
|
31
31
|
}
|
|
32
32
|
case "add": {
|
|
33
33
|
const rootDir = await findRoot();
|
|
34
|
-
const { addCommand } = await import("./add-
|
|
34
|
+
const { addCommand } = await import("./add-BmNL5VwL.mjs");
|
|
35
35
|
await addCommand(rootDir, {
|
|
36
36
|
packages: flags.packages,
|
|
37
37
|
message: flags.message,
|
|
@@ -42,7 +42,7 @@ async function main() {
|
|
|
42
42
|
}
|
|
43
43
|
case "status": {
|
|
44
44
|
const rootDir = await findRoot();
|
|
45
|
-
const { statusCommand } = await import("./status
|
|
45
|
+
const { statusCommand } = await import("./status-EGYqULJg.mjs");
|
|
46
46
|
await statusCommand(rootDir, {
|
|
47
47
|
json: flags.json === true,
|
|
48
48
|
packagesOnly: flags.packages === true,
|
|
@@ -54,13 +54,13 @@ async function main() {
|
|
|
54
54
|
}
|
|
55
55
|
case "version": {
|
|
56
56
|
const rootDir = await findRoot();
|
|
57
|
-
const { versionCommand } = await import("./version-
|
|
58
|
-
await versionCommand(rootDir);
|
|
57
|
+
const { versionCommand } = await import("./version-BcfidiVX.mjs");
|
|
58
|
+
await versionCommand(rootDir, { commit: flags.commit === true });
|
|
59
59
|
break;
|
|
60
60
|
}
|
|
61
61
|
case "generate": {
|
|
62
62
|
const rootDir = await findRoot();
|
|
63
|
-
const { generateCommand } = await import("./generate-
|
|
63
|
+
const { generateCommand } = await import("./generate-DX46X-rW.mjs");
|
|
64
64
|
await generateCommand(rootDir, {
|
|
65
65
|
from: flags.from,
|
|
66
66
|
dryRun: flags["dry-run"] === true,
|
|
@@ -68,15 +68,9 @@ async function main() {
|
|
|
68
68
|
});
|
|
69
69
|
break;
|
|
70
70
|
}
|
|
71
|
-
case "migrate": {
|
|
72
|
-
const rootDir = await findRoot();
|
|
73
|
-
const { migrateCommand } = await import("./migrate-CfQNwD0T.mjs");
|
|
74
|
-
await migrateCommand(rootDir, { force: flags.force === true });
|
|
75
|
-
break;
|
|
76
|
-
}
|
|
77
71
|
case "check": {
|
|
78
72
|
const rootDir = await findRoot();
|
|
79
|
-
const { checkCommand } = await import("./check-
|
|
73
|
+
const { checkCommand } = await import("./check-BjWF6SJm.mjs");
|
|
80
74
|
await checkCommand(rootDir);
|
|
81
75
|
break;
|
|
82
76
|
}
|
|
@@ -85,20 +79,22 @@ async function main() {
|
|
|
85
79
|
const subcommand = args[1];
|
|
86
80
|
const ciFlags = parseFlags(args.slice(2));
|
|
87
81
|
if (subcommand === "check") {
|
|
88
|
-
const { ciCheckCommand } = await import("./ci-
|
|
82
|
+
const { ciCheckCommand } = await import("./ci-DY58ugIi.mjs");
|
|
89
83
|
await ciCheckCommand(rootDir, {
|
|
90
84
|
comment: ciFlags.comment !== void 0 ? ciFlags.comment === true : void 0,
|
|
91
|
-
failOnMissing: ciFlags["fail-on-missing"] === true
|
|
85
|
+
failOnMissing: ciFlags["fail-on-missing"] === true,
|
|
86
|
+
patComments: ciFlags["pat-comments"] === true
|
|
92
87
|
});
|
|
93
88
|
} else if (subcommand === "release") {
|
|
94
|
-
const { ciReleaseCommand } = await import("./ci-
|
|
89
|
+
const { ciReleaseCommand } = await import("./ci-DY58ugIi.mjs");
|
|
95
90
|
await ciReleaseCommand(rootDir, {
|
|
96
91
|
mode: ciFlags["auto-publish"] === true ? "auto-publish" : "version-pr",
|
|
97
92
|
tag: ciFlags.tag,
|
|
98
|
-
branch: ciFlags.branch
|
|
93
|
+
branch: ciFlags.branch,
|
|
94
|
+
patPr: ciFlags["pat-pr"] === true
|
|
99
95
|
});
|
|
100
96
|
} else if (subcommand === "setup") {
|
|
101
|
-
const { ciSetupCommand } = await import("./ci-setup-
|
|
97
|
+
const { ciSetupCommand } = await import("./ci-setup-BQwktQEe.mjs");
|
|
102
98
|
await ciSetupCommand(rootDir);
|
|
103
99
|
} else {
|
|
104
100
|
log.error(`Unknown ci subcommand: ${subcommand}. Use "ci check", "ci release", or "ci setup".`);
|
|
@@ -108,7 +104,7 @@ async function main() {
|
|
|
108
104
|
}
|
|
109
105
|
case "publish": {
|
|
110
106
|
const rootDir = await findRoot();
|
|
111
|
-
const { publishCommand } = await import("./publish-
|
|
107
|
+
const { publishCommand } = await import("./publish-CGB4TIKD.mjs");
|
|
112
108
|
await publishCommand(rootDir, {
|
|
113
109
|
dryRun: flags["dry-run"] === true,
|
|
114
110
|
tag: flags.tag,
|
|
@@ -122,7 +118,7 @@ async function main() {
|
|
|
122
118
|
const subcommand = args[1];
|
|
123
119
|
const aiFlags = parseFlags(args.slice(2));
|
|
124
120
|
if (subcommand === "setup") {
|
|
125
|
-
const { aiSetupCommand } = await import("./ai-
|
|
121
|
+
const { aiSetupCommand } = await import("./ai-sMYUf3lP.mjs");
|
|
126
122
|
await aiSetupCommand(rootDir, { target: aiFlags.target });
|
|
127
123
|
} else {
|
|
128
124
|
log.error(`Unknown ai subcommand: ${subcommand}. Use "ai setup".`);
|
|
@@ -132,7 +128,7 @@ async function main() {
|
|
|
132
128
|
}
|
|
133
129
|
case "--version":
|
|
134
130
|
case "-v":
|
|
135
|
-
console.log(`bumpy
|
|
131
|
+
console.log(`bumpy 1.1.0`);
|
|
136
132
|
break;
|
|
137
133
|
case "help":
|
|
138
134
|
case "--help":
|
|
@@ -152,41 +148,40 @@ async function main() {
|
|
|
152
148
|
}
|
|
153
149
|
function printHelp() {
|
|
154
150
|
console.log(`
|
|
155
|
-
${colorize(`🐸 bumpy
|
|
151
|
+
${colorize(`🐸 bumpy v1.1.0`, "bold")} - Modern monorepo versioning
|
|
156
152
|
|
|
157
153
|
Usage: bumpy <command> [options]
|
|
158
154
|
|
|
159
155
|
Commands:
|
|
160
|
-
init
|
|
161
|
-
add Create a new
|
|
162
|
-
generate Generate
|
|
156
|
+
init [--force] Initialize .bumpy/ (migrates from .changeset/ if found)
|
|
157
|
+
add Create a new bump file
|
|
158
|
+
generate Generate bump file from branch commits
|
|
163
159
|
status Show pending releases
|
|
164
|
-
check Verify changed packages have
|
|
165
|
-
version
|
|
160
|
+
check Verify changed packages have bump files (for pre-push hooks)
|
|
161
|
+
version [--commit] Apply bump files and bump versions
|
|
166
162
|
publish Publish versioned packages
|
|
167
163
|
ci check PR check — report pending releases, comment on PR
|
|
168
164
|
ci release Release — create version PR or auto-publish
|
|
169
165
|
ci setup Set up a token for triggering CI on version PRs
|
|
170
|
-
|
|
171
|
-
ai setup Install AI skill for creating changesets
|
|
166
|
+
ai setup Install AI skill for creating bump files
|
|
172
167
|
|
|
173
168
|
Add options:
|
|
174
169
|
--packages <list> Package bumps (e.g., "pkg-a:minor,pkg-b:patch")
|
|
175
|
-
--message <text>
|
|
176
|
-
--name <name>
|
|
177
|
-
--empty Create an empty
|
|
170
|
+
--message <text> Bump file summary
|
|
171
|
+
--name <name> Bump file filename
|
|
172
|
+
--empty Create an empty bump file
|
|
178
173
|
|
|
179
174
|
Generate options:
|
|
180
|
-
--from <ref> Git ref to scan from (default:
|
|
181
|
-
--dry-run Preview without creating a
|
|
182
|
-
--name <name>
|
|
175
|
+
--from <ref> Git ref to scan from (default: branch point from baseBranch)
|
|
176
|
+
--dry-run Preview without creating a bump file
|
|
177
|
+
--name <name> Bump file filename
|
|
183
178
|
|
|
184
179
|
Status options:
|
|
185
|
-
--json Output as JSON (includes dirs,
|
|
180
|
+
--json Output as JSON (includes dirs, bumpFiles, packageNames)
|
|
186
181
|
--packages Output only package names, one per line
|
|
187
182
|
--bump <types> Filter by bump type (e.g., "major", "minor,patch")
|
|
188
183
|
--filter <names> Filter by package name/glob (e.g., "@myorg/*")
|
|
189
|
-
--verbose Show
|
|
184
|
+
--verbose Show bump file details
|
|
190
185
|
|
|
191
186
|
Publish options:
|
|
192
187
|
--dry-run Preview without publishing
|
|
@@ -196,7 +191,7 @@ function printHelp() {
|
|
|
196
191
|
|
|
197
192
|
CI check options:
|
|
198
193
|
--comment Force PR comment on/off (auto-detected in CI)
|
|
199
|
-
--fail-on-missing Exit 1 if no
|
|
194
|
+
--fail-on-missing Exit 1 if no bump files found
|
|
200
195
|
|
|
201
196
|
CI release options:
|
|
202
197
|
--auto-publish Version + publish directly (default: create version PR)
|
|
@@ -206,7 +201,7 @@ function printHelp() {
|
|
|
206
201
|
AI setup options:
|
|
207
202
|
--target <tool> Target AI tool: opencode, cursor, codex
|
|
208
203
|
|
|
209
|
-
${colorize("https://
|
|
204
|
+
${colorize("https://bumpy.varlock.dev", "dim")}
|
|
210
205
|
`);
|
|
211
206
|
}
|
|
212
207
|
main();
|