@varlock/bumpy 1.14.0-rc.1 → 1.14.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.
|
@@ -77,9 +77,10 @@ async function ciCheckCommand(rootDir, opts) {
|
|
|
77
77
|
const config = await loadConfig(rootDir);
|
|
78
78
|
const { packages } = await discoverWorkspace(rootDir, config);
|
|
79
79
|
const depGraph = new DependencyGraph(packages);
|
|
80
|
-
const { bumpFiles: allBumpFiles, errors: parseErrors } = await readBumpFiles(rootDir);
|
|
80
|
+
const { bumpFiles: allBumpFiles, errors: parseErrors } = await readBumpFiles(rootDir, { channels: channelNames(config) });
|
|
81
81
|
const prBranchName = detectPrBranch(rootDir);
|
|
82
|
-
const
|
|
82
|
+
const channels = resolveChannels(config);
|
|
83
|
+
const releasePrBranches = new Set([config.versionPr.branch, ...[...channels.values()].map((c) => c.versionPr.branch)]);
|
|
83
84
|
if (prBranchName && releasePrBranches.has(prBranchName)) {
|
|
84
85
|
log.dim(" Skipping — this is a release PR branch.");
|
|
85
86
|
return;
|
|
@@ -122,7 +123,7 @@ async function ciCheckCommand(rootDir, opts) {
|
|
|
122
123
|
console.log(` ${r.name}: ${r.oldVersion} → ${colorize(`${r.newVersion}${releaseSuffix}`, "cyan")}${tag}`);
|
|
123
124
|
}
|
|
124
125
|
if (plan.warnings.length > 0) for (const w of plan.warnings) log.warn(w);
|
|
125
|
-
if (shouldComment && prNumber) await postOrUpdatePrComment(prNumber, formatReleasePlanComment(plan, prBumpFiles, prNumber, detectPrBranch(rootDir), pm, plan.warnings, parseErrors, emptyBumpFileIds, prChannel), rootDir);
|
|
126
|
+
if (shouldComment && prNumber) await postOrUpdatePrComment(prNumber, formatReleasePlanComment(plan, prBumpFiles, prNumber, detectPrBranch(rootDir), pm, plan.warnings, parseErrors, emptyBumpFileIds, prChannel, channels), rootDir);
|
|
126
127
|
if (parseErrors.length > 0 && !opts.noFail) process.exit(1);
|
|
127
128
|
const coveredPackages = new Set(plan.releases.map((r) => r.name));
|
|
128
129
|
for (const bf of prBumpFiles) for (const release of bf.releases) coveredPackages.add(release.name);
|
|
@@ -169,7 +170,7 @@ async function ciPlanCommand(rootDir) {
|
|
|
169
170
|
packageNames: plan.releases.map((r) => r.name)
|
|
170
171
|
};
|
|
171
172
|
else {
|
|
172
|
-
const { findUnpublishedPackages } = await import("./publish-
|
|
173
|
+
const { findUnpublishedPackages } = await import("./publish-DWxi552d.mjs");
|
|
173
174
|
const unpublished = await findUnpublishedPackages(packages, config);
|
|
174
175
|
if (unpublished.length > 0) output = {
|
|
175
176
|
mode: "publish",
|
|
@@ -253,7 +254,7 @@ async function ciReleaseCommand(rootDir, opts) {
|
|
|
253
254
|
const msg = bumpFiles.length === 0 ? "No pending bump files — checking for unpublished packages..." : "Bump files found but no packages would be released — checking for unpublished packages...";
|
|
254
255
|
log.info(msg);
|
|
255
256
|
const recoveredBumpFiles = recoverDeletedBumpFiles(rootDir);
|
|
256
|
-
const { publishCommand } = await import("./publish-
|
|
257
|
+
const { publishCommand } = await import("./publish-DWxi552d.mjs");
|
|
257
258
|
await publishCommand(rootDir, {
|
|
258
259
|
tag: opts.tag,
|
|
259
260
|
recoveredBumpFiles
|
|
@@ -306,7 +307,7 @@ async function autoPublish(rootDir, config, plan, tag) {
|
|
|
306
307
|
], { cwd: rootDir });
|
|
307
308
|
}
|
|
308
309
|
log.step("Running bumpy publish...");
|
|
309
|
-
const { publishCommand } = await import("./publish-
|
|
310
|
+
const { publishCommand } = await import("./publish-DWxi552d.mjs");
|
|
310
311
|
await publishCommand(rootDir, { tag });
|
|
311
312
|
}
|
|
312
313
|
/**
|
|
@@ -475,6 +476,93 @@ async function createVersionPr(rootDir, plan, config, packageDirs, branchName) {
|
|
|
475
476
|
"checkout",
|
|
476
477
|
baseBranch
|
|
477
478
|
], { cwd: rootDir });
|
|
479
|
+
await closePromotedChannelReleasePrs(rootDir, config, plan.bumpFiles);
|
|
480
|
+
}
|
|
481
|
+
/**
|
|
482
|
+
* Channels whose dirs gained bump files in the triggering push — i.e. this push is
|
|
483
|
+
* the promotion/graduation merge that delivered them. (Same range detection as the
|
|
484
|
+
* channel publish trigger.)
|
|
485
|
+
*/
|
|
486
|
+
function detectArrivedChannelFiles(rootDir, config) {
|
|
487
|
+
const range = getPushEventRange();
|
|
488
|
+
let diffRange;
|
|
489
|
+
if (range) diffRange = `${range.before}..${range.after}`;
|
|
490
|
+
else {
|
|
491
|
+
if (!tryRunArgs([
|
|
492
|
+
"git",
|
|
493
|
+
"rev-parse",
|
|
494
|
+
"--verify",
|
|
495
|
+
"HEAD^"
|
|
496
|
+
], { cwd: rootDir })) return /* @__PURE__ */ new Set();
|
|
497
|
+
diffRange = "HEAD^..HEAD";
|
|
498
|
+
}
|
|
499
|
+
const out = tryRunArgs([
|
|
500
|
+
"git",
|
|
501
|
+
"diff",
|
|
502
|
+
"--name-only",
|
|
503
|
+
"--diff-filter=A",
|
|
504
|
+
"--no-renames",
|
|
505
|
+
diffRange,
|
|
506
|
+
"--",
|
|
507
|
+
".bumpy/"
|
|
508
|
+
], { cwd: rootDir });
|
|
509
|
+
if (!out) return /* @__PURE__ */ new Set();
|
|
510
|
+
const knownChannels = new Set(channelNames(config));
|
|
511
|
+
const arrived = /* @__PURE__ */ new Set();
|
|
512
|
+
for (const f of out.split("\n")) {
|
|
513
|
+
if (!f.endsWith(".md") || f.endsWith("README.md")) continue;
|
|
514
|
+
const parts = f.split("/");
|
|
515
|
+
if (parts.length === 3 && knownChannels.has(parts[1])) arrived.add(parts[1]);
|
|
516
|
+
}
|
|
517
|
+
return arrived;
|
|
518
|
+
}
|
|
519
|
+
/**
|
|
520
|
+
* Close lingering channel release PRs whose cycles were promoted: once a channel's
|
|
521
|
+
* bump files are pending on this branch (via a promotion or graduation merge), the
|
|
522
|
+
* source channel's own release PR is obsolete — merging it would re-publish a cycle
|
|
523
|
+
* that's already moving to its next stage. A fresh release PR is created automatically
|
|
524
|
+
* if new work lands on the channel branch.
|
|
525
|
+
*
|
|
526
|
+
* Only channels whose files arrived in the TRIGGERING push are considered: the files
|
|
527
|
+
* stay pending here until our version/release PR merges, and re-closing on every
|
|
528
|
+
* later push in that window would kill the release PR of a newly restarted cycle.
|
|
529
|
+
*/
|
|
530
|
+
async function closePromotedChannelReleasePrs(rootDir, config, bumpFiles, currentChannel) {
|
|
531
|
+
const arrived = detectArrivedChannelFiles(rootDir, config);
|
|
532
|
+
const promoted = [...new Set(bumpFiles.map((bf) => bf.channel))].filter((name) => name != null && name !== currentChannel?.name && arrived.has(name));
|
|
533
|
+
if (promoted.length === 0) return;
|
|
534
|
+
const channels = resolveChannels(config);
|
|
535
|
+
for (const name of promoted) {
|
|
536
|
+
const channel = channels.get(name);
|
|
537
|
+
if (!channel) continue;
|
|
538
|
+
const pr = tryRunArgs([
|
|
539
|
+
"gh",
|
|
540
|
+
"pr",
|
|
541
|
+
"list",
|
|
542
|
+
"--head",
|
|
543
|
+
channel.versionPr.branch,
|
|
544
|
+
"--json",
|
|
545
|
+
"number",
|
|
546
|
+
"--jq",
|
|
547
|
+
".[0].number"
|
|
548
|
+
], { cwd: rootDir });
|
|
549
|
+
if (!pr) continue;
|
|
550
|
+
const validPr = validatePrNumber(pr);
|
|
551
|
+
log.step(`Closing release PR #${validPr} — the "${name}" cycle's changes are pending here now...`);
|
|
552
|
+
try {
|
|
553
|
+
await withPatToken(() => runArgsAsync([
|
|
554
|
+
"gh",
|
|
555
|
+
"pr",
|
|
556
|
+
"close",
|
|
557
|
+
validPr,
|
|
558
|
+
"--comment",
|
|
559
|
+
`Closing — the \`${name}\` cycle's bump files were promoted and are now pending a release here. A new release PR will be created automatically if more changes land on \`${channel.branch}\`.`
|
|
560
|
+
], { cwd: rootDir }));
|
|
561
|
+
log.success(`🐸 Closed obsolete release PR #${validPr}`);
|
|
562
|
+
} catch (e) {
|
|
563
|
+
log.warn(` Failed to close release PR #${validPr}: ${e}`);
|
|
564
|
+
}
|
|
565
|
+
}
|
|
478
566
|
}
|
|
479
567
|
/** Read the push event's before/after range, if running on a GitHub Actions push event */
|
|
480
568
|
function getPushEventRange() {
|
|
@@ -555,7 +643,7 @@ async function ciChannelRelease(rootDir, config, channel, opts) {
|
|
|
555
643
|
"--no-verify"
|
|
556
644
|
], { cwd: rootDir });
|
|
557
645
|
}
|
|
558
|
-
const { publishCommand } = await import("./publish-
|
|
646
|
+
const { publishCommand } = await import("./publish-DWxi552d.mjs");
|
|
559
647
|
await publishCommand(rootDir, {
|
|
560
648
|
channel: channel.name,
|
|
561
649
|
tag: opts.tag
|
|
@@ -566,7 +654,7 @@ async function ciChannelRelease(rootDir, config, channel, opts) {
|
|
|
566
654
|
const shouldPublish = movedIds.length > 0 && opts.assertMode !== "version-pr";
|
|
567
655
|
if (shouldPublish) {
|
|
568
656
|
log.step(`Release PR merge detected (${movedIds.map((id) => `${id}.md`).join(", ")}) — publishing prereleases...`);
|
|
569
|
-
const { publishCommand } = await import("./publish-
|
|
657
|
+
const { publishCommand } = await import("./publish-DWxi552d.mjs");
|
|
570
658
|
await publishCommand(rootDir, {
|
|
571
659
|
channel: channel.name,
|
|
572
660
|
tag: opts.tag
|
|
@@ -732,6 +820,7 @@ async function createChannelReleasePr(rootDir, config, channel, packages, branch
|
|
|
732
820
|
"checkout",
|
|
733
821
|
baseBranch
|
|
734
822
|
], { cwd: rootDir });
|
|
823
|
+
await closePromotedChannelReleasePrs(rootDir, config, result.movedFiles, channel);
|
|
735
824
|
}
|
|
736
825
|
function buildChannelPrPreamble(config, channel) {
|
|
737
826
|
return [
|
|
@@ -824,11 +913,13 @@ function pmRunCommand(pm) {
|
|
|
824
913
|
if (pm === "yarn") return "yarn bumpy";
|
|
825
914
|
return "npx bumpy";
|
|
826
915
|
}
|
|
827
|
-
function formatReleasePlanComment(plan, bumpFiles, prNumber, prBranch, pm, warnings = [], parseErrors = [], emptyBumpFileIds = [], channel = null) {
|
|
916
|
+
function formatReleasePlanComment(plan, bumpFiles, prNumber, prBranch, pm, warnings = [], parseErrors = [], emptyBumpFileIds = [], channel = null, allChannels = null) {
|
|
828
917
|
const repo = process.env.GITHUB_REPOSITORY;
|
|
829
918
|
const lines = [];
|
|
830
919
|
const versionSuffix = channel ? `-${channel.preid}.x` : "";
|
|
831
|
-
const
|
|
920
|
+
const promotedChannels = channel ? [] : [...new Set(bumpFiles.map((bf) => bf.channel))].filter((c) => c != null);
|
|
921
|
+
const channelTag = (name) => `\`@${allChannels?.get(name)?.tag ?? name}\``;
|
|
922
|
+
const headline = channel ? `**This PR targets the \`${channel.name}\` prerelease channel** — merging it ships these packages as a **prerelease** to the \`@${channel.tag}\` dist-tag, not a stable release.` : promotedChannels.length > 0 ? `**This PR promotes the ${promotedChannels.map((c) => `\`${c}\``).join(", ")} prerelease cycle${promotedChannels.length > 1 ? "s" : ""} to a stable release.** The changes below that already shipped to the ${promotedChannels.map(channelTag).join(", ")} dist-tag${promotedChannels.length > 1 ? "s" : ""} will be consolidated into the next stable version bump.` : "**The changes in this PR will be included in the next version bump.**";
|
|
832
923
|
const preamble = [
|
|
833
924
|
`<a href="https://bumpy.varlock.dev"><img src="${FROG_IMG_BASE}/frog-clipboard.png" alt="bumpy-frog" width="60" align="left" style="image-rendering: pixelated;" title="Hi! I'm bumpy!" /></a>`,
|
|
834
925
|
"",
|
|
@@ -867,8 +958,9 @@ function formatReleasePlanComment(plan, bumpFiles, prNumber, prBranch, pm, warni
|
|
|
867
958
|
lines.push(`#### Bump files in this PR`);
|
|
868
959
|
lines.push("");
|
|
869
960
|
for (const bf of bumpFiles) {
|
|
870
|
-
const filename = `${bf.id}.md`;
|
|
961
|
+
const filename = bf.channel ? `${bf.channel}/${bf.id}.md` : `${bf.id}.md`;
|
|
871
962
|
const parts = [`\`${filename}\``];
|
|
963
|
+
if (bf.channel) parts.push(`_(shipped on ${channelTag(bf.channel)})_`);
|
|
872
964
|
if (repo) {
|
|
873
965
|
parts.push(`([view diff](https://github.com/${repo}/pull/${prNumber}/changes#diff-${sha256Hex(`.bumpy/${filename}`)}))`);
|
|
874
966
|
if (prBranch) parts.push(`([edit](https://github.com/${repo}/edit/${prBranch}/.bumpy/${filename}))`);
|
package/dist/cli.mjs
CHANGED
|
@@ -94,17 +94,17 @@ async function main() {
|
|
|
94
94
|
const subcommand = args[1];
|
|
95
95
|
const ciFlags = parseFlags(args.slice(2));
|
|
96
96
|
if (subcommand === "check") {
|
|
97
|
-
const { ciCheckCommand } = await import("./ci-
|
|
97
|
+
const { ciCheckCommand } = await import("./ci-BRJNl-VN.mjs");
|
|
98
98
|
await ciCheckCommand(rootDir, {
|
|
99
99
|
comment: ciFlags.comment !== void 0 ? ciFlags.comment === true : void 0,
|
|
100
100
|
strict: ciFlags.strict === true,
|
|
101
101
|
noFail: ciFlags["no-fail"] === true
|
|
102
102
|
});
|
|
103
103
|
} else if (subcommand === "plan") {
|
|
104
|
-
const { ciPlanCommand } = await import("./ci-
|
|
104
|
+
const { ciPlanCommand } = await import("./ci-BRJNl-VN.mjs");
|
|
105
105
|
await ciPlanCommand(rootDir);
|
|
106
106
|
} else if (subcommand === "release") {
|
|
107
|
-
const { ciReleaseCommand } = await import("./ci-
|
|
107
|
+
const { ciReleaseCommand } = await import("./ci-BRJNl-VN.mjs");
|
|
108
108
|
const expectModeFlag = ciFlags["expect-mode"];
|
|
109
109
|
const autoPublishFlag = ciFlags["auto-publish"] === true;
|
|
110
110
|
if (expectModeFlag !== void 0 && expectModeFlag !== "version-pr" && expectModeFlag !== "publish") {
|
|
@@ -132,7 +132,7 @@ async function main() {
|
|
|
132
132
|
}
|
|
133
133
|
case "publish": {
|
|
134
134
|
const rootDir = await findRoot();
|
|
135
|
-
const { publishCommand } = await import("./publish-
|
|
135
|
+
const { publishCommand } = await import("./publish-DWxi552d.mjs");
|
|
136
136
|
await publishCommand(rootDir, {
|
|
137
137
|
dryRun: flags["dry-run"] === true,
|
|
138
138
|
tag: flags.tag,
|
|
@@ -157,7 +157,7 @@ async function main() {
|
|
|
157
157
|
}
|
|
158
158
|
case "--version":
|
|
159
159
|
case "-v":
|
|
160
|
-
console.log(`bumpy 1.
|
|
160
|
+
console.log(`bumpy 1.14.0`);
|
|
161
161
|
break;
|
|
162
162
|
case "help":
|
|
163
163
|
case "--help":
|
|
@@ -177,7 +177,7 @@ async function main() {
|
|
|
177
177
|
}
|
|
178
178
|
function printHelp() {
|
|
179
179
|
console.log(`
|
|
180
|
-
${colorize(`🐸 bumpy v1.
|
|
180
|
+
${colorize(`🐸 bumpy v1.14.0`, "bold")} - Modern monorepo versioning
|
|
181
181
|
|
|
182
182
|
Usage: bumpy <command> [options]
|
|
183
183
|
|
|
@@ -9,7 +9,7 @@ import { f as tagExists, l as hasUncommittedChanges, n as forcePushTag } from ".
|
|
|
9
9
|
import { n as willUseOidcExclusively, t as publishPackages } from "./publish-pipeline-BD8mLbL9.mjs";
|
|
10
10
|
import { channelNames, resolveActiveChannel } from "./channels-CFXZkyGd.mjs";
|
|
11
11
|
import { i as writeChannelVersionsInPlace, t as buildChannelReleasePlan } from "./prerelease-B2PVfXkm.mjs";
|
|
12
|
-
import { CI_PLAN_CACHE_PATH } from "./ci-
|
|
12
|
+
import { CI_PLAN_CACHE_PATH } from "./ci-BRJNl-VN.mjs";
|
|
13
13
|
//#region src/core/github-release.ts
|
|
14
14
|
var import_semver = /* @__PURE__ */ __toESM(require_semver(), 1);
|
|
15
15
|
/** Get the current HEAD commit SHA */
|