@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.
- package/.claude-plugin/plugin.json +2 -2
- package/dist/add-CgCjs4d-.mjs +313 -0
- package/dist/{ai-CQhUyHAG.mjs → ai-sMYUf3lP.mjs} +21 -4
- package/dist/{apply-release-plan-D6TSrcwX.mjs → apply-release-plan-CczGWJTk.mjs} +28 -24
- package/dist/bump-file-CCLXMLA8.mjs +143 -0
- package/dist/{changelog-github-Du62krXi.mjs → changelog-github-Cd8uJHZI.mjs} +22 -20
- package/dist/{check-jIwike9F.mjs → check-BOoxpWqk.mjs} +9 -9
- package/dist/{ci-D6LQbR38.mjs → ci-Bhx--Tj6.mjs} +116 -72
- package/dist/{ci-setup-C6FlOfW5.mjs → ci-setup-qz4Y3v7T.mjs} +1 -1
- package/dist/cli.mjs +32 -30
- package/dist/{config-BkwIEaQg.mjs → config-XZWUL3ma.mjs} +27 -22
- package/dist/fs-DYR2XuFE.mjs +81 -0
- package/dist/{generate-Btrsn1qi.mjs → generate-gYKTpvex.mjs} +8 -8
- package/dist/index.d.mts +55 -37
- package/dist/index.mjs +8 -8
- package/dist/{init-B0q3wEQW.mjs → init-lA9E5pEc.mjs} +2 -2
- package/dist/{migrate-CfQNwD0T.mjs → migrate-DmOYgmfD.mjs} +10 -10
- package/dist/{names-Ck8cun7B.mjs → names-9VubBmL0.mjs} +1 -1
- package/dist/{package-manager-DcI5TdDE.mjs → package-manager-VCe10bjc.mjs} +1 -1
- package/dist/{publish-D_7RqEYL.mjs → publish-Cun-zQ1b.mjs} +21 -20
- package/dist/{publish-pipeline-ChnqW8nR.mjs → publish-pipeline-BwBuKCIk.mjs} +22 -17
- package/dist/release-plan-Bi5QNSEo.mjs +264 -0
- package/dist/{semver-BTzYh8vc.mjs → semver-DfQyVLM_.mjs} +13 -3
- package/dist/{status--Q8yAxQ4.mjs → status-CfE63ti5.mjs} +25 -21
- package/dist/{version-cAUkfYPx.mjs → version-19vVt9dv.mjs} +16 -12
- package/dist/{workspace-CxEKakDm.mjs → workspace-C5ULTyUN.mjs} +3 -3
- package/package.json +13 -1
- package/skills/add-change/SKILL.md +8 -12
- package/dist/add-BjyVIUlr.mjs +0 -175
- package/dist/changeset-UCZdSRDv.mjs +0 -108
- package/dist/fs-0AtnPUUe.mjs +0 -51
- 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", { "
|
|
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,
|
|
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
|
|
24
|
-
if (
|
|
25
|
-
if (!
|
|
26
|
-
const { cleanSummary, overrides } = extractSummaryMeta(
|
|
27
|
-
const gitInfo =
|
|
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 &&
|
|
35
|
-
if (release.isCascadeBump && !release.isDependencyBump &&
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
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
|
|
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
|
|
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/${
|
|
121
|
-
`.changeset/${
|
|
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-
|
|
3
|
-
import { n as discoverWorkspace } from "./workspace-
|
|
4
|
-
import { r as
|
|
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
|
|
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
|
|
16
|
+
const bumpFiles = await readBumpFiles(rootDir);
|
|
17
17
|
const coveredPackages = /* @__PURE__ */ new Set();
|
|
18
|
-
for (const
|
|
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
|
|
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
|
|
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
|
|
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-
|
|
3
|
-
import { t as detectPackageManager } from "./package-manager-
|
|
4
|
-
import { n as discoverWorkspace } from "./workspace-
|
|
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
|
|
8
|
-
import { t as assembleReleasePlan } from "./release-plan-
|
|
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-
|
|
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
|
|
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
|
|
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
|
|
64
|
-
const
|
|
65
|
-
if (
|
|
66
|
-
log.info("No
|
|
67
|
-
if (shouldComment && prNumber) await postOrUpdatePrComment(prNumber,
|
|
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(
|
|
72
|
-
log.bold(`${
|
|
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 (
|
|
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
|
|
89
|
-
if (
|
|
90
|
-
log.info("No pending
|
|
91
|
-
const { publishCommand } = await import("./publish-
|
|
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(
|
|
123
|
+
const plan = assembleReleasePlan(bumpFiles, packages, depGraph, config);
|
|
96
124
|
if (plan.releases.length === 0) {
|
|
97
|
-
log.info("
|
|
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-
|
|
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([
|
|
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-
|
|
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
|
-
"^
|
|
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
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
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-
|
|
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
|
|
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,
|
|
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(`####
|
|
459
|
+
lines.push(`#### Bump files in this PR`);
|
|
419
460
|
lines.push("");
|
|
420
|
-
for (const
|
|
421
|
-
const filename = `${
|
|
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
|
-
|
|
431
|
-
|
|
432
|
-
|
|
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
|
|
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
|
|
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
|
|
491
|
+
"You can add a bump file by running:\n",
|
|
445
492
|
"```bash",
|
|
446
493
|
`${runCmd} add`,
|
|
447
494
|
"```"
|
|
448
495
|
];
|
|
449
|
-
const addLink =
|
|
496
|
+
const addLink = buildAddBumpFileLink(prBranch);
|
|
450
497
|
if (addLink) {
|
|
451
498
|
lines.push("");
|
|
452
|
-
lines.push(`Or [click here to add a
|
|
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
|
-
|
|
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
|
|
499
|
-
if (
|
|
500
|
-
for (const
|
|
501
|
-
const
|
|
502
|
-
const summaryLines =
|
|
503
|
-
lines.push(`- ${summaryLines[0]}${
|
|
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-
|
|
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
|