MCPcopy Create free account
hub / github.com/dmno-dev/bumpy / ciReleaseCommand

Function ciReleaseCommand

packages/bumpy/src/commands/ci.ts:547–622  ·  view source on GitHub ↗
(rootDir: string, opts: ReleaseOptions)

Source from the content-addressed store, hash-verified

545 if (pkgConfig.publishCommand) {
546 targets.push({ type: 'custom' });
547 }
548 if (!pkgConfig.publishCommand && !pkgConfig.skipNpmPublish) {
549 targets.push({ type: 'npm' });
550 }
551 return targets;
552}
553
554/** Write a key=value pair to $GITHUB_OUTPUT if available */
555function writeGitHubOutput(key: string, value: string): void {
556 const outputFile = process.env.GITHUB_OUTPUT;
557 if (!outputFile) return;
558 // Use delimiter protocol for multiline values
559 const delimiter = `ghadelimiter_${Date.now()}`;
560 appendFileSync(outputFile, `${key}<<${delimiter}\n${value}\n${delimiter}\n`);
561}
562
563// ---- ci release ----
564
565interface ReleaseOptions {
566 autoPublish?: boolean; // skip the version-PR step and version+publish in one shot
567 assertMode?: 'version-pr' | 'publish'; // refuse to run if detected mode doesn't match — see CiPlanMode
568 tag?: string; // npm dist-tag for auto-publish (or the snapshot dist-tag)
569 branch?: string; // branch name for version PR (default: "bumpy/version-packages")
570 snapshot?: string; // publish a transient snapshot under this name + comment install instructions on the PR
571}
572
573/**
574 * CI release: either create a version PR (bump files present) or publish unpublished
575 * packages (no bump files — i.e. a version PR was just merged). Pass `autoPublish` to
576 * collapse both steps into a single push-to-main, or `assertMode` to refuse running
577 * when the detected state doesn't match expectations (used by split-job workflows).
578 */
579export async function ciReleaseCommand(rootDir: string, opts: ReleaseOptions): Promise<void> {
580 const config = await loadConfig(rootDir);
581 ensureGitIdentity(rootDir, config);
582
583 // Snapshots are a one-shot transient release that can run from any branch (typically a
584 // feature PR), so they bypass the base/channel branch routing entirely.
585 if (opts.snapshot !== undefined) {
586 await ciSnapshotRelease(rootDir, opts);
587 return;
588 }
589
590 // Channel branches get the channel flow; unknown branches are refused (when channels
591 // are configured) so a misconfigured workflow can't publish from a feature branch.
592 const releaseBranch = detectReleaseBranch(rootDir);
593 const channel = matchChannelByBranch(config, releaseBranch);
594 if (channel) {
595 await ciChannelRelease(rootDir, config, channel, opts);
596 return;
597 }
598 if (Object.keys(config.channels || {}).length > 0 && releaseBranch && releaseBranch !== config.baseBranch) {
599 throw new Error(
600 `"bumpy ci release" ran on branch "${releaseBranch}", which is neither the base branch ` +
601 `("${config.baseBranch}") nor a configured channel branch. Refusing to release — ` +
602 'add the branch to "channels" in .bumpy/_config.json or fix the workflow trigger.',
603 );
604 }

Callers 1

mainFunction · 0.85

Calls 14

loadConfigFunction · 0.90
detectReleaseBranchFunction · 0.90
matchChannelByBranchFunction · 0.90
discoverWorkspaceFunction · 0.90
readBumpFilesFunction · 0.90
channelNamesFunction · 0.90
assembleReleasePlanFunction · 0.90
recoverDeletedBumpFilesFunction · 0.90
ensureGitIdentityFunction · 0.85
ciSnapshotReleaseFunction · 0.85
ciChannelReleaseFunction · 0.85
publishCommandFunction · 0.85

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…