@varlock/bumpy 0.0.2 → 1.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.
Files changed (32) hide show
  1. package/.claude-plugin/plugin.json +2 -2
  2. package/dist/add-CgCjs4d-.mjs +313 -0
  3. package/dist/{ai-CQhUyHAG.mjs → ai-sMYUf3lP.mjs} +21 -4
  4. package/dist/{apply-release-plan-D6TSrcwX.mjs → apply-release-plan-CczGWJTk.mjs} +28 -24
  5. package/dist/bump-file-CCLXMLA8.mjs +143 -0
  6. package/dist/{changelog-github-Du62krXi.mjs → changelog-github-Cd8uJHZI.mjs} +22 -20
  7. package/dist/{check-jIwike9F.mjs → check-BOoxpWqk.mjs} +9 -9
  8. package/dist/{ci-D6LQbR38.mjs → ci-Bhx--Tj6.mjs} +116 -72
  9. package/dist/{ci-setup-C6FlOfW5.mjs → ci-setup-qz4Y3v7T.mjs} +1 -1
  10. package/dist/cli.mjs +32 -30
  11. package/dist/{config-BkwIEaQg.mjs → config-XZWUL3ma.mjs} +27 -22
  12. package/dist/fs-DYR2XuFE.mjs +81 -0
  13. package/dist/{generate-Btrsn1qi.mjs → generate-gYKTpvex.mjs} +8 -8
  14. package/dist/index.d.mts +55 -37
  15. package/dist/index.mjs +8 -8
  16. package/dist/{init-B0q3wEQW.mjs → init-lA9E5pEc.mjs} +2 -2
  17. package/dist/{migrate-CfQNwD0T.mjs → migrate-DmOYgmfD.mjs} +10 -10
  18. package/dist/{names-Ck8cun7B.mjs → names-9VubBmL0.mjs} +1 -1
  19. package/dist/{package-manager-DcI5TdDE.mjs → package-manager-VCe10bjc.mjs} +1 -1
  20. package/dist/{publish-D_7RqEYL.mjs → publish-Cun-zQ1b.mjs} +21 -20
  21. package/dist/{publish-pipeline-ChnqW8nR.mjs → publish-pipeline-BwBuKCIk.mjs} +22 -17
  22. package/dist/release-plan-Bi5QNSEo.mjs +264 -0
  23. package/dist/{semver-BTzYh8vc.mjs → semver-DfQyVLM_.mjs} +13 -3
  24. package/dist/{status--Q8yAxQ4.mjs → status-CfE63ti5.mjs} +25 -21
  25. package/dist/{version-cAUkfYPx.mjs → version-19vVt9dv.mjs} +16 -12
  26. package/dist/{workspace-CxEKakDm.mjs → workspace-C5ULTyUN.mjs} +3 -3
  27. package/package.json +13 -1
  28. package/skills/add-change/SKILL.md +8 -12
  29. package/dist/add-BjyVIUlr.mjs +0 -175
  30. package/dist/changeset-UCZdSRDv.mjs +0 -108
  31. package/dist/fs-0AtnPUUe.mjs +0 -51
  32. package/dist/release-plan-BEzwApuK.mjs +0 -173
@@ -7,12 +7,14 @@ import { o as tryRunArgs } from "./shell-Dj7JRD_q.mjs";
7
7
  * Usage in config:
8
8
  * "changelog": "github"
9
9
  * "changelog": ["github", { "repo": "dmno-dev/bumpy" }]
10
- * "changelog": ["github", { "repo": "dmno-dev/bumpy", "internalAuthors": ["theoephraim"] }]
10
+ * "changelog": ["github", { "thankContributors": false }]
11
+ * "changelog": ["github", { "internalAuthors": ["theoephraim"] }]
11
12
  */
12
13
  function createGithubFormatter(options = {}) {
14
+ const thankContributors = options.thankContributors ?? true;
13
15
  const internalAuthorsSet = new Set((options.internalAuthors ?? []).map((a) => a.toLowerCase()));
14
16
  return async (ctx) => {
15
- const { release, changesets, date } = ctx;
17
+ const { release, bumpFiles, date } = ctx;
16
18
  const repoSlug = options.repo ?? detectRepo();
17
19
  const serverUrl = process.env.GITHUB_SERVER_URL || "https://github.com";
18
20
  const lines = [];
@@ -20,25 +22,25 @@ function createGithubFormatter(options = {}) {
20
22
  lines.push("");
21
23
  lines.push(`_${date}_`);
22
24
  lines.push("");
23
- const relevantChangesets = changesets.filter((cs) => release.changesets.includes(cs.id));
24
- if (relevantChangesets.length > 0) for (const cs of relevantChangesets) {
25
- if (!cs.summary) continue;
26
- const { cleanSummary, overrides } = extractSummaryMeta(cs.summary);
27
- const gitInfo = resolveChangesetInfo(cs.id, repoSlug, serverUrl, overrides);
25
+ const relevantBumpFiles = bumpFiles.filter((bf) => release.bumpFiles.includes(bf.id));
26
+ if (relevantBumpFiles.length > 0) for (const bf of relevantBumpFiles) {
27
+ if (!bf.summary) continue;
28
+ const { cleanSummary, overrides } = extractSummaryMeta(bf.summary);
29
+ const gitInfo = resolveBumpFileInfo(bf.id, repoSlug, serverUrl, overrides);
28
30
  const summaryLines = cleanSummary.split("\n");
29
31
  const firstLine = linkifyIssueRefs(summaryLines[0], serverUrl, repoSlug);
30
- const prefix = formatPrefix(gitInfo, serverUrl, repoSlug, internalAuthorsSet);
32
+ const prefix = formatPrefix(gitInfo, serverUrl, repoSlug, thankContributors, internalAuthorsSet);
31
33
  lines.push(`-${prefix ? ` ${prefix} -` : ""} ${firstLine}`);
32
34
  for (let i = 1; i < summaryLines.length; i++) if (summaryLines[i].trim()) lines.push(` ${linkifyIssueRefs(summaryLines[i], serverUrl, repoSlug)}`);
33
35
  }
34
- if (release.isDependencyBump && relevantChangesets.length === 0) lines.push("- Updated dependencies");
35
- if (release.isCascadeBump && !release.isDependencyBump && relevantChangesets.length === 0) lines.push("- Version bump via cascade rule");
36
+ if (release.isDependencyBump && relevantBumpFiles.length === 0) lines.push("- Updated dependencies");
37
+ if (release.isCascadeBump && !release.isDependencyBump && relevantBumpFiles.length === 0) lines.push("- Version bump via cascade rule");
36
38
  lines.push("");
37
39
  return lines.join("\n");
38
40
  };
39
41
  }
40
42
  /**
41
- * Extract metadata lines (pr, commit, author) from a changeset summary.
43
+ * Extract metadata lines (pr, commit, author) from a bump file summary.
42
44
  * These override git-derived info, matching the behavior of @changesets/changelog-github.
43
45
  */
44
46
  function extractSummaryMeta(summary) {
@@ -60,10 +62,10 @@ function extractSummaryMeta(summary) {
60
62
  };
61
63
  }
62
64
  /**
63
- * Resolve PR, commit, and author info for a changeset.
65
+ * Resolve PR, commit, and author info for a bump file.
64
66
  * Summary overrides take precedence over git-derived info.
65
67
  */
66
- function resolveChangesetInfo(changesetId, repo, serverUrl, overrides) {
68
+ function resolveBumpFileInfo(bumpFileId, repo, serverUrl, overrides) {
67
69
  if (overrides.pr !== void 0) {
68
70
  const prInfo = lookupPr(overrides.pr, repo);
69
71
  return {
@@ -73,7 +75,7 @@ function resolveChangesetInfo(changesetId, repo, serverUrl, overrides) {
73
75
  author: overrides.authors?.[0] ?? prInfo?.author
74
76
  };
75
77
  }
76
- const gitInfo = findChangesetCommitInfo(changesetId, repo);
78
+ const gitInfo = findBumpFileCommitInfo(bumpFileId, repo);
77
79
  return {
78
80
  prNumber: gitInfo?.prNumber,
79
81
  prUrl: gitInfo?.prUrl,
@@ -106,10 +108,10 @@ function lookupPr(prNumber, repo) {
106
108
  }
107
109
  }
108
110
  /**
109
- * Find the PR that introduced a changeset file by checking git log
111
+ * Find the PR that introduced a bump file by checking git log
110
112
  * for the commit that added the file, then looking up the PR.
111
113
  */
112
- function findChangesetCommitInfo(changesetId, repo) {
114
+ function findBumpFileCommitInfo(bumpFileId, repo) {
113
115
  try {
114
116
  const commitOutput = tryRunArgs([
115
117
  "git",
@@ -117,8 +119,8 @@ function findChangesetCommitInfo(changesetId, repo) {
117
119
  "--diff-filter=A",
118
120
  "--format=%H",
119
121
  "--",
120
- `.bumpy/${changesetId}.md`,
121
- `.changeset/${changesetId}.md`
122
+ `.bumpy/${bumpFileId}.md`,
123
+ `.changeset/${bumpFileId}.md`
122
124
  ]);
123
125
  if (!commitOutput) return null;
124
126
  const commitHash = commitOutput.split("\n")[0].trim();
@@ -155,14 +157,14 @@ function findChangesetCommitInfo(changesetId, repo) {
155
157
  * Build the prefix portion of a changelog line: PR link, commit link, thanks.
156
158
  * Matches the format used by @changesets/changelog-github.
157
159
  */
158
- function formatPrefix(info, serverUrl, repo, internalAuthors) {
160
+ function formatPrefix(info, serverUrl, repo, thankContributors, internalAuthors) {
159
161
  const parts = [];
160
162
  if (info.prNumber && info.prUrl) parts.push(`[#${info.prNumber}](${info.prUrl})`);
161
163
  if (info.commitHash && repo) {
162
164
  const short = info.commitHash.slice(0, 7);
163
165
  parts.push(`[\`${short}\`](${serverUrl}/${repo}/commit/${info.commitHash})`);
164
166
  }
165
- if (info.author && !internalAuthors.has(info.author.toLowerCase())) parts.push(`Thanks [@${info.author}](${serverUrl}/${info.author})!`);
167
+ if (thankContributors && info.author && !internalAuthors.has(info.author.toLowerCase())) parts.push(`Thanks [@${info.author}](${serverUrl}/${info.author})!`);
166
168
  return parts.join(" ");
167
169
  }
168
170
  /**
@@ -1,21 +1,21 @@
1
1
  import { n as log, t as colorize } from "./logger-C2dEe5Su.mjs";
2
- import { a as loadConfig } from "./config-BkwIEaQg.mjs";
3
- import { n as discoverWorkspace } from "./workspace-CxEKakDm.mjs";
4
- import { r as readChangesets } from "./changeset-UCZdSRDv.mjs";
2
+ import { a as loadConfig } from "./config-XZWUL3ma.mjs";
3
+ import { n as discoverWorkspace } from "./workspace-C5ULTyUN.mjs";
4
+ import { r as readBumpFiles } from "./bump-file-CCLXMLA8.mjs";
5
5
  import { n as getChangedFiles } from "./git-CGHVXXKw.mjs";
6
6
  import { relative } from "node:path";
7
7
  //#region src/commands/check.ts
8
8
  /**
9
9
  * Local check: detect which packages have changed on this branch
10
- * and verify they have corresponding changesets.
10
+ * and verify they have corresponding bump files.
11
11
  * Designed for pre-push hooks — no GitHub API needed.
12
12
  */
13
13
  async function checkCommand(rootDir) {
14
14
  const config = await loadConfig(rootDir);
15
15
  const { packages } = await discoverWorkspace(rootDir, config);
16
- const changesets = await readChangesets(rootDir);
16
+ const bumpFiles = await readBumpFiles(rootDir);
17
17
  const coveredPackages = /* @__PURE__ */ new Set();
18
- for (const cs of changesets) for (const release of cs.releases) coveredPackages.add(release.name);
18
+ for (const bf of bumpFiles) for (const release of bf.releases) coveredPackages.add(release.name);
19
19
  const baseBranch = config.baseBranch;
20
20
  const changedFiles = getChangedFiles(rootDir, baseBranch);
21
21
  if (changedFiles.length === 0) {
@@ -29,13 +29,13 @@ async function checkCommand(rootDir) {
29
29
  }
30
30
  const missing = changedPackages.filter((name) => !coveredPackages.has(name));
31
31
  if (missing.length === 0) {
32
- log.success(`All ${changedPackages.length} changed package(s) have changesets.`);
32
+ log.success(`All ${changedPackages.length} changed package(s) have bump files.`);
33
33
  return;
34
34
  }
35
- log.warn(`${missing.length} changed package(s) missing changesets:\n`);
35
+ log.warn(`${missing.length} changed package(s) missing bump files:\n`);
36
36
  for (const name of missing) console.log(` ${colorize(name, "yellow")}`);
37
37
  console.log();
38
- log.dim("Run `bumpy add` to create a changeset, or `bumpy add --empty` if no release is needed.");
38
+ log.dim("Run `bumpy add` to create a bump file, or `bumpy add --empty` if no release is needed.");
39
39
  process.exit(1);
40
40
  }
41
41
  /** Map changed files to the packages they belong to */
@@ -1,14 +1,41 @@
1
1
  import { n as log, t as colorize } from "./logger-C2dEe5Su.mjs";
2
- import { a as loadConfig } from "./config-BkwIEaQg.mjs";
3
- import { t as detectPackageManager } from "./package-manager-DcI5TdDE.mjs";
4
- import { n as discoverWorkspace } from "./workspace-CxEKakDm.mjs";
2
+ import { a as loadConfig } from "./config-XZWUL3ma.mjs";
3
+ import { t as detectPackageManager } from "./package-manager-VCe10bjc.mjs";
4
+ import { n as discoverWorkspace } from "./workspace-C5ULTyUN.mjs";
5
5
  import { t as DependencyGraph } from "./dep-graph-E-9-eQ2J.mjs";
6
6
  import { n as runArgsAsync, o as tryRunArgs, t as runArgs } from "./shell-Dj7JRD_q.mjs";
7
- import { r as readChangesets } from "./changeset-UCZdSRDv.mjs";
8
- import { t as assembleReleasePlan } from "./release-plan-BEzwApuK.mjs";
7
+ import { r as readBumpFiles } from "./bump-file-CCLXMLA8.mjs";
8
+ import { t as assembleReleasePlan } from "./release-plan-Bi5QNSEo.mjs";
9
9
  import { n as getChangedFiles } from "./git-CGHVXXKw.mjs";
10
- import { t as randomName } from "./names-Ck8cun7B.mjs";
10
+ import { t as randomName } from "./names-9VubBmL0.mjs";
11
+ import { createHash } from "node:crypto";
11
12
  //#region src/commands/ci.ts
13
+ /**
14
+ * Temporarily override GH_TOKEN with BUMPY_GH_TOKEN for a gh CLI call.
15
+ *
16
+ * Use `--pat-pr` / `--pat-comments` flags to opt in. This is useful when
17
+ * BUMPY_GH_TOKEN belongs to a dedicated automation/bot account. If you're
18
+ * using a developer's personal PAT, it's better to leave these flags off so
19
+ * that PRs and comments appear from github-actions[bot] — allowing the
20
+ * developer to still review and approve the PR.
21
+ */
22
+ function requirePatToken() {
23
+ const token = process.env.BUMPY_GH_TOKEN;
24
+ if (!token) throw new Error("BUMPY_GH_TOKEN must be set when using --pat-pr or --pat-comments");
25
+ return token;
26
+ }
27
+ async function withPatToken(usePat, fn) {
28
+ if (!usePat) return fn();
29
+ const token = requirePatToken();
30
+ const originalGhToken = process.env.GH_TOKEN;
31
+ process.env.GH_TOKEN = token;
32
+ try {
33
+ return await fn();
34
+ } finally {
35
+ if (originalGhToken !== void 0) process.env.GH_TOKEN = originalGhToken;
36
+ else delete process.env.GH_TOKEN;
37
+ }
38
+ }
12
39
  /** Validate a git branch name to prevent injection */
13
40
  function validateBranchName(name) {
14
41
  if (!/^[a-zA-Z0-9_./-]+$/.test(name)) throw new Error(`Invalid branch name: ${name}`);
@@ -43,14 +70,14 @@ function ensureGitIdentity(rootDir, config) {
43
70
  }
44
71
  }
45
72
  /**
46
- * CI check: report on pending changesets.
73
+ * CI check: report on pending bump files.
47
74
  * Designed for PR workflows — shows what would be released and optionally comments on the PR.
48
75
  */
49
76
  async function ciCheckCommand(rootDir, opts) {
50
77
  const config = await loadConfig(rootDir);
51
78
  const { packages } = await discoverWorkspace(rootDir, config);
52
79
  const depGraph = new DependencyGraph(packages);
53
- const allChangesets = await readChangesets(rootDir);
80
+ const allBumpFiles = await readBumpFiles(rootDir);
54
81
  if (detectPrBranch(rootDir) === config.versionPr.branch) {
55
82
  log.dim(" Skipping — this is the version PR branch.");
56
83
  return;
@@ -60,21 +87,22 @@ async function ciCheckCommand(rootDir, opts) {
60
87
  const prNumber = detectPrNumber();
61
88
  const pm = await detectPackageManager(rootDir);
62
89
  const changedFiles = getChangedFiles(rootDir, config.baseBranch);
63
- const prChangesetIds = new Set(changedFiles.filter((f) => /^\.bumpy\/.*\.md$/.test(f) && !f.endsWith("README.md")).map((f) => f.replace(/^\.bumpy\//, "").replace(/\.md$/, "")));
64
- const prChangesets = allChangesets.filter((cs) => prChangesetIds.has(cs.id));
65
- if (prChangesets.length === 0) {
66
- log.info("No changesets found in this PR.");
67
- if (shouldComment && prNumber) await postOrUpdatePrComment(prNumber, formatNoChangesetsComment(detectPrBranch(rootDir), pm), rootDir);
90
+ const prBumpFileIds = new Set(changedFiles.filter((f) => /^\.bumpy\/.*\.md$/.test(f) && !f.endsWith("README.md")).map((f) => f.replace(/^\.bumpy\//, "").replace(/\.md$/, "")));
91
+ const prBumpFiles = allBumpFiles.filter((bf) => prBumpFileIds.has(bf.id));
92
+ if (prBumpFiles.length === 0) {
93
+ log.info("No bump files found in this PR.");
94
+ if (shouldComment && prNumber) await postOrUpdatePrComment(prNumber, formatNoBumpFilesComment(detectPrBranch(rootDir), pm), rootDir, opts.patComments);
68
95
  if (opts.failOnMissing) process.exit(1);
69
96
  return;
70
97
  }
71
- const plan = assembleReleasePlan(prChangesets, packages, depGraph, config);
72
- log.bold(`${prChangesets.length} changeset(s) → ${plan.releases.length} package(s) to release\n`);
98
+ const plan = assembleReleasePlan(prBumpFiles, packages, depGraph, config);
99
+ log.bold(`${prBumpFiles.length} bump file(s) → ${plan.releases.length} package(s) to release\n`);
73
100
  for (const r of plan.releases) {
74
101
  const tag = r.isDependencyBump ? " (dep)" : r.isCascadeBump ? " (cascade)" : "";
75
102
  console.log(` ${r.name}: ${r.oldVersion} → ${colorize(r.newVersion, "cyan")}${tag}`);
76
103
  }
77
- if (shouldComment && prNumber) await postOrUpdatePrComment(prNumber, formatReleasePlanComment(plan, prChangesets, prNumber, detectPrBranch(rootDir), pm), rootDir);
104
+ if (plan.warnings.length > 0) for (const w of plan.warnings) log.warn(w);
105
+ if (shouldComment && prNumber) await postOrUpdatePrComment(prNumber, formatReleasePlanComment(plan, prBumpFiles, prNumber, detectPrBranch(rootDir), pm, plan.warnings), rootDir, opts.patComments);
78
106
  }
79
107
  /**
80
108
  * CI release: either auto-publish or create a version PR.
@@ -85,24 +113,24 @@ async function ciReleaseCommand(rootDir, opts) {
85
113
  ensureGitIdentity(rootDir, config);
86
114
  const { packages } = await discoverWorkspace(rootDir, config);
87
115
  const depGraph = new DependencyGraph(packages);
88
- const changesets = await readChangesets(rootDir);
89
- if (changesets.length === 0) {
90
- log.info("No pending changesets — checking for unpublished packages...");
91
- const { publishCommand } = await import("./publish-D_7RqEYL.mjs");
116
+ const bumpFiles = await readBumpFiles(rootDir);
117
+ if (bumpFiles.length === 0) {
118
+ log.info("No pending bump files — checking for unpublished packages...");
119
+ const { publishCommand } = await import("./publish-Cun-zQ1b.mjs");
92
120
  await publishCommand(rootDir, { tag: opts.tag });
93
121
  return;
94
122
  }
95
- const plan = assembleReleasePlan(changesets, packages, depGraph, config);
123
+ const plan = assembleReleasePlan(bumpFiles, packages, depGraph, config);
96
124
  if (plan.releases.length === 0) {
97
- log.info("Changesets found but no packages would be released.");
125
+ log.info("Bump files found but no packages would be released.");
98
126
  return;
99
127
  }
100
128
  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);
129
+ else await createVersionPr(rootDir, plan, config, new Map([...packages.values()].map((p) => [p.name, p.relativeDir])), opts.branch, opts.patPr);
102
130
  }
103
131
  async function autoPublish(rootDir, config, tag) {
104
132
  log.step("Running bumpy version...");
105
- const { versionCommand } = await import("./version-cAUkfYPx.mjs");
133
+ const { versionCommand } = await import("./version-19vVt9dv.mjs");
106
134
  await versionCommand(rootDir);
107
135
  log.step("Committing version changes...");
108
136
  runArgs([
@@ -121,10 +149,14 @@ async function autoPublish(rootDir, config, tag) {
121
149
  "-m",
122
150
  "Version packages"
123
151
  ], { cwd: rootDir });
124
- runArgs(["git", "push"], { cwd: rootDir });
152
+ runArgs([
153
+ "git",
154
+ "push",
155
+ "--no-verify"
156
+ ], { cwd: rootDir });
125
157
  }
126
158
  log.step("Running bumpy publish...");
127
- const { publishCommand } = await import("./publish-D_7RqEYL.mjs");
159
+ const { publishCommand } = await import("./publish-Cun-zQ1b.mjs");
128
160
  await publishCommand(rootDir, { tag });
129
161
  }
130
162
  /**
@@ -138,7 +170,8 @@ async function autoPublish(rootDir, config, tag) {
138
170
  * When only the default `GITHUB_TOKEN` is available the push still succeeds,
139
171
  * but PR workflows won't be triggered automatically.
140
172
  */
141
- function pushWithToken(rootDir, branch) {
173
+ function pushWithToken(rootDir, branch, config) {
174
+ 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
175
  const token = process.env.BUMPY_GH_TOKEN;
143
176
  const repo = process.env.GITHUB_REPOSITORY;
144
177
  const server = process.env.GITHUB_SERVER_URL || "https://github.com";
@@ -162,7 +195,7 @@ function pushWithToken(rootDir, branch) {
162
195
  "config",
163
196
  "--local",
164
197
  "--get-regexp",
165
- "^includeIf\\.gitdir:"
198
+ "^includeif\\.gitdir:"
166
199
  ], { cwd: rootDir });
167
200
  const savedIncludeIfs = [];
168
201
  if (includeIfRaw) for (const line of includeIfRaw.split("\n").filter(Boolean)) {
@@ -194,14 +227,20 @@ function pushWithToken(rootDir, branch) {
194
227
  "origin",
195
228
  authedUrl
196
229
  ], { cwd: rootDir });
197
- runArgs([
198
- "git",
199
- "push",
200
- "-u",
201
- "origin",
202
- branch,
203
- "--force"
204
- ], { cwd: rootDir });
230
+ try {
231
+ runArgs([
232
+ "git",
233
+ "push",
234
+ "-u",
235
+ "origin",
236
+ branch,
237
+ "--force",
238
+ "--no-verify"
239
+ ], { cwd: rootDir });
240
+ } catch (err) {
241
+ const msg = err instanceof Error ? err.message : String(err);
242
+ throw new Error(msg.replaceAll(token, "***"));
243
+ }
205
244
  } finally {
206
245
  if (originalUrl) runArgs([
207
246
  "git",
@@ -233,12 +272,13 @@ function pushWithToken(rootDir, branch) {
233
272
  "-u",
234
273
  "origin",
235
274
  branch,
236
- "--force"
275
+ "--force",
276
+ "--no-verify"
237
277
  ], { cwd: rootDir });
238
278
  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
279
  }
240
280
  }
241
- async function createVersionPr(rootDir, plan, config, packageDirs, branchName) {
281
+ async function createVersionPr(rootDir, plan, config, packageDirs, branchName, patPr) {
242
282
  const branch = validateBranchName(branchName || config.versionPr.branch);
243
283
  const baseBranch = validateBranchName(tryRunArgs([
244
284
  "git",
@@ -282,7 +322,7 @@ async function createVersionPr(rootDir, plan, config, packageDirs, branchName) {
282
322
  branch
283
323
  ], { cwd: rootDir });
284
324
  log.step("Running bumpy version...");
285
- const { versionCommand } = await import("./version-cAUkfYPx.mjs");
325
+ const { versionCommand } = await import("./version-19vVt9dv.mjs");
286
326
  await versionCommand(rootDir);
287
327
  runArgs([
288
328
  "git",
@@ -315,12 +355,12 @@ async function createVersionPr(rootDir, plan, config, packageDirs, branchName) {
315
355
  ...plan.releases.map((r) => `${r.name}@${r.newVersion}`)
316
356
  ].join("\n")
317
357
  });
318
- pushWithToken(rootDir, branch);
358
+ pushWithToken(rootDir, branch, config);
319
359
  const prBody = formatVersionPrBody(plan, config.versionPr.preamble, packageDirs);
320
360
  if (existingPr) {
321
361
  const validPr = validatePrNumber(existingPr);
322
362
  log.step(`Updating existing PR #${validPr}...`);
323
- await runArgsAsync([
363
+ await withPatToken(!!patPr, () => runArgsAsync([
324
364
  "gh",
325
365
  "pr",
326
366
  "edit",
@@ -332,12 +372,12 @@ async function createVersionPr(rootDir, plan, config, packageDirs, branchName) {
332
372
  ], {
333
373
  cwd: rootDir,
334
374
  input: prBody
335
- });
375
+ }));
336
376
  log.success(`Updated PR #${validPr}`);
337
377
  } else {
338
378
  log.step("Creating version PR...");
339
379
  const prTitle = config.versionPr.title;
340
- const result = await runArgsAsync([
380
+ const result = await withPatToken(!!patPr, () => runArgsAsync([
341
381
  "gh",
342
382
  "pr",
343
383
  "create",
@@ -352,8 +392,9 @@ async function createVersionPr(rootDir, plan, config, packageDirs, branchName) {
352
392
  ], {
353
393
  cwd: rootDir,
354
394
  input: prBody
355
- });
395
+ }));
356
396
  log.success(`Created PR: ${result}`);
397
+ if (!patPr) pushWithToken(rootDir, branch, config);
357
398
  }
358
399
  runArgs([
359
400
  "git",
@@ -362,7 +403,7 @@ async function createVersionPr(rootDir, plan, config, packageDirs, branchName) {
362
403
  ], { cwd: rootDir });
363
404
  }
364
405
  const FROG_IMG_BASE = "https://raw.githubusercontent.com/dmno-dev/bumpy/main/images";
365
- function buildAddChangesetLink(prBranch) {
406
+ function buildAddBumpFileLink(prBranch) {
366
407
  if (!prBranch) return null;
367
408
  const repo = process.env.GITHUB_REPOSITORY;
368
409
  if (!repo) return null;
@@ -383,7 +424,7 @@ function pmRunCommand(pm) {
383
424
  if (pm === "yarn") return "yarn bumpy";
384
425
  return "npx bumpy";
385
426
  }
386
- function formatReleasePlanComment(plan, changesets, prNumber, prBranch, pm) {
427
+ function formatReleasePlanComment(plan, bumpFiles, prNumber, prBranch, pm, warnings = []) {
387
428
  const repo = process.env.GITHUB_REPOSITORY;
388
429
  const lines = [];
389
430
  const preamble = [
@@ -415,10 +456,10 @@ function formatReleasePlanComment(plan, changesets, prNumber, prBranch, pm) {
415
456
  }
416
457
  lines.push("");
417
458
  }
418
- lines.push(`#### Changesets in this PR`);
459
+ lines.push(`#### Bump files in this PR`);
419
460
  lines.push("");
420
- for (const cs of changesets) {
421
- const filename = `${cs.id}.md`;
461
+ for (const bf of bumpFiles) {
462
+ const filename = `${bf.id}.md`;
422
463
  const parts = [`\`${filename}\``];
423
464
  if (repo) {
424
465
  parts.push(`([view diff](https://github.com/${repo}/pull/${prNumber}/files#diff-.bumpy/${filename}))`);
@@ -427,29 +468,35 @@ function formatReleasePlanComment(plan, changesets, prNumber, prBranch, pm) {
427
468
  lines.push(`- ${parts.join(" ")}`);
428
469
  }
429
470
  lines.push("");
430
- const addLink = buildAddChangesetLink(prBranch);
431
- if (addLink) lines.push(`[Click here if you want to add another changeset to this PR](${addLink})\n`);
432
- else lines.push(`To add another changeset, run \`${pmRunCommand(pm)} add\`\n`);
471
+ if (warnings.length > 0) {
472
+ lines.push("#### Warnings");
473
+ lines.push("");
474
+ for (const w of warnings) lines.push(`> ⚠️ ${w}`);
475
+ lines.push("");
476
+ }
477
+ const addLink = buildAddBumpFileLink(prBranch);
478
+ if (addLink) lines.push(`[Click here if you want to add another bump file to this PR](${addLink})\n`);
479
+ else lines.push(`To add another bump file, run \`${pmRunCommand(pm)} add\`\n`);
433
480
  lines.push("---");
434
481
  lines.push(`_This comment is maintained by [bumpy](https://github.com/dmno-dev/bumpy)._`);
435
482
  return lines.join("\n");
436
483
  }
437
- function formatNoChangesetsComment(prBranch, pm) {
484
+ function formatNoBumpFilesComment(prBranch, pm) {
438
485
  const runCmd = pmRunCommand(pm);
439
486
  const lines = [
440
487
  `<a href="https://github.com/dmno-dev/bumpy"><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
488
  "",
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 changeset.**",
489
+ "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
490
  "<br clear=\"left\" />\n",
444
- "You can add a changeset by running:\n",
491
+ "You can add a bump file by running:\n",
445
492
  "```bash",
446
493
  `${runCmd} add`,
447
494
  "```"
448
495
  ];
449
- const addLink = buildAddChangesetLink(prBranch);
496
+ const addLink = buildAddBumpFileLink(prBranch);
450
497
  if (addLink) {
451
498
  lines.push("");
452
- lines.push(`Or [click here to add a changeset](${addLink}) directly on GitHub.`);
499
+ lines.push(`Or [click here to add a bump file](${addLink}) directly on GitHub.`);
453
500
  }
454
501
  lines.push("\n---");
455
502
  lines.push(`_This comment is maintained by [bumpy](https://github.com/dmno-dev/bumpy)._`);
@@ -465,10 +512,7 @@ function buildDiffLinks(pkgDir) {
465
512
  return ` <sub>${[`[package.json](#diff-${sha256Hex(pkgJsonPath)})`, `[CHANGELOG.md](#diff-${sha256Hex(changelogPath)})`].join(" · ")}</sub>`;
466
513
  }
467
514
  function sha256Hex(input) {
468
- const encoder = new TextEncoder();
469
- const hasher = new Bun.CryptoHasher("sha256");
470
- hasher.update(encoder.encode(input));
471
- return hasher.digest("hex");
515
+ return createHash("sha256").update(input).digest("hex");
472
516
  }
473
517
  function formatVersionPrBody(plan, preamble, packageDirs) {
474
518
  const lines = [];
@@ -495,12 +539,12 @@ function formatVersionPrBody(plan, preamble, packageDirs) {
495
539
  const diffLinks = pkgDir ? buildDiffLinks(pkgDir) : "";
496
540
  lines.push(`#### \`${r.name}\` ${r.oldVersion} → **${r.newVersion}**${suffix}${diffLinks}`);
497
541
  lines.push("");
498
- const relevantChangesets = plan.changesets.filter((cs) => r.changesets.includes(cs.id));
499
- if (relevantChangesets.length > 0) {
500
- for (const cs of relevantChangesets) if (cs.summary) {
501
- const csLink = ` ([changeset](#diff-${sha256Hex(`.bumpy/${cs.id}.md`)}))`;
502
- const summaryLines = cs.summary.split("\n");
503
- lines.push(`- ${summaryLines[0]}${csLink}`);
542
+ const relevantBumpFiles = plan.bumpFiles.filter((bf) => r.bumpFiles.includes(bf.id));
543
+ if (relevantBumpFiles.length > 0) {
544
+ for (const bf of relevantBumpFiles) if (bf.summary) {
545
+ const bfLink = ` ([bump file](#diff-${sha256Hex(`.bumpy/${bf.id}.md`)}))`;
546
+ const summaryLines = bf.summary.split("\n");
547
+ lines.push(`- ${summaryLines[0]}${bfLink}`);
504
548
  for (let i = 1; i < summaryLines.length; i++) if (summaryLines[i].trim()) lines.push(` ${summaryLines[i]}`);
505
549
  }
506
550
  } else if (r.isDependencyBump) lines.push("- Updated dependencies");
@@ -511,7 +555,7 @@ function formatVersionPrBody(plan, preamble, packageDirs) {
511
555
  return lines.join("\n");
512
556
  }
513
557
  const COMMENT_MARKER = "<!-- bumpy-release-plan -->";
514
- async function postOrUpdatePrComment(prNumber, body, rootDir) {
558
+ async function postOrUpdatePrComment(prNumber, body, rootDir, usePat = false) {
515
559
  const validPr = validatePrNumber(prNumber);
516
560
  const markedBody = `${COMMENT_MARKER}\n${body}`;
517
561
  try {
@@ -526,7 +570,7 @@ async function postOrUpdatePrComment(prNumber, body, rootDir) {
526
570
  `.comments[] | select(.body | startswith("${COMMENT_MARKER}")) | .url | capture("issuecomment-(?<id>[0-9]+)$") | .id`
527
571
  ], { cwd: rootDir })?.split("\n")[0]?.trim();
528
572
  if (commentId) {
529
- await runArgsAsync([
573
+ await withPatToken(usePat, () => runArgsAsync([
530
574
  "gh",
531
575
  "api",
532
576
  `repos/{owner}/{repo}/issues/comments/${commentId}`,
@@ -537,10 +581,10 @@ async function postOrUpdatePrComment(prNumber, body, rootDir) {
537
581
  ], {
538
582
  cwd: rootDir,
539
583
  input: markedBody
540
- });
584
+ }));
541
585
  log.dim(" Updated PR comment");
542
586
  } else {
543
- await runArgsAsync([
587
+ await withPatToken(usePat, () => runArgsAsync([
544
588
  "gh",
545
589
  "pr",
546
590
  "comment",
@@ -550,7 +594,7 @@ async function postOrUpdatePrComment(prNumber, body, rootDir) {
550
594
  ], {
551
595
  cwd: rootDir,
552
596
  input: markedBody
553
- });
597
+ }));
554
598
  log.dim(" Posted PR comment");
555
599
  }
556
600
  } catch (err) {
@@ -1,5 +1,5 @@
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-DcI5TdDE.mjs";
2
+ import { t as detectPackageManager } from "./package-manager-VCe10bjc.mjs";
3
3
  import { o as tryRunArgs } from "./shell-Dj7JRD_q.mjs";
4
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-CDRCHrC-.mjs";
5
5
  //#region src/commands/ci-setup.ts