* Create or update the channel's release PR. Unlike the stable version PR, its diff * is pure file moves (pending bump files → `.bumpy/ /`) — no versions, no * changelogs. The PR title/body show targets with a wildcard counter (`1.2.0-rc.x`), * derived purely from committed state; the exa
(
rootDir: string,
config: BumpyConfig,
channel: ResolvedChannel,
packages: Map<string, import('../types.ts').WorkspacePackage>,
branchOverride?: string,
)
| 1051 | * derived purely from committed state; the exact counter is assigned at publish time. |
| 1052 | */ |
| 1053 | async function createChannelReleasePr( |
| 1054 | rootDir: string, |
| 1055 | config: BumpyConfig, |
| 1056 | channel: ResolvedChannel, |
| 1057 | packages: Map<string, import('../types.ts').WorkspacePackage>, |
| 1058 | branchOverride?: string, |
| 1059 | ): Promise<void> { |
| 1060 | const branch = validateBranchName(branchOverride || channel.versionPr.branch); |
| 1061 | const baseBranch = validateBranchName(channel.branch); |
| 1062 | |
| 1063 | // Check if a release PR already exists |
| 1064 | const existingPr = tryRunArgs(['gh', 'pr', 'list', '--head', branch, '--json', 'number', '--jq', '.[0].number'], { |
| 1065 | cwd: rootDir, |
| 1066 | }); |
| 1067 | |
| 1068 | log.step(`Creating branch ${branch}...`); |
| 1069 | const branchExists = tryRunArgs(['git', 'rev-parse', '--verify', branch], { cwd: rootDir }) !== null; |
| 1070 | if (branchExists) { |
| 1071 | runArgs(['git', 'checkout', branch], { cwd: rootDir }); |
| 1072 | runArgs(['git', 'reset', '--hard', baseBranch], { cwd: rootDir }); |
| 1073 | } else { |
| 1074 | runArgs(['git', 'checkout', '-b', branch], { cwd: rootDir }); |
| 1075 | } |
| 1076 | |
| 1077 | // Move pending bump files into the channel dir (the entire "version" step for a channel) |
| 1078 | const { channelVersion } = await import('./version.ts'); |
| 1079 | const result = await channelVersion(rootDir, config, channel); |
| 1080 | if (!result) { |
| 1081 | log.info('No pending bump files to move.'); |
| 1082 | runArgs(['git', 'checkout', baseBranch], { cwd: rootDir }); |
| 1083 | return; |
| 1084 | } |
| 1085 | |
| 1086 | // Versions shown in the PR title/body/commit message are deterministic: targets |
| 1087 | // come from committed bump files; the counter is a wildcard (`-rc.x`) because the |
| 1088 | // real one is derived from the registry at publish time and could drift by merge. |
| 1089 | const displayPlan = channelDisplayPlan(result.cyclePlan, channel, packages); |
| 1090 | |
| 1091 | const versionSummary = formatChannelVersionSummary(displayPlan.releases); |
| 1092 | const prTitle = versionSummary ? `${channel.versionPr.title}: ${versionSummary}` : channel.versionPr.title; |
| 1093 | |
| 1094 | // Commit the moves — the version summary lives in the commit message, so |
| 1095 | // `git log` on the channel branch reads as a release history |
| 1096 | runArgs(['git', 'add', '-A', '.bumpy/'], { cwd: rootDir }); |
| 1097 | const status = tryRunArgs(['git', 'status', '--porcelain'], { cwd: rootDir }); |
| 1098 | if (!status) { |
| 1099 | log.info('No changes to commit.'); |
| 1100 | runArgs(['git', 'checkout', baseBranch], { cwd: rootDir }); |
| 1101 | return; |
| 1102 | } |
| 1103 | const commitMsg = `${prTitle}\n\nShipped: ${result.movedFiles.map((bf) => `${bf.id}.md`).join(', ')}`; |
| 1104 | runArgs(['git', 'commit', '-F', '-'], { cwd: rootDir, input: commitMsg }); |
| 1105 | |
| 1106 | pushWithToken(rootDir, branch, config); |
| 1107 | |
| 1108 | const repo = process.env.GITHUB_REPOSITORY; |
| 1109 | const noPatWarning = !process.env.BUMPY_GH_TOKEN && !!repo; |
| 1110 | const packageDirs = new Map([...packages.values()].map((p) => [p.name, p.relativeDir])); |
no test coverage detected
searching dependent graphs…