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

Function publishCommand

packages/bumpy/src/commands/publish.ts:72–164  ·  view source on GitHub ↗
(
  rootDir: string,
  opts: PublishCommandOptions,
)

Source from the content-addressed store, hash-verified

70 * transiently into the working tree, published to the channel's dist-tag, and restored.
71 */
72export async function publishCommand(
73 rootDir: string,
74 opts: PublishCommandOptions,
75): Promise<SnapshotPublishOutcome | null | void> {
76 const config = await loadConfig(rootDir);
77 const { packages, catalogs } = await discoverWorkspace(rootDir, config);
78 const { packageManager: detectedPm } = await detectWorkspaces(rootDir);
79 const depGraph = new DependencyGraph(packages);
80
81 if (!opts.dryRun && hasUncommittedChanges({ cwd: rootDir })) {
82 log.warn('You have uncommitted changes. Commit or stash them before publishing.');
83 process.exit(1);
84 }
85
86 // Snapshots are a distinct, transient release model — never mixed with the channel flow.
87 if (opts.snapshot !== undefined) {
88 if (opts.channel !== undefined) {
89 log.error('--snapshot and --channel cannot be used together — they are distinct release models.');
90 process.exit(1);
91 }
92 return await publishSnapshot(rootDir, config, packages, catalogs, detectedPm, depGraph, opts);
93 }
94
95 const channel = resolveActiveChannel(rootDir, config, opts.channel);
96 if (channel) {
97 await publishChannel(rootDir, config, packages, catalogs, detectedPm, depGraph, channel, opts);
98 return;
99 }
100
101 // Find packages that need publishing — use cached plan from `ci plan` if available,
102 // otherwise query the registry
103 let toPublish = await findUnpublishedWithCache(rootDir, packages, config);
104
105 // When channels are configured, prerelease versions must never reach the stable
106 // flow (they'd land on @latest). With the no-commit model this can't normally
107 // happen — committed versions are always stable — so a suffixed version here
108 // means something went wrong. Refuse loudly rather than publish it.
109 if (Object.keys(config.channels || {}).length > 0) {
110 const prereleases = toPublish.filter((r) => semver.prerelease(r.newVersion) !== null);
111 if (prereleases.length > 0) {
112 log.error('Refusing to publish prerelease versions outside a channel:');
113 for (const r of prereleases) log.error(` • ${r.name}@${r.newVersion}`);
114 log.error('Prerelease versions should never be committed — see https://bumpy.varlock.dev/docs/prereleases');
115 process.exit(1);
116 }
117 }
118
119 // Exclude packages with pending non-none bumps (they'll be superseded by the next version PR)
120 if (opts.excludePackages && opts.excludePackages.size > 0) {
121 const excluded = toPublish.filter((r) => opts.excludePackages!.has(r.name));
122 if (excluded.length > 0) {
123 for (const r of excluded) {
124 log.dim(` Skipping ${r.name}@${r.newVersion} — pending bump will supersede this version`);
125 }
126 toPublish = toPublish.filter((r) => !opts.excludePackages!.has(r.name));
127 }
128 }
129

Callers 5

mainFunction · 0.85
ciReleaseCommandFunction · 0.85
autoPublishFunction · 0.85
ciSnapshotReleaseFunction · 0.85
ciChannelReleaseFunction · 0.85

Calls 10

loadConfigFunction · 0.90
discoverWorkspaceFunction · 0.90
detectWorkspacesFunction · 0.90
hasUncommittedChangesFunction · 0.90
resolveActiveChannelFunction · 0.90
publishSnapshotFunction · 0.85
publishChannelFunction · 0.85
findUnpublishedWithCacheFunction · 0.85
matchGlobFunction · 0.85
runPublishFlowFunction · 0.85

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…