* Publish a prerelease cycle from a channel branch. * * The cycle = every bump file on the branch (pending at root or in other channels' * dirs, plus shipped in this channel's dir). The whole cycle republishes together * each time so the channel dist-tag always points at one coherent, exact-pinn
( rootDir: string, config: BumpyConfig, packages: Map<string, WorkspacePackage>, catalogs: CatalogMap, detectedPm: PackageManager, depGraph: DependencyGraph, channel: ResolvedChannel, opts: PublishCommandOptions, )
| 171 | * each time so the channel dist-tag always points at one coherent, exact-pinned set. |
| 172 | */ |
| 173 | async function publishChannel( |
| 174 | rootDir: string, |
| 175 | config: BumpyConfig, |
| 176 | packages: Map<string, WorkspacePackage>, |
| 177 | catalogs: CatalogMap, |
| 178 | detectedPm: PackageManager, |
| 179 | depGraph: DependencyGraph, |
| 180 | channel: ResolvedChannel, |
| 181 | opts: PublishCommandOptions, |
| 182 | ): Promise<void> { |
| 183 | const { bumpFiles, errors: parseErrors } = await readBumpFiles(rootDir, { channels: channelNames(config) }); |
| 184 | if (parseErrors.length > 0) { |
| 185 | for (const err of parseErrors) log.error(err); |
| 186 | process.exit(1); |
| 187 | } |
| 188 | |
| 189 | const shipped = bumpFiles.filter((bf) => bf.channel === channel.name); |
| 190 | if (shipped.length === 0) { |
| 191 | log.info( |
| 192 | `Nothing has shipped on channel "${channel.name}" yet (no bump files in .bumpy/${channel.name}/).\n` + |
| 193 | ` Run \`bumpy version\` on the channel branch (or merge the release PR) first.`, |
| 194 | ); |
| 195 | return; |
| 196 | } |
| 197 | |
| 198 | log.bold(`Channel "${channel.name}" — preid "-${channel.preid}.N", dist-tag @${channel.tag}\n`); |
| 199 | |
| 200 | // Targets from the full cycle's bump files; counters from the registry. |
| 201 | const stablePlan = assembleReleasePlan(bumpFiles, packages, depGraph, config, { |
| 202 | prereleasePreid: channel.preid, |
| 203 | }); |
| 204 | const { plan, alreadyPublished, warnings } = await buildChannelReleasePlan(stablePlan, channel, packages, rootDir); |
| 205 | |
| 206 | for (const w of warnings) log.warn(w); |
| 207 | for (const skip of alreadyPublished) { |
| 208 | log.dim(` Skipping ${skip.name}@${skip.version} — already published from this commit`); |
| 209 | } |
| 210 | |
| 211 | if (plan.releases.length === 0) { |
| 212 | log.info('All cycle packages already published from this commit.'); |
| 213 | return; |
| 214 | } |
| 215 | |
| 216 | // Filter only restricts what gets *published* — the in-place rewrite below still |
| 217 | // covers the whole plan so dependency pins stay consistent (used for partial-failure resume). |
| 218 | let toPublish = plan.releases; |
| 219 | if (opts.filter) { |
| 220 | const { matchGlob } = await import('../core/config.ts'); |
| 221 | const patterns = opts.filter.split(',').map((p) => p.trim()); |
| 222 | toPublish = toPublish.filter((r) => patterns.some((p) => matchGlob(r.name, p))); |
| 223 | if (toPublish.length === 0) { |
| 224 | log.info('No cycle packages match the filter.'); |
| 225 | return; |
| 226 | } |
| 227 | } |
| 228 | |
| 229 | // Transiently write computed versions + exact pins into the working tree so |
| 230 | // pack/build see them; always restored afterwards — prereleases never land in git. |
no test coverage detected
searching dependent graphs…