@varlock/bumpy 0.0.1 → 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 (44) hide show
  1. package/.claude-plugin/plugin.json +2 -2
  2. package/dist/add-CgCjs4d-.mjs +313 -0
  3. package/dist/{ai-B8ZL2x8z.mjs → ai-sMYUf3lP.mjs} +22 -5
  4. package/dist/{apply-release-plan-DtU3rVyL.mjs → apply-release-plan-CczGWJTk.mjs} +34 -25
  5. package/dist/bump-file-CCLXMLA8.mjs +143 -0
  6. package/dist/changelog-github-Cd8uJHZI.mjs +195 -0
  7. package/dist/{check-CkRubvuk.mjs → check-BOoxpWqk.mjs} +11 -17
  8. package/dist/ci-Bhx--Tj6.mjs +629 -0
  9. package/dist/ci-setup-qz4Y3v7T.mjs +211 -0
  10. package/dist/clack-CDRCHrC-.mjs +1216 -0
  11. package/dist/cli.mjs +37 -31
  12. package/dist/{config-CJ2orhTL.mjs → config-XZWUL3ma.mjs} +28 -23
  13. package/dist/fs-DYR2XuFE.mjs +81 -0
  14. package/dist/{generate-oOFD9ABC.mjs → generate-gYKTpvex.mjs} +31 -12
  15. package/dist/git-CGHVXXKw.mjs +78 -0
  16. package/dist/index.d.mts +63 -37
  17. package/dist/index.mjs +9 -9
  18. package/dist/{init-Blw2GfC_.mjs → init-lA9E5pEc.mjs} +3 -3
  19. package/dist/logger-C2dEe5Su.mjs +135 -0
  20. package/dist/{migrate-DvOrXSw0.mjs → migrate-DmOYgmfD.mjs} +23 -16
  21. package/dist/{names-C-u50ofE.mjs → names-9VubBmL0.mjs} +3 -2
  22. package/dist/package-manager-VCe10bjc.mjs +80 -0
  23. package/dist/{publish-DZ3m7qkX.mjs → publish-Cun-zQ1b.mjs} +90 -35
  24. package/dist/{publish-pipeline-1M5GmbdP.mjs → publish-pipeline-BwBuKCIk.mjs} +56 -65
  25. package/dist/release-plan-Bi5QNSEo.mjs +264 -0
  26. package/dist/{semver-DWO6NFKN.mjs → semver-DfQyVLM_.mjs} +14 -4
  27. package/dist/shell-Dj7JRD_q.mjs +92 -0
  28. package/dist/{status-DRpq_Mha.mjs → status-CfE63ti5.mjs} +27 -23
  29. package/dist/version-19vVt9dv.mjs +124 -0
  30. package/dist/workspace-C5ULTyUN.mjs +107 -0
  31. package/package.json +16 -2
  32. package/skills/add-change/SKILL.md +8 -12
  33. package/dist/add-u5V9V3L7.mjs +0 -131
  34. package/dist/changelog-github-n-3zV1p9.mjs +0 -59
  35. package/dist/changeset-ClCYsChu.mjs +0 -75
  36. package/dist/ci-8KWWhjXl.mjs +0 -224
  37. package/dist/fs-DbNNEyzq.mjs +0 -51
  38. package/dist/logger-ZqggsyGZ.mjs +0 -176
  39. package/dist/prompt-BP8toAOI.mjs +0 -46
  40. package/dist/release-plan-CFnutSHD.mjs +0 -173
  41. package/dist/shell-DPlltpzb.mjs +0 -44
  42. package/dist/version-CJwf8XIA.mjs +0 -81
  43. package/dist/workspace-mVjawG8g.mjs +0 -183
  44. /package/dist/{dep-graph-DiLeAhl9.mjs → dep-graph-E-9-eQ2J.mjs} +0 -0
@@ -0,0 +1,195 @@
1
+ import { o as tryRunArgs } from "./shell-Dj7JRD_q.mjs";
2
+ //#region src/core/changelog-github.ts
3
+ /**
4
+ * GitHub-enhanced changelog formatter.
5
+ * Adds PR links, commit links, and contributor attribution when git/gh info is available.
6
+ *
7
+ * Usage in config:
8
+ * "changelog": "github"
9
+ * "changelog": ["github", { "repo": "dmno-dev/bumpy" }]
10
+ * "changelog": ["github", { "thankContributors": false }]
11
+ * "changelog": ["github", { "internalAuthors": ["theoephraim"] }]
12
+ */
13
+ function createGithubFormatter(options = {}) {
14
+ const thankContributors = options.thankContributors ?? true;
15
+ const internalAuthorsSet = new Set((options.internalAuthors ?? []).map((a) => a.toLowerCase()));
16
+ return async (ctx) => {
17
+ const { release, bumpFiles, date } = ctx;
18
+ const repoSlug = options.repo ?? detectRepo();
19
+ const serverUrl = process.env.GITHUB_SERVER_URL || "https://github.com";
20
+ const lines = [];
21
+ lines.push(`## ${release.newVersion}`);
22
+ lines.push("");
23
+ lines.push(`_${date}_`);
24
+ lines.push("");
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);
30
+ const summaryLines = cleanSummary.split("\n");
31
+ const firstLine = linkifyIssueRefs(summaryLines[0], serverUrl, repoSlug);
32
+ const prefix = formatPrefix(gitInfo, serverUrl, repoSlug, thankContributors, internalAuthorsSet);
33
+ lines.push(`-${prefix ? ` ${prefix} -` : ""} ${firstLine}`);
34
+ for (let i = 1; i < summaryLines.length; i++) if (summaryLines[i].trim()) lines.push(` ${linkifyIssueRefs(summaryLines[i], serverUrl, repoSlug)}`);
35
+ }
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");
38
+ lines.push("");
39
+ return lines.join("\n");
40
+ };
41
+ }
42
+ /**
43
+ * Extract metadata lines (pr, commit, author) from a bump file summary.
44
+ * These override git-derived info, matching the behavior of @changesets/changelog-github.
45
+ */
46
+ function extractSummaryMeta(summary) {
47
+ const overrides = {};
48
+ return {
49
+ cleanSummary: summary.replace(/^\s*(?:pr|pull|pull\s+request):\s*#?(\d+)/im, (_, pr) => {
50
+ const num = Number(pr);
51
+ if (!isNaN(num)) overrides.pr = num;
52
+ return "";
53
+ }).replace(/^\s*commit:\s*([^\s]+)/im, (_, commit) => {
54
+ overrides.commit = commit;
55
+ return "";
56
+ }).replace(/^\s*(?:author|user):\s*@?([^\s]+)/gim, (_, user) => {
57
+ overrides.authors ??= [];
58
+ overrides.authors.push(user);
59
+ return "";
60
+ }).trim(),
61
+ overrides
62
+ };
63
+ }
64
+ /**
65
+ * Resolve PR, commit, and author info for a bump file.
66
+ * Summary overrides take precedence over git-derived info.
67
+ */
68
+ function resolveBumpFileInfo(bumpFileId, repo, serverUrl, overrides) {
69
+ if (overrides.pr !== void 0) {
70
+ const prInfo = lookupPr(overrides.pr, repo);
71
+ return {
72
+ prNumber: overrides.pr,
73
+ prUrl: prInfo?.url ?? `${serverUrl}/${repo}/pull/${overrides.pr}`,
74
+ commitHash: overrides.commit ?? prInfo?.commitHash,
75
+ author: overrides.authors?.[0] ?? prInfo?.author
76
+ };
77
+ }
78
+ const gitInfo = findBumpFileCommitInfo(bumpFileId, repo);
79
+ return {
80
+ prNumber: gitInfo?.prNumber,
81
+ prUrl: gitInfo?.prUrl,
82
+ commitHash: overrides.commit ?? gitInfo?.commitHash,
83
+ author: overrides.authors?.[0] ?? gitInfo?.author
84
+ };
85
+ }
86
+ /** Look up a PR by number using gh CLI */
87
+ function lookupPr(prNumber, repo) {
88
+ try {
89
+ const ghArgs = [
90
+ "gh",
91
+ "pr",
92
+ "view",
93
+ String(prNumber),
94
+ "--json",
95
+ "url,author,mergeCommit"
96
+ ];
97
+ if (repo) ghArgs.push("--repo", repo);
98
+ const result = tryRunArgs(ghArgs);
99
+ if (!result) return null;
100
+ const pr = JSON.parse(result);
101
+ return {
102
+ url: pr.url,
103
+ author: pr.author?.login,
104
+ commitHash: pr.mergeCommit?.oid
105
+ };
106
+ } catch {
107
+ return null;
108
+ }
109
+ }
110
+ /**
111
+ * Find the PR that introduced a bump file by checking git log
112
+ * for the commit that added the file, then looking up the PR.
113
+ */
114
+ function findBumpFileCommitInfo(bumpFileId, repo) {
115
+ try {
116
+ const commitOutput = tryRunArgs([
117
+ "git",
118
+ "log",
119
+ "--diff-filter=A",
120
+ "--format=%H",
121
+ "--",
122
+ `.bumpy/${bumpFileId}.md`,
123
+ `.changeset/${bumpFileId}.md`
124
+ ]);
125
+ if (!commitOutput) return null;
126
+ const commitHash = commitOutput.split("\n")[0].trim();
127
+ if (!commitHash) return null;
128
+ const ghArgs = [
129
+ "gh",
130
+ "pr",
131
+ "list",
132
+ "--search",
133
+ commitHash,
134
+ "--state",
135
+ "merged",
136
+ "--json",
137
+ "number,url,author",
138
+ "--jq",
139
+ ".[0]"
140
+ ];
141
+ if (repo) ghArgs.push("--repo", repo);
142
+ const prJson = tryRunArgs(ghArgs);
143
+ if (!prJson) return { commitHash };
144
+ const pr = JSON.parse(prJson);
145
+ if (!pr.number) return { commitHash };
146
+ return {
147
+ prNumber: pr.number,
148
+ prUrl: pr.url,
149
+ commitHash,
150
+ author: pr.author?.login
151
+ };
152
+ } catch {
153
+ return null;
154
+ }
155
+ }
156
+ /**
157
+ * Build the prefix portion of a changelog line: PR link, commit link, thanks.
158
+ * Matches the format used by @changesets/changelog-github.
159
+ */
160
+ function formatPrefix(info, serverUrl, repo, thankContributors, internalAuthors) {
161
+ const parts = [];
162
+ if (info.prNumber && info.prUrl) parts.push(`[#${info.prNumber}](${info.prUrl})`);
163
+ if (info.commitHash && repo) {
164
+ const short = info.commitHash.slice(0, 7);
165
+ parts.push(`[\`${short}\`](${serverUrl}/${repo}/commit/${info.commitHash})`);
166
+ }
167
+ if (thankContributors && info.author && !internalAuthors.has(info.author.toLowerCase())) parts.push(`Thanks [@${info.author}](${serverUrl}/${info.author})!`);
168
+ return parts.join(" ");
169
+ }
170
+ /**
171
+ * Linkify bare issue/PR references like #123 in text,
172
+ * but skip references already inside markdown links.
173
+ */
174
+ function linkifyIssueRefs(line, serverUrl, repo) {
175
+ if (!repo) return line;
176
+ return line.replace(/\[.*?\]\(.*?\)|\B#([1-9]\d*)\b/g, (match, issue) => issue ? `[#${issue}](${serverUrl}/${repo}/issues/${issue})` : match);
177
+ }
178
+ /** Try to detect the repo slug from the gh CLI */
179
+ function detectRepo() {
180
+ try {
181
+ return tryRunArgs([
182
+ "gh",
183
+ "repo",
184
+ "view",
185
+ "--json",
186
+ "nameWithOwner",
187
+ "--jq",
188
+ ".nameWithOwner"
189
+ ])?.trim() || void 0;
190
+ } catch {
191
+ return;
192
+ }
193
+ }
194
+ //#endregion
195
+ export { createGithubFormatter };
@@ -1,21 +1,21 @@
1
- import { n as log, t as colorize } from "./logger-ZqggsyGZ.mjs";
2
- import { a as loadConfig } from "./config-CJ2orhTL.mjs";
3
- import { n as discoverWorkspace } from "./workspace-mVjawG8g.mjs";
4
- import { r as readChangesets } from "./changeset-ClCYsChu.mjs";
5
- import { i as tryRun } from "./shell-DPlltpzb.mjs";
1
+ import { n as log, t as colorize } from "./logger-C2dEe5Su.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
+ 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,21 +29,15 @@ 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
- /** Get files changed on this branch compared to the base branch */
42
- function getChangedFiles(rootDir, baseBranch) {
43
- const diff = tryRun(`git diff --name-only ${tryRun(`git merge-base HEAD origin/${baseBranch}`, { cwd: rootDir }) || `origin/${baseBranch}`}`, { cwd: rootDir });
44
- if (!diff) return [];
45
- return diff.split("\n").filter(Boolean);
46
- }
47
41
  /** Map changed files to the packages they belong to */
48
42
  function findChangedPackages(changedFiles, packages, rootDir) {
49
43
  const changed = /* @__PURE__ */ new Set();