(
rootDir: string,
config: BumpyConfig,
channel: ResolvedChannel,
opts: { commit?: boolean } = {},
)
| 112 | * as shipped on this channel. |
| 113 | */ |
| 114 | export async function channelVersion( |
| 115 | rootDir: string, |
| 116 | config: BumpyConfig, |
| 117 | channel: ResolvedChannel, |
| 118 | opts: { commit?: boolean } = {}, |
| 119 | ): Promise<ChannelVersionResult | null> { |
| 120 | const packages = await discoverPackages(rootDir, config); |
| 121 | const depGraph = new DependencyGraph(packages); |
| 122 | const { bumpFiles, errors: parseErrors } = await readBumpFiles(rootDir, { channels: channelNames(config) }); |
| 123 | |
| 124 | if (parseErrors.length > 0) { |
| 125 | for (const err of parseErrors) { |
| 126 | log.error(err); |
| 127 | } |
| 128 | throw new Error('Bump file parse errors must be fixed before versioning.'); |
| 129 | } |
| 130 | |
| 131 | // A bump file is pending for this channel unless it's already in this channel's dir |
| 132 | const pending = bumpFiles.filter((bf) => bf.channel !== channel.name); |
| 133 | |
| 134 | if (pending.length === 0) { |
| 135 | log.info(`No pending bump files for channel "${channel.name}".`); |
| 136 | return null; |
| 137 | } |
| 138 | |
| 139 | // The full cycle (pending + shipped) determines the targets — show them, suffixed. |
| 140 | // Counters come from the registry at publish time, so they render as ".?" here. |
| 141 | const cyclePlan = assembleReleasePlan(bumpFiles, packages, depGraph, config, { |
| 142 | prereleasePreid: channel.preid, |
| 143 | }); |
| 144 | |
| 145 | if (cyclePlan.warnings.length > 0) { |
| 146 | for (const w of cyclePlan.warnings) { |
| 147 | log.warn(w); |
| 148 | } |
| 149 | console.log(); |
| 150 | } |
| 151 | |
| 152 | log.step(`Channel "${channel.name}" — moving ${pending.length} bump file(s) into .bumpy/${channel.name}/:`); |
| 153 | for (const bf of pending) { |
| 154 | const from = bf.channel ? `.bumpy/${bf.channel}/` : '.bumpy/'; |
| 155 | console.log(` ${from}${bf.id}.md → .bumpy/${channel.name}/${bf.id}.md`); |
| 156 | } |
| 157 | console.log(); |
| 158 | log.step('Cycle targets (counters are derived from the registry at publish time):'); |
| 159 | for (const r of cyclePlan.releases) { |
| 160 | const tag = r.isDependencyBump ? ' (dep)' : r.isCascadeBump ? ' (cascade)' : ''; |
| 161 | console.log(` ${r.name}: ${r.oldVersion} → ${colorize(`${r.newVersion}-${channel.preid}.x`, 'cyan')}${tag}`); |
| 162 | } |
| 163 | |
| 164 | await moveBumpFilesToChannel(rootDir, pending, channel.name); |
| 165 | log.success(`🐸 Moved ${pending.length} bump file(s) — no versions written (prereleases are derived, not committed)`); |
| 166 | |
| 167 | if (opts.commit) { |
| 168 | try { |
| 169 | runArgs(['git', 'add', '-A', '.bumpy/'], { cwd: rootDir }); |
| 170 | const summary = pending.map((bf) => `${bf.id}.md`).join(', '); |
| 171 | const msg = `Version prerelease (${channel.name})\n\nShipped: ${summary}`; |
no test coverage detected
searching dependent graphs…