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

Function buildChannelReleasePlan

packages/bumpy/src/core/prerelease.ts:125–185  ·  view source on GitHub ↗
(
  stablePlan: ReleasePlan,
  channel: ResolvedChannel,
  packages: Map<string, WorkspacePackage>,
  rootDir: string,
  opts: {
    /**
     * Display mode (release PR titles/bodies, status output): compute counters but
     * skip the published-from-HEAD checks — the numbers are advisory narrative and
     * the registry wins at actual publish time.
     */
    forDisplay?: boolean;
  } = {},
)

Source from the content-addressed store, hash-verified

123 * gitHead equal to HEAD (or, for non-npm packages, its tag points at HEAD), the package
124 * was already published from this exact commit — it is skipped rather than re-counted.
125 */
126export async function buildChannelReleasePlan(
127 stablePlan: ReleasePlan,
128 channel: ResolvedChannel,
129 packages: Map<string, WorkspacePackage>,
130 rootDir: string,
131 opts: {
132 /**
133 * Display mode (release PR titles/bodies, status output): compute counters but
134 * skip the published-from-HEAD checks — the numbers are advisory narrative and
135 * the registry wins at actual publish time.
136 */
137 forDisplay?: boolean;
138 } = {},
139): Promise<ChannelReleasePlanResult> {
140 const headSha = tryRunArgs(['git', 'rev-parse', 'HEAD'], { cwd: rootDir });
141 const warnings: string[] = [...stablePlan.warnings];
142 const alreadyPublished: Array<{ name: string; version: string }> = [];
143 const releases: PlannedRelease[] = [];
144
145 await Promise.all(
146 stablePlan.releases.map(async (release) => {
147 const pkg = packages.get(release.name);
148 if (!pkg) return;
149 // Unpublishable packages can't participate in a registry-consumable cycle
150 if (pkg.private && !pkg.bumpy?.publishCommand) return;
151
152 const target = release.newVersion; // stable target from the bump files
153 const state = await getPublishedPrereleaseState(pkg, target, channel.preid, rootDir);
154
155 if (state.stablePublished) {
156 warnings.push(
157 `${release.name}@${target} is already published as a stable release — ` +
158 `merge ${target}'s release into the "${channel.branch}" branch so the cycle retargets.`,
159 );
160 }
161
162 if (!opts.forDisplay && state.counters.length > 0 && headSha) {
163 const latest = `${target}-${channel.preid}.${Math.max(...state.counters)}`;
164 const publishedFromHead = usesNpmRegistry(pkg)
165 ? (await fetchGitHead(pkg.name, latest, pkg.bumpy?.registry)) === headSha
166 : tryRunArgs(['git', 'rev-parse', `refs/tags/${pkg.name}@${latest}`], { cwd: rootDir }) === headSha;
167 if (publishedFromHead) {
168 alreadyPublished.push({ name: release.name, version: latest });
169 return;
170 }
171 }
172
173 releases.push({
174 ...release,
175 newVersion: nextPrereleaseVersion(target, channel.preid, state.counters),
176 });
177 }),
178 );
179
180 releases.sort((a, b) => a.name.localeCompare(b.name));
181 return {
182 plan: { bumpFiles: stablePlan.bumpFiles, releases, warnings },

Callers 3

channelStatusFunction · 0.90
ciChannelPlanFunction · 0.90
publishChannelFunction · 0.90

Calls 5

tryRunArgsFunction · 0.90
usesNpmRegistryFunction · 0.85
fetchGitHeadFunction · 0.85
nextPrereleaseVersionFunction · 0.85

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…