Skip to content

Commit 6ca52ea

Browse files
committed
feat: make ci check comment channel-aware
When a PR targets a prerelease channel branch, the bumpy ci check comment now says so explicitly instead of implying a stable release: - headline: 'This PR targets the <name> prerelease channel — merging ships these as a prerelease to @<tag>, not a stable release' - versions display the derived '-<preid>.?' suffix (counter comes from the registry at publish time) - a note with the dist-tag install hint and how to promote to stable - plan uses the prerelease preid so the wider channel cascade is shown Export formatReleasePlanComment and cover both stable and channel comment shapes with tests.
1 parent 0038295 commit 6ca52ea

2 files changed

Lines changed: 88 additions & 6 deletions

File tree

packages/bumpy/src/commands/ci.ts

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,9 @@ export async function ciCheckCommand(rootDir: string, opts: CheckOptions): Promi
120120
// For PRs targeting a channel branch, compare against that branch (GITHUB_BASE_REF),
121121
// not baseBranch — otherwise the whole cycle's changes would show up.
122122
const compareBranch = process.env.GITHUB_BASE_REF || config.baseBranch;
123+
// If this PR targets a channel branch, the comment makes that explicit (prerelease,
124+
// dist-tag) rather than implying a normal stable release.
125+
const prChannel = matchChannelByBranch(config, process.env.GITHUB_BASE_REF || null);
123126
const changedFiles = getChangedFiles(rootDir, compareBranch);
124127
const { branchBumpFiles: prBumpFiles, emptyBumpFileIds } = filterBranchBumpFiles(
125128
allBumpFiles,
@@ -180,13 +183,25 @@ export async function ciCheckCommand(rootDir: string, opts: CheckOptions): Promi
180183
return;
181184
}
182185

183-
const plan = assembleReleasePlan(prBumpFiles, packages, depGraph, config);
186+
// On a channel-targeted PR, plan with the prerelease preid so the wider cascade
187+
// (every dependent joins the cycle) is reflected accurately in the preview.
188+
const plan = assembleReleasePlan(
189+
prBumpFiles,
190+
packages,
191+
depGraph,
192+
config,
193+
prChannel ? { prereleasePreid: prChannel.preid } : {},
194+
);
184195

185196
// Pretty output for logs
186-
log.bold(`${prBumpFiles.length} bump file(s) → ${plan.releases.length} package(s) to release\n`);
197+
const releaseSuffix = prChannel ? `-${prChannel.preid}.?` : '';
198+
log.bold(
199+
`${prBumpFiles.length} bump file(s) → ${plan.releases.length} package(s) to release` +
200+
`${prChannel ? ` on the "${prChannel.name}" channel (@${prChannel.tag})` : ''}\n`,
201+
);
187202
for (const r of plan.releases) {
188203
const tag = r.isDependencyBump ? ' (dep)' : r.isCascadeBump ? ' (cascade)' : '';
189-
console.log(` ${r.name}: ${r.oldVersion}${colorize(r.newVersion, 'cyan')}${tag}`);
204+
console.log(` ${r.name}: ${r.oldVersion}${colorize(`${r.newVersion}${releaseSuffix}`, 'cyan')}${tag}`);
190205
}
191206
if (plan.warnings.length > 0) {
192207
for (const w of plan.warnings) {
@@ -206,6 +221,7 @@ export async function ciCheckCommand(rootDir: string, opts: CheckOptions): Promi
206221
plan.warnings,
207222
parseErrors,
208223
emptyBumpFileIds,
224+
prChannel,
209225
);
210226
await postOrUpdatePrComment(prNumber, comment, rootDir);
211227
}
@@ -1007,7 +1023,7 @@ function pmRunCommand(pm: PackageManager): string {
10071023
return 'npx bumpy';
10081024
}
10091025

1010-
function formatReleasePlanComment(
1026+
export function formatReleasePlanComment(
10111027
plan: ReleasePlan,
10121028
bumpFiles: BumpFile[],
10131029
prNumber: string,
@@ -1016,14 +1032,22 @@ function formatReleasePlanComment(
10161032
warnings: string[] = [],
10171033
parseErrors: string[] = [],
10181034
emptyBumpFileIds: string[] = [],
1035+
channel: ResolvedChannel | null = null,
10191036
): string {
10201037
const repo = process.env.GITHUB_REPOSITORY;
10211038
const lines: string[] = [];
10221039

1040+
// When targeting a prerelease channel, the version display carries the `-<preid>.?`
1041+
// suffix (the exact counter is derived from the registry at publish time).
1042+
const versionSuffix = channel ? `-${channel.preid}.?` : '';
1043+
1044+
const headline = channel
1045+
? `**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.`
1046+
: '**The changes in this PR will be included in the next version bump.**';
10231047
const preamble = [
10241048
`<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>`,
10251049
'',
1026-
'**The changes in this PR will be included in the next version bump.**',
1050+
headline,
10271051
'<br clear="left" />',
10281052
].join('\n');
10291053
lines.push(preamble);
@@ -1043,11 +1067,23 @@ function formatReleasePlanComment(
10431067
lines.push('');
10441068
for (const r of releases) {
10451069
const suffix = r.isDependencyBump ? ' _(dep)_' : r.isCascadeBump ? ' _(cascade)_' : '';
1046-
lines.push(`- \`${r.name}\` ${r.oldVersion} → **${r.newVersion}**${suffix}`);
1070+
lines.push(`- \`${r.name}\` ${r.oldVersion} → **${r.newVersion}${versionSuffix}**${suffix}`);
10471071
}
10481072
lines.push('');
10491073
}
10501074

1075+
if (channel) {
1076+
const examplePkg =
1077+
plan.releases.find((r) => !r.isDependencyBump && !r.isCascadeBump)?.name ?? plan.releases[0]?.name;
1078+
const installHint = examplePkg ? ` (e.g. \`npm i ${examplePkg}@${channel.tag}\`)` : '';
1079+
lines.push(
1080+
`> 🔀 Published to the \`@${channel.tag}\` dist-tag${installHint}. ` +
1081+
`Prerelease versions are derived at publish time — the \`.?\` counter is filled in from the registry. ` +
1082+
`Promote to a stable release by merging \`${channel.branch}\` into your base branch.`,
1083+
);
1084+
lines.push('');
1085+
}
1086+
10511087
// Bump file list with links
10521088
lines.push(`#### Bump files in this PR`);
10531089
lines.push('');
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { describe, test, expect } from 'bun:test';
2+
import { formatReleasePlanComment } from '../../src/commands/ci.ts';
3+
import { resolveChannels } from '../../src/core/channels.ts';
4+
import { makeRelease, makeReleasePlan, makeBumpFile, makeConfig } from '../helpers.ts';
5+
6+
const channel = resolveChannels(makeConfig({ channels: { next: { branch: 'next', preid: 'rc', tag: 'next' } } })).get(
7+
'next',
8+
)!;
9+
10+
const plan = makeReleasePlan(
11+
[makeRelease('@myorg/core', '1.2.0', { type: 'minor', oldVersion: '1.1.0', bumpFiles: ['feat'] })],
12+
[makeBumpFile('feat', [{ name: '@myorg/core', type: 'minor' }], 'Add a feature')],
13+
);
14+
15+
describe('formatReleasePlanComment — stable (no channel)', () => {
16+
const comment = formatReleasePlanComment(plan, plan.bumpFiles, '1', 'feature-branch', 'npm');
17+
18+
test('uses the normal "next version bump" headline', () => {
19+
expect(comment).toContain('included in the next version bump');
20+
expect(comment).not.toContain('prerelease channel');
21+
});
22+
23+
test('shows plain stable versions (no preid suffix)', () => {
24+
expect(comment).toContain('1.1.0 → **1.2.0**');
25+
expect(comment).not.toContain('-rc.');
26+
});
27+
});
28+
29+
describe('formatReleasePlanComment — prerelease channel', () => {
30+
const comment = formatReleasePlanComment(plan, plan.bumpFiles, '1', 'feature-branch', 'npm', [], [], [], channel);
31+
32+
test('headline makes the channel + prerelease explicit', () => {
33+
expect(comment).toContain('`next` prerelease channel');
34+
expect(comment).toContain('prerelease');
35+
expect(comment).toContain('@next');
36+
});
37+
38+
test('versions carry the derived "-rc.?" suffix', () => {
39+
expect(comment).toContain('1.1.0 → **1.2.0-rc.?**');
40+
});
41+
42+
test('includes a dist-tag install hint and promotion note', () => {
43+
expect(comment).toContain('npm i @myorg/core@next');
44+
expect(comment).toContain('Promote to a stable release by merging `next`');
45+
});
46+
});

0 commit comments

Comments
 (0)