* CI release on a channel branch. Two independent steps, both of which can run * in the same invocation: * * 1. **Publish** — if this push moved bump files into `.bumpy/ /` (a release * PR merge), publish the cycle as prereleases. Versions are derived (targets from * bump files, c
( rootDir: string, config: BumpyConfig, channel: ResolvedChannel, opts: ReleaseOptions, )
| 986 | * create/update the file-move release PR. |
| 987 | */ |
| 988 | async function ciChannelRelease( |
| 989 | rootDir: string, |
| 990 | config: BumpyConfig, |
| 991 | channel: ResolvedChannel, |
| 992 | opts: ReleaseOptions, |
| 993 | ): Promise<void> { |
| 994 | log.bold(`Channel "${channel.name}" (branch "${channel.branch}")\n`); |
| 995 | const { packages } = await discoverWorkspace(rootDir, config); |
| 996 | const { bumpFiles, errors: parseErrors } = await readBumpFiles(rootDir, { channels: channelNames(config) }); |
| 997 | if (parseErrors.length > 0) { |
| 998 | for (const err of parseErrors) log.error(err); |
| 999 | throw new Error('Bump file parse errors must be fixed before releasing.'); |
| 1000 | } |
| 1001 | |
| 1002 | const pending = bumpFiles.filter((bf) => bf.channel !== channel.name); |
| 1003 | |
| 1004 | if (opts.autoPublish) { |
| 1005 | // Skip the release PR: move pending files, commit and push directly to the |
| 1006 | // channel branch, then publish. (The push re-triggers CI; the re-run is a no-op |
| 1007 | // thanks to the published-from-HEAD skip.) |
| 1008 | if (pending.length > 0) { |
| 1009 | const { channelVersion } = await import('./version.ts'); |
| 1010 | const result = await channelVersion(rootDir, config, channel, { commit: true }); |
| 1011 | if (result) { |
| 1012 | runArgs(['git', 'push', '--no-verify'], { cwd: rootDir }); |
| 1013 | } |
| 1014 | } |
| 1015 | const { publishCommand } = await import('./publish.ts'); |
| 1016 | await publishCommand(rootDir, { channel: channel.name, tag: opts.tag }); |
| 1017 | return; |
| 1018 | } |
| 1019 | |
| 1020 | // Step 1: publish if this push merged a release PR (moved files into the channel dir) |
| 1021 | const movedIds = detectChannelMoves(rootDir, channel); |
| 1022 | const shouldPublish = movedIds.length > 0 && opts.assertMode !== 'version-pr'; |
| 1023 | if (shouldPublish) { |
| 1024 | log.step(`Release PR merge detected (${movedIds.map((id) => `${id}.md`).join(', ')}) — publishing prereleases...`); |
| 1025 | const { publishCommand } = await import('./publish.ts'); |
| 1026 | await publishCommand(rootDir, { channel: channel.name, tag: opts.tag }); |
| 1027 | } |
| 1028 | |
| 1029 | if (opts.assertMode === 'publish') { |
| 1030 | if (!shouldPublish) { |
| 1031 | throw new Error( |
| 1032 | 'Expected mode "publish" but this push did not move bump files into the channel dir. ' + |
| 1033 | 'Either remove --expect-mode, or gate this step on the output of "bumpy ci plan".', |
| 1034 | ); |
| 1035 | } |
| 1036 | return; |
| 1037 | } |
| 1038 | |
| 1039 | // Step 2: create/update the release PR for pending bump files |
| 1040 | if (pending.length > 0) { |
| 1041 | await createChannelReleasePr(rootDir, config, channel, packages, opts.branch); |
| 1042 | } else if (!shouldPublish) { |
| 1043 | log.info(`Nothing to do on channel "${channel.name}" — no pending bump files, no release PR merge in this push.`); |
| 1044 | } |
| 1045 | } |
no test coverage detected
searching dependent graphs…