@kb-labs/release-manager-core 2.104.0 → 2.105.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -134,6 +134,14 @@ interface FlowConfig {
134
134
  versioningStrategy?: 'lockstep' | 'independent' | 'adaptive';
135
135
  /** If set, replaces global checks for this flow. */
136
136
  checks?: CustomCheckConfig[];
137
+ /**
138
+ * Git tag template for this flow's stable releases. Tokens: `{flow}`
139
+ * (the flow's config key, e.g. "platform") and `{version}` (the release
140
+ * version). Default: `{flow}-v{version}` (e.g. `platform-v2.105.0`).
141
+ * Used both to generate the tag (`buildReleaseTag`) and to parse a tag
142
+ * back into a flow (`resolveFlowFromTag`) — see `./tag.ts`.
143
+ */
144
+ tagPattern?: string;
137
145
  }
138
146
  interface PackagesFilter {
139
147
  /** Glob dirs to scan, e.g. ['packages/*', 'apps/*'].
@@ -204,6 +212,12 @@ interface ReleaseConfig {
204
212
  };
205
213
  changelog?: {
206
214
  enabled?: boolean;
215
+ /**
216
+ * Where the consolidated repo-root changelog is written, relative to
217
+ * repoRoot. Default: '.kb/release/CHANGELOG.md'. Set to 'CHANGELOG.md'
218
+ * to write it at the repo root instead.
219
+ */
220
+ outputPath?: string;
207
221
  includeTypes?: string[];
208
222
  excludeTypes?: string[];
209
223
  ignoreAuthors?: string[];
@@ -313,6 +327,14 @@ interface PipelineOptions {
313
327
  skipChecks?: boolean;
314
328
  skipBuild?: boolean;
315
329
  skipVerify?: boolean;
330
+ /**
331
+ * Prepare-only mode: run checks/build/verify/version-bump/changelog and
332
+ * commit+tag git, but never call the publisher. No npm credentials are
333
+ * required. Intended for a local/CI "prepare" step whose git tag is the
334
+ * trigger for a separate CI job that runs `kb release promote` to do the
335
+ * actual npm publish. See plugins/release/docs/adr/0001-*.
336
+ */
337
+ skipPublish?: boolean;
316
338
  /** Custom check configs from kb.config.json */
317
339
  checks?: CustomCheckConfig[];
318
340
  /** Injected publisher (CLI = interactive OTP, REST = programmatic token) */
@@ -402,9 +424,18 @@ declare function copyChangelogToPackages(options: {
402
424
  plan: ReleasePlan;
403
425
  changelog: string;
404
426
  }): Promise<void>;
427
+ /** Default location of the consolidated repo-root changelog, relative to repoRoot. */
428
+ declare const DEFAULT_ROOT_CHANGELOG_PATH = ".kb/release/CHANGELOG.md";
429
+ /**
430
+ * Resolve the repo-relative path of the consolidated root changelog.
431
+ * Config-driven via `release.changelog.outputPath` so teams can point it at
432
+ * the conventional `CHANGELOG.md` repo root instead of the default.
433
+ */
434
+ declare function resolveRootChangelogRelPath(outputPath?: string): string;
405
435
  /**
406
436
  * Merge the generated changelog for this release into the repo-root
407
- * `.kb/release/CHANGELOG.md`, prepending/deduplicating the same way
437
+ * changelog file (default `.kb/release/CHANGELOG.md`, configurable via
438
+ * `release.changelog.outputPath`), prepending/deduplicating the same way
408
439
  * `copyChangelogToPackages` does for per-package changelogs — this file is
409
440
  * cumulative history, not a per-run snapshot, so it must never be overwritten.
410
441
  */
@@ -412,6 +443,8 @@ declare function mergeRootChangelog(options: {
412
443
  repoRoot: string;
413
444
  plan: ReleasePlan;
414
445
  changelog: string;
446
+ /** Repo-relative output path. Defaults to DEFAULT_ROOT_CHANGELOG_PATH. */
447
+ outputPath?: string;
415
448
  }): Promise<void>;
416
449
  /**
417
450
  * Commit and tag release changes
@@ -433,6 +466,19 @@ declare function commitAndTagRelease(options: {
433
466
  tagged: string[];
434
467
  pushed: boolean;
435
468
  }>;
469
+ /** Repo-relative path to the consolidated root changelog. Defaults to DEFAULT_ROOT_CHANGELOG_PATH. */
470
+ changelogOutputPath?: string;
471
+ /**
472
+ * The flow this release came from (e.g. "platform", "sdk"). Drives the
473
+ * tag grammar (`{flow}-v{version}`, see ./tag.ts). If omitted (ran
474
+ * without `--flow`), falls back to `"release"` and — for a genuinely
475
+ * divergent multi-version independent release — to the old one-tag-
476
+ * per-package behavior, since a single flow-level tag can't represent
477
+ * packages at different versions.
478
+ */
479
+ flowName?: string;
480
+ /** Per-flow tag template override, from `FlowConfig.tagPattern`. */
481
+ tagPattern?: string;
436
482
  }): Promise<{
437
483
  committed: boolean;
438
484
  tagged: string[];
@@ -531,6 +577,35 @@ declare function applyCanarySuffix(packages: PackageVersion[], shortSha: string)
531
577
  declare function resolvePublishTag(config: ReleaseConfig, channel: ReleaseChannel): string;
532
578
  declare function resolvePublishRegistry(config: ReleaseConfig, channel: ReleaseChannel): string;
533
579
 
580
+ /**
581
+ * Git tag grammar for release flows — one place that both generates a
582
+ * flow's release tag and parses a tag back into a flow. Keeping generation
583
+ * and resolution on the same template prevents them from drifting apart
584
+ * (previously tag-building was inlined ad hoc in `commitAndTagRelease` and
585
+ * nothing parsed a tag back into a flow at all — CI guessed via bash).
586
+ *
587
+ * Only stable-channel releases ever produce a git tag (canary is ephemeral,
588
+ * npm-only — see pipeline.ts), so a resolved tag always implies `channel:
589
+ * 'stable'`; it is never inferred from the tag itself.
590
+ */
591
+
592
+ declare const DEFAULT_TAG_PATTERN = "{flow}-v{version}";
593
+ /**
594
+ * Build the release tag for a flow. `tagPattern` defaults to
595
+ * `{flow}-v{version}` (e.g. `platform-v2.105.0`) when omitted.
596
+ */
597
+ declare function buildReleaseTag(flowName: string, version: string, tagPattern?: string): string;
598
+ /**
599
+ * Resolve a git tag back into the flow (and channel) that produced it, by
600
+ * matching it against every configured flow's tag pattern. Returns `null`
601
+ * if no configured flow's pattern matches — callers (e.g. `deliver`) must
602
+ * treat that as a hard failure, never a guess.
603
+ */
604
+ declare function resolveFlowFromTag(config: ReleaseConfig, tag: string): {
605
+ flowName: string;
606
+ channel: ReleaseChannel;
607
+ } | null;
608
+
534
609
  /**
535
610
  * Unified release pipeline — single orchestrator for CLI and REST.
536
611
  *
@@ -640,6 +715,13 @@ interface VerifyAgainstRegistryOptions {
640
715
  registry: string;
641
716
  /** Timeout (ms) for the registry HTTP check and the `npm pack` round-trip. Default: 30000. */
642
717
  timeout?: number;
718
+ /**
719
+ * Extra attempts for the "is it published yet" check before giving up —
720
+ * each retry waits `retryDelaysMs[attempt]` (capped at the last entry).
721
+ * Default: 0 (single attempt, matches pre-existing Verdaccio behavior).
722
+ */
723
+ retries?: number;
724
+ retryDelaysMs?: readonly number[];
643
725
  logger?: Pick<PluginLogger, 'info' | 'warn'>;
644
726
  }
645
727
  /**
@@ -674,4 +756,4 @@ declare function verifyAgainstRegistry(packages: PublishablePackage[], options:
674
756
  */
675
757
  declare function resolveScopePath(repoRoot: string, scope: string): Promise<string>;
676
758
 
677
- export { type AuditSummary, type BuildResult, type ChangelogGenerator, type CheckId, type CheckResult, type CheckResultDetails, type CustomCheckConfig, type FlowConfig, type PackagePublisher, type PackageVersion, type PackagesFilter, type PipelineOptions, type PipelineResult, type PlannerOptions, type PluginLogger, type PublishResult, type PublishablePackage, type ReleaseChannel, type ReleaseConfig, type ReleaseContext, type ReleasePlan, type ReleaseReport, type ReleaseResult, type ReleaseStage, type RollbackSnapshot, type StrategyOptions, type VerifyResult, type VersionBump, type VersionStrategy, applyCanarySuffix, applyVersionStrategy, buildPackages, commitAndTagRelease, copyChangelogToPackages, createExecaShellAdapter, discoverCurrentPackages, isBuildCommand, isVersionPublished, matchesPackagePattern, mergeConfigWithFlow, mergeRootChangelog, planRelease, renderJson, renderMarkdown, renderText, resolvePublishRegistry, resolvePublishTag, resolveScopePath, restoreSnapshot, runReleaseChecks, runReleasePipeline, runSafeBuild, saveSnapshot, spawnCommand, updatePackageVersion, updatePackageVersions, verifyAgainstRegistry, verifyExtractedTarball, verifyPackage, verifyPackages };
759
+ export { type AuditSummary, type BuildResult, type ChangelogGenerator, type CheckId, type CheckResult, type CheckResultDetails, type CustomCheckConfig, DEFAULT_ROOT_CHANGELOG_PATH, DEFAULT_TAG_PATTERN, type FlowConfig, type PackagePublisher, type PackageVersion, type PackagesFilter, type PipelineOptions, type PipelineResult, type PlannerOptions, type PluginLogger, type PublishResult, type PublishablePackage, type ReleaseChannel, type ReleaseConfig, type ReleaseContext, type ReleasePlan, type ReleaseReport, type ReleaseResult, type ReleaseStage, type RollbackSnapshot, type StrategyOptions, type VerifyResult, type VersionBump, type VersionStrategy, applyCanarySuffix, applyVersionStrategy, buildPackages, buildReleaseTag, commitAndTagRelease, copyChangelogToPackages, createExecaShellAdapter, discoverCurrentPackages, isBuildCommand, isVersionPublished, matchesPackagePattern, mergeConfigWithFlow, mergeRootChangelog, planRelease, renderJson, renderMarkdown, renderText, resolveFlowFromTag, resolvePublishRegistry, resolvePublishTag, resolveRootChangelogRelPath, resolveScopePath, restoreSnapshot, runReleaseChecks, runReleasePipeline, runSafeBuild, saveSnapshot, spawnCommand, updatePackageVersion, updatePackageVersions, verifyAgainstRegistry, verifyExtractedTarball, verifyPackage, verifyPackages };
package/dist/index.js CHANGED
@@ -507,6 +507,32 @@ function isCheckpointResumable(checkpoint, flow, version) {
507
507
  return checkpoint.publishedPackages.length > 0 && Object.values(checkpoint.gitRoots).some((s) => !s.pushed);
508
508
  }
509
509
 
510
+ // src/tag.ts
511
+ var DEFAULT_TAG_PATTERN = "{flow}-v{version}";
512
+ function escapeRegex(str) {
513
+ return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
514
+ }
515
+ var SEMVER_SRC = "\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?(?:\\+[0-9A-Za-z.-]+)?";
516
+ function buildReleaseTag(flowName, version, tagPattern) {
517
+ const pattern = tagPattern ?? DEFAULT_TAG_PATTERN;
518
+ return pattern.replace("{flow}", flowName).replace("{version}", version);
519
+ }
520
+ function buildTagRegex(flowName, tagPattern) {
521
+ const escapedPattern = escapeRegex(tagPattern);
522
+ const src = escapedPattern.replace(escapeRegex("{flow}"), escapeRegex(flowName)).replace(escapeRegex("{version}"), `(${SEMVER_SRC})`);
523
+ return new RegExp(`^${src}$`);
524
+ }
525
+ function resolveFlowFromTag(config, tag) {
526
+ const flows = config.flows ?? {};
527
+ for (const [flowName, flowConfig] of Object.entries(flows)) {
528
+ const regex = buildTagRegex(flowName, flowConfig.tagPattern ?? DEFAULT_TAG_PATTERN);
529
+ if (regex.test(tag)) {
530
+ return { flowName, channel: "stable" };
531
+ }
532
+ }
533
+ return null;
534
+ }
535
+
510
536
  // src/publisher.ts
511
537
  async function updatePackageVersion(pkg) {
512
538
  const packageJsonPath = join(pkg.path, "package.json");
@@ -594,8 +620,12 @@ function mergeChangelogBlock(existingChangelog, newBlock, versionPattern) {
594
620
  }
595
621
  return newBlock + (existingChangelog ? "\n" + existingChangelog : "");
596
622
  }
623
+ var DEFAULT_ROOT_CHANGELOG_PATH = ".kb/release/CHANGELOG.md";
624
+ function resolveRootChangelogRelPath(outputPath) {
625
+ return outputPath && outputPath.trim().length > 0 ? outputPath : DEFAULT_ROOT_CHANGELOG_PATH;
626
+ }
597
627
  async function mergeRootChangelog(options) {
598
- const { repoRoot, plan, changelog } = options;
628
+ const { repoRoot, plan, changelog, outputPath } = options;
599
629
  if (!changelog || changelog.trim().length === 0 || plan.packages.length === 0) {
600
630
  return;
601
631
  }
@@ -606,15 +636,14 @@ async function mergeRootChangelog(options) {
606
636
  `^##\\s+${primary.name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\s+${primary.nextVersion.replace(/\./g, "\\.")}`,
607
637
  "m"
608
638
  );
609
- const releaseDir = join(repoRoot, ".kb", "release");
610
- const changelogPath = join(releaseDir, "CHANGELOG.md");
639
+ const changelogPath = join(repoRoot, resolveRootChangelogRelPath(outputPath));
611
640
  let existingChangelog = "";
612
641
  try {
613
642
  existingChangelog = await readFile(changelogPath, "utf-8");
614
643
  } catch {
615
644
  }
616
645
  const updatedChangelog = mergeChangelogBlock(existingChangelog, changelog.trim(), versionPattern);
617
- await mkdir(releaseDir, { recursive: true });
646
+ await mkdir(dirname(changelogPath), { recursive: true });
618
647
  await writeFile(changelogPath, updatedChangelog.trim() + "\n", "utf-8");
619
648
  }
620
649
  function createPackageChangelog(pkg, changelog) {
@@ -644,7 +673,7 @@ function createPackageChangelog(pkg, changelog) {
644
673
  return changelog.substring(startIdx, endIdx).trim();
645
674
  }
646
675
  async function commitAndTagRelease(options) {
647
- const { cwd, plan, dryRun, noVerify = false, repoRoot, checkpointGitRoots } = options;
676
+ const { cwd, plan, dryRun, noVerify = false, repoRoot, checkpointGitRoots, changelogOutputPath, flowName = "release", tagPattern } = options;
648
677
  const simpleGit2 = (await import('simple-git')).default;
649
678
  const result = {
650
679
  committed: false,
@@ -668,7 +697,7 @@ async function commitAndTagRelease(options) {
668
697
  rootToPkgs.set(root, list);
669
698
  }
670
699
  const uniqueVersions = new Set(plan.packages.map((p) => p.nextVersion));
671
- const isLockstep = plan.packages.length > 1 && uniqueVersions.size === 1;
700
+ const singleVersionAcrossPlan = uniqueVersions.size === 1;
672
701
  const pushFlags = noVerify ? ["--no-verify"] : [];
673
702
  for (const [root, pkgs] of rootToPkgs) {
674
703
  const prior = checkpointGitRoots?.[root];
@@ -692,9 +721,10 @@ async function commitAndTagRelease(options) {
692
721
  }
693
722
  }
694
723
  if (repoRoot && root === repoRoot) {
695
- const rootChangelogPath = join(repoRoot, ".kb", "release", "CHANGELOG.md");
724
+ const rootChangelogRelPath = resolveRootChangelogRelPath(changelogOutputPath);
725
+ const rootChangelogPath = join(repoRoot, rootChangelogRelPath);
696
726
  if (existsSync(rootChangelogPath)) {
697
- filesToStage.push(".kb/release/CHANGELOG.md");
727
+ filesToStage.push(rootChangelogRelPath);
698
728
  }
699
729
  }
700
730
  await rootGit.add(filesToStage);
@@ -712,8 +742,8 @@ async function commitAndTagRelease(options) {
712
742
  result.committed = true;
713
743
  }
714
744
  if (rootTagged.length === 0) {
715
- if (isLockstep) {
716
- const tagName = `v${plan.packages[0].nextVersion}`;
745
+ if (singleVersionAcrossPlan) {
746
+ const tagName = buildReleaseTag(flowName, plan.packages[0].nextVersion, tagPattern);
717
747
  await rootGit.addTag(tagName);
718
748
  rootTagged = [tagName];
719
749
  } else {
@@ -1356,18 +1386,36 @@ function findFiles(dir, predicate) {
1356
1386
  return results;
1357
1387
  }
1358
1388
  var DEFAULT_TIMEOUT_MS = 3e4;
1389
+ var DEFAULT_POLL_RETRY_DELAYS_MS = [2e3, 4e3, 8e3, 16e3, 3e4];
1359
1390
  async function verifyAgainstRegistry(packages, options) {
1360
- const { registry, timeout = DEFAULT_TIMEOUT_MS, logger } = options;
1391
+ const { registry, timeout = DEFAULT_TIMEOUT_MS, retries = 0, retryDelaysMs = DEFAULT_POLL_RETRY_DELAYS_MS, logger } = options;
1361
1392
  const results = [];
1362
1393
  for (const pkg of packages) {
1363
- results.push(await verifyOneAgainstRegistry(pkg, registry, timeout, logger));
1394
+ results.push(await verifyOneAgainstRegistry(pkg, registry, timeout, retries, retryDelaysMs, logger));
1364
1395
  }
1365
1396
  return results;
1366
1397
  }
1367
- async function verifyOneAgainstRegistry(pkg, registry, timeout, logger) {
1368
- const published = await isVersionPublished(pkg.name, pkg.version, registry);
1398
+ async function waitUntilPublished(pkg, registry, retries, retryDelaysMs, logger) {
1399
+ for (let attempt = 0; attempt <= retries; attempt++) {
1400
+ if (await isVersionPublished(pkg.name, pkg.version, registry)) {
1401
+ return true;
1402
+ }
1403
+ if (attempt < retries) {
1404
+ const delay = retryDelaysMs[Math.min(attempt, retryDelaysMs.length - 1)];
1405
+ logger?.warn?.(
1406
+ `${pkg.name}@${pkg.version} not yet visible on ${registry} (attempt ${attempt + 1}/${retries + 1}), retrying in ${(delay / 1e3).toFixed(0)}s \u2014 likely registry propagation lag`
1407
+ );
1408
+ await new Promise((r) => {
1409
+ setTimeout(r, delay);
1410
+ });
1411
+ }
1412
+ }
1413
+ return false;
1414
+ }
1415
+ async function verifyOneAgainstRegistry(pkg, registry, timeout, retries, retryDelaysMs, logger) {
1416
+ const published = await waitUntilPublished(pkg, registry, retries, retryDelaysMs, logger);
1369
1417
  if (!published) {
1370
- return { name: pkg.name, success: false, issues: [`${pkg.name}@${pkg.version} was not found on ${registry} after publish`] };
1418
+ return { name: pkg.name, success: false, issues: [`${pkg.name}@${pkg.version} was not found on ${registry} after publish (waited through ${retries} retr${retries === 1 ? "y" : "ies"})`] };
1371
1419
  }
1372
1420
  logger?.info?.(`${pkg.name}@${pkg.version} confirmed on ${registry}`);
1373
1421
  const tmpDir = join(tmpdir(), `kb-verdaccio-verify-${randomBytes(6).toString("hex")}`);
@@ -1451,6 +1499,7 @@ async function runReleasePipeline(options) {
1451
1499
  skipChecks = false,
1452
1500
  skipBuild = false,
1453
1501
  skipVerify = false,
1502
+ skipPublish = false,
1454
1503
  noVerify = false,
1455
1504
  checks: checkConfigs,
1456
1505
  publisher,
@@ -1476,6 +1525,7 @@ async function runReleasePipeline(options) {
1476
1525
  skipChecks,
1477
1526
  skipBuild,
1478
1527
  skipVerify,
1528
+ skipPublish,
1479
1529
  noVerify,
1480
1530
  checkConfigs,
1481
1531
  publisher,
@@ -1500,6 +1550,7 @@ async function _runPipeline(ctx) {
1500
1550
  skipChecks,
1501
1551
  skipBuild,
1502
1552
  skipVerify,
1553
+ skipPublish,
1503
1554
  noVerify,
1504
1555
  checkConfigs,
1505
1556
  publisher,
@@ -1511,7 +1562,7 @@ async function _runPipeline(ctx) {
1511
1562
  const channel = config.channel ?? "stable";
1512
1563
  const publishTag = resolvePublishTag(config, channel);
1513
1564
  const publishRegistry = resolvePublishRegistry(config, channel);
1514
- if (!dryRun) {
1565
+ if (!dryRun && !skipPublish) {
1515
1566
  const registry = publishRegistry;
1516
1567
  const authError = await verifyNpmAuth(registry);
1517
1568
  if (authError) {
@@ -1549,7 +1600,7 @@ async function _runPipeline(ctx) {
1549
1600
  };
1550
1601
  }
1551
1602
  progress("planning", `Found ${plan.packages.length} package(s) to release`);
1552
- if (!dryRun) {
1603
+ if (!dryRun && !skipPublish) {
1553
1604
  const existingCheckpoint = loadCheckpoint(repoRoot);
1554
1605
  if (existingCheckpoint) {
1555
1606
  const uniqueVersions = new Set(plan.packages.map((p) => p.nextVersion));
@@ -1562,7 +1613,10 @@ async function _runPipeline(ctx) {
1562
1613
  dryRun: false,
1563
1614
  noVerify,
1564
1615
  repoRoot,
1565
- checkpointGitRoots: existingCheckpoint.gitRoots
1616
+ checkpointGitRoots: existingCheckpoint.gitRoots,
1617
+ changelogOutputPath: config.changelog?.outputPath,
1618
+ flowName: flow,
1619
+ tagPattern: flow ? config.flows?.[flow]?.tagPattern : void 0
1566
1620
  });
1567
1621
  deleteCheckpoint(repoRoot);
1568
1622
  const resumeReport = buildReport("verifying", plan, repoRoot, dryRun, startTime, {
@@ -1696,15 +1750,21 @@ async function _runPipeline(ctx) {
1696
1750
  }
1697
1751
  if (changelogMd && !dryRun) {
1698
1752
  await copyChangelogToPackages({ plan, changelog: changelogMd });
1699
- await mergeRootChangelog({ repoRoot, plan, changelog: changelogMd });
1753
+ await mergeRootChangelog({ repoRoot, plan, changelog: changelogMd, outputPath: config.changelog?.outputPath });
1700
1754
  }
1701
- progress("publishing", dryRun ? "Simulating publish (dry-run)..." : "Publishing packages...");
1755
+ progress("publishing", dryRun ? "Simulating publish (dry-run)..." : skipPublish ? "Skipping publish (prepare-only)..." : "Publishing packages...");
1702
1756
  const packagesToPublish = plan.packages.map((pkg) => ({
1703
1757
  name: pkg.name,
1704
1758
  version: pkg.nextVersion,
1705
1759
  path: pkg.path
1706
1760
  }));
1707
- const publishResult = await publisher.publish(packagesToPublish, {
1761
+ const publishResult = skipPublish ? {
1762
+ published: [],
1763
+ alreadyPublished: [],
1764
+ failed: [],
1765
+ skipped: packagesToPublish.map((p) => `${p.name}@${p.version} (prepared, not published)`),
1766
+ errors: []
1767
+ } : await publisher.publish(packagesToPublish, {
1708
1768
  dryRun,
1709
1769
  access: config.publish?.access ?? "public",
1710
1770
  tag: publishTag,
@@ -1727,7 +1787,7 @@ async function _runPipeline(ctx) {
1727
1787
  })
1728
1788
  };
1729
1789
  }
1730
- if (!dryRun && channel === "stable") {
1790
+ if (!dryRun && !skipPublish && channel === "stable") {
1731
1791
  const uniqueVersions = new Set(plan.packages.map((p) => p.nextVersion));
1732
1792
  const cpVersion = uniqueVersions.size === 1 ? plan.packages[0].nextVersion : "independent";
1733
1793
  writeCheckpoint(repoRoot, {
@@ -1742,7 +1802,7 @@ async function _runPipeline(ctx) {
1742
1802
  gitRoots: {}
1743
1803
  });
1744
1804
  }
1745
- if (!dryRun && channel === "stable") {
1805
+ if (!dryRun && !skipPublish && channel === "stable") {
1746
1806
  progress("verifying", "Verifying published artifacts against the registry...");
1747
1807
  const registryVerifyResults = await verifyAgainstRegistry(packagesToPublish, {
1748
1808
  registry: publishRegistry,
@@ -1768,7 +1828,16 @@ async function _runPipeline(ctx) {
1768
1828
  let gitResult;
1769
1829
  if (!dryRun && channel === "stable") {
1770
1830
  progress("verifying", "Committing and tagging release...");
1771
- gitResult = await commitAndTagRelease({ cwd: scopeCwd, plan, dryRun, noVerify, repoRoot });
1831
+ gitResult = await commitAndTagRelease({
1832
+ cwd: scopeCwd,
1833
+ plan,
1834
+ dryRun,
1835
+ noVerify,
1836
+ repoRoot,
1837
+ changelogOutputPath: config.changelog?.outputPath,
1838
+ flowName: flow,
1839
+ tagPattern: flow ? config.flows?.[flow]?.tagPattern : void 0
1840
+ });
1772
1841
  deleteCheckpoint(repoRoot);
1773
1842
  }
1774
1843
  const report = buildReport("verifying", plan, repoRoot, dryRun, startTime, {
@@ -1838,6 +1907,6 @@ async function resolveScopePath(repoRoot, scope) {
1838
1907
  return join(repoRoot, scope);
1839
1908
  }
1840
1909
 
1841
- export { applyCanarySuffix, applyVersionStrategy, buildPackages, commitAndTagRelease, copyChangelogToPackages, createExecaShellAdapter, discoverCurrentPackages, isBuildCommand, isVersionPublished, matchesPackagePattern, mergeConfigWithFlow, mergeRootChangelog, planRelease, renderJson, renderMarkdown, renderText, resolvePublishRegistry, resolvePublishTag, resolveScopePath, restoreSnapshot, runReleaseChecks, runReleasePipeline, runSafeBuild, saveSnapshot, spawnCommand, updatePackageVersion, updatePackageVersions, verifyAgainstRegistry, verifyExtractedTarball, verifyPackage, verifyPackages };
1910
+ export { DEFAULT_ROOT_CHANGELOG_PATH, DEFAULT_TAG_PATTERN, applyCanarySuffix, applyVersionStrategy, buildPackages, buildReleaseTag, commitAndTagRelease, copyChangelogToPackages, createExecaShellAdapter, discoverCurrentPackages, isBuildCommand, isVersionPublished, matchesPackagePattern, mergeConfigWithFlow, mergeRootChangelog, planRelease, renderJson, renderMarkdown, renderText, resolveFlowFromTag, resolvePublishRegistry, resolvePublishTag, resolveRootChangelogRelPath, resolveScopePath, restoreSnapshot, runReleaseChecks, runReleasePipeline, runSafeBuild, saveSnapshot, spawnCommand, updatePackageVersion, updatePackageVersions, verifyAgainstRegistry, verifyExtractedTarball, verifyPackage, verifyPackages };
1842
1911
  //# sourceMappingURL=index.js.map
1843
1912
  //# sourceMappingURL=index.js.map