@ucdjs/release-scripts 0.1.0-beta.44 → 0.1.0-beta.46

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.mts CHANGED
@@ -90,6 +90,10 @@ interface PackageRelease {
90
90
  * Whether this package has direct changes (vs being updated due to dependency changes)
91
91
  */
92
92
  hasDirectChanges: boolean;
93
+ /**
94
+ * Why/how this release entry exists.
95
+ */
96
+ changeKind: "auto" | "manual" | "as-is" | "dependent";
93
97
  }
94
98
  //#endregion
95
99
  //#region src/types.d.ts
package/dist/index.mjs CHANGED
@@ -1059,7 +1059,10 @@ async function selectPackagePrompt(packages) {
1059
1059
  if (!response.selectedPackages || response.selectedPackages.length === 0) return [];
1060
1060
  return response.selectedPackages;
1061
1061
  }
1062
- async function selectVersionPrompt(workspaceRoot, pkg, currentVersion, suggestedVersion) {
1062
+ async function selectVersionPrompt(workspaceRoot, pkg, currentVersion, suggestedVersion, options) {
1063
+ const defaultChoice = options?.defaultChoice ?? "auto";
1064
+ const suggestedSuffix = options?.suggestedHint ? farver.dim(` (${options.suggestedHint})`) : "";
1065
+ const initial = defaultChoice === "skip" ? 0 : defaultChoice === "suggested" ? 4 : defaultChoice === "as-is" ? 5 : suggestedVersion === currentVersion ? 0 : 4;
1063
1066
  const answers = await prompts([{
1064
1067
  type: "autocomplete",
1065
1068
  name: "version",
@@ -1083,7 +1086,7 @@ async function selectVersionPrompt(workspaceRoot, pkg, currentVersion, suggested
1083
1086
  },
1084
1087
  {
1085
1088
  value: "suggested",
1086
- title: `suggested ${farver.bold(suggestedVersion)}`
1089
+ title: `suggested ${farver.bold(suggestedVersion)}${suggestedSuffix}`
1087
1090
  },
1088
1091
  {
1089
1092
  value: "as-is",
@@ -1094,7 +1097,7 @@ async function selectVersionPrompt(workspaceRoot, pkg, currentVersion, suggested
1094
1097
  title: "custom"
1095
1098
  }
1096
1099
  ],
1097
- initial: suggestedVersion === currentVersion ? 0 : 4
1100
+ initial
1098
1101
  }, {
1099
1102
  type: (prev) => prev === "custom" ? "text" : null,
1100
1103
  name: "custom",
@@ -1415,7 +1418,8 @@ function createVersionUpdate(pkg, bump, hasDirectChanges) {
1415
1418
  currentVersion: pkg.version,
1416
1419
  newVersion,
1417
1420
  bumpType: bump,
1418
- hasDirectChanges
1421
+ hasDirectChanges,
1422
+ changeKind: "dependent"
1419
1423
  };
1420
1424
  }
1421
1425
  function determineBumpType(commit) {
@@ -1535,12 +1539,16 @@ function getPackagePublishOrder(graph, packagesToPublish) {
1535
1539
  * @param directUpdates - Packages with direct code changes
1536
1540
  * @returns All updates including dependent packages that need patch bumps
1537
1541
  */
1538
- function createDependentUpdates(graph, workspacePackages, directUpdates) {
1542
+ function createDependentUpdates(graph, workspacePackages, directUpdates, excludedPackages = /* @__PURE__ */ new Set()) {
1539
1543
  const allUpdates = [...directUpdates];
1540
1544
  const directUpdateMap = new Map(directUpdates.map((u) => [u.package.name, u]));
1541
1545
  const affectedPackages = getAllAffectedPackages(graph, new Set(directUpdates.map((u) => u.package.name)));
1542
1546
  for (const pkgName of affectedPackages) {
1543
1547
  logger.verbose(`Processing affected package: ${pkgName}`);
1548
+ if (excludedPackages.has(pkgName)) {
1549
+ logger.verbose(`Skipping ${pkgName}, explicitly excluded from dependent bumps`);
1550
+ continue;
1551
+ }
1544
1552
  if (directUpdateMap.has(pkgName)) {
1545
1553
  logger.verbose(`Skipping ${pkgName}, already has a direct update`);
1546
1554
  continue;
@@ -1604,6 +1612,7 @@ async function calculateVersionUpdates({ workspacePackages, packageCommits, work
1604
1612
  const versionUpdates = [];
1605
1613
  const processedPackages = /* @__PURE__ */ new Set();
1606
1614
  const newOverrides = { ...initialOverrides };
1615
+ const excludedPackages = /* @__PURE__ */ new Set();
1607
1616
  const bumpRanks = {
1608
1617
  major: 3,
1609
1618
  minor: 2,
@@ -1624,10 +1633,6 @@ async function calculateVersionUpdates({ workspacePackages, packageCommits, work
1624
1633
  const override = newOverrides[pkgName];
1625
1634
  const effectiveBump = override?.type || determinedBump;
1626
1635
  const canPrompt = !isCI && showPrompt;
1627
- if (override?.type === "none" && override.version === pkg.version) {
1628
- delete newOverrides[pkgName];
1629
- logger.verbose(`Removed stale "none" override for ${pkgName}`);
1630
- }
1631
1636
  if (effectiveBump === "none" && !canPrompt) continue;
1632
1637
  let newVersion = override?.version || getNextVersion(pkg.version, effectiveBump);
1633
1638
  let finalBumpType = effectiveBump;
@@ -1636,26 +1641,50 @@ async function calculateVersionUpdates({ workspacePackages, packageCommits, work
1636
1641
  logger.section(`📝 Commits for ${farver.cyan(pkg.name)}`);
1637
1642
  formatCommitsForDisplay(allCommitsForPackage).split("\n").forEach((line) => logger.item(line));
1638
1643
  logger.emptyLine();
1639
- const selectedVersion = await selectVersionPrompt(workspaceRoot, pkg, pkg.version, newVersion);
1644
+ const selectedVersion = await selectVersionPrompt(workspaceRoot, pkg, pkg.version, newVersion, {
1645
+ defaultChoice: override ? "suggested" : "auto",
1646
+ suggestedHint: override ? "from override" : void 0
1647
+ });
1640
1648
  if (selectedVersion === null) continue;
1641
1649
  const userBump = calculateBumpType(pkg.version, selectedVersion);
1642
1650
  finalBumpType = userBump;
1643
1651
  if (selectedVersion === pkg.version) {
1644
- if (newOverrides[pkgName]) {
1652
+ excludedPackages.add(pkgName);
1653
+ if (determinedBump !== "none") {
1654
+ const nextOverride = {
1655
+ type: "none",
1656
+ version: pkg.version
1657
+ };
1658
+ if (!override || override.type !== nextOverride.type || override.version !== nextOverride.version) {
1659
+ newOverrides[pkgName] = nextOverride;
1660
+ logger.info(`Override set for ${pkgName}: suggested as-is (${pkg.version}) from auto ${determinedBump}`);
1661
+ }
1662
+ } else if (newOverrides[pkgName]) {
1645
1663
  delete newOverrides[pkgName];
1646
- logger.info(`Version override removed for ${pkgName}.`);
1664
+ logger.info(`Override cleared for ${pkgName}.`);
1647
1665
  }
1666
+ versionUpdates.push({
1667
+ package: pkg,
1668
+ currentVersion: pkg.version,
1669
+ newVersion: pkg.version,
1670
+ bumpType: "none",
1671
+ hasDirectChanges: allCommitsForPackage.length > 0,
1672
+ changeKind: "as-is"
1673
+ });
1648
1674
  continue;
1649
1675
  }
1650
1676
  if (bumpRanks[userBump] < bumpRanks[determinedBump]) {
1651
- newOverrides[pkgName] = {
1677
+ const nextOverride = {
1652
1678
  type: userBump,
1653
1679
  version: selectedVersion
1654
1680
  };
1655
- logger.info(`Version override recorded for ${pkgName}: ${determinedBump} ${userBump}`);
1681
+ if (!override || override.type !== nextOverride.type || override.version !== nextOverride.version) {
1682
+ newOverrides[pkgName] = nextOverride;
1683
+ logger.info(`Override set for ${pkgName}: suggested ${userBump} (${selectedVersion}) from auto ${determinedBump}`);
1684
+ }
1656
1685
  } else if (newOverrides[pkgName] && bumpRanks[userBump] >= bumpRanks[determinedBump]) {
1657
1686
  delete newOverrides[pkgName];
1658
- logger.info(`Version override removed for ${pkgName}.`);
1687
+ logger.info(`Override cleared for ${pkgName}.`);
1659
1688
  }
1660
1689
  newVersion = selectedVersion;
1661
1690
  }
@@ -1664,7 +1693,8 @@ async function calculateVersionUpdates({ workspacePackages, packageCommits, work
1664
1693
  currentVersion: pkg.version,
1665
1694
  newVersion,
1666
1695
  bumpType: finalBumpType,
1667
- hasDirectChanges: allCommitsForPackage.length > 0
1696
+ hasDirectChanges: allCommitsForPackage.length > 0,
1697
+ changeKind: canPrompt ? "manual" : "auto"
1668
1698
  });
1669
1699
  }
1670
1700
  if (!isCI && showPrompt) for (const pkg of workspacePackages) {
@@ -1674,20 +1704,24 @@ async function calculateVersionUpdates({ workspacePackages, packageCommits, work
1674
1704
  logger.item("No direct commits found");
1675
1705
  const newVersion = await selectVersionPrompt(workspaceRoot, pkg, pkg.version, pkg.version);
1676
1706
  if (newVersion === null) break;
1677
- if (newVersion !== pkg.version) {
1678
- const bumpType = calculateBumpType(pkg.version, newVersion);
1679
- versionUpdates.push({
1680
- package: pkg,
1681
- currentVersion: pkg.version,
1682
- newVersion,
1683
- bumpType,
1684
- hasDirectChanges: false
1685
- });
1707
+ if (newVersion === pkg.version) {
1708
+ excludedPackages.add(pkg.name);
1709
+ continue;
1686
1710
  }
1711
+ const bumpType = calculateBumpType(pkg.version, newVersion);
1712
+ versionUpdates.push({
1713
+ package: pkg,
1714
+ currentVersion: pkg.version,
1715
+ newVersion,
1716
+ bumpType,
1717
+ hasDirectChanges: false,
1718
+ changeKind: "manual"
1719
+ });
1687
1720
  }
1688
1721
  return {
1689
1722
  updates: versionUpdates,
1690
- overrides: newOverrides
1723
+ overrides: newOverrides,
1724
+ excludedPackages
1691
1725
  };
1692
1726
  }
1693
1727
  /**
@@ -1695,7 +1729,7 @@ async function calculateVersionUpdates({ workspacePackages, packageCommits, work
1695
1729
  * Returns both the updates and a function to apply them
1696
1730
  */
1697
1731
  async function calculateAndPrepareVersionUpdates({ workspacePackages, packageCommits, workspaceRoot, showPrompt, globalCommitsPerPackage, overrides }) {
1698
- const { updates: directUpdates, overrides: newOverrides } = await calculateVersionUpdates({
1732
+ const { updates: directUpdates, overrides: newOverrides, excludedPackages: promptExcludedPackages } = await calculateVersionUpdates({
1699
1733
  workspacePackages,
1700
1734
  packageCommits,
1701
1735
  workspaceRoot,
@@ -1703,7 +1737,9 @@ async function calculateAndPrepareVersionUpdates({ workspacePackages, packageCom
1703
1737
  globalCommitsPerPackage,
1704
1738
  overrides
1705
1739
  });
1706
- const allUpdates = createDependentUpdates(buildPackageDependencyGraph(workspacePackages), workspacePackages, directUpdates);
1740
+ const graph = buildPackageDependencyGraph(workspacePackages);
1741
+ const overrideExcludedPackages = new Set(Object.entries(newOverrides).filter(([, override]) => override.type === "none").map(([pkgName]) => pkgName));
1742
+ const allUpdates = createDependentUpdates(graph, workspacePackages, directUpdates, new Set([...overrideExcludedPackages, ...promptExcludedPackages]));
1707
1743
  const applyUpdates = async () => {
1708
1744
  await Promise.all(allUpdates.map(async (update) => {
1709
1745
  const depUpdates = getDependencyUpdates(update.package, allUpdates);
@@ -1876,8 +1912,9 @@ async function prepareWorkflow(options) {
1876
1912
  });
1877
1913
  if (!updatesResult.ok) exitWithError("Failed to calculate package updates.", void 0, updatesResult.error);
1878
1914
  const { allUpdates, applyUpdates, overrides: newOverrides } = updatesResult.value;
1879
- if (Object.keys(newOverrides).length > 0) {
1880
- logger.info("Writing version overrides file...");
1915
+ const hasOverrideChanges = JSON.stringify(existingOverrides) !== JSON.stringify(newOverrides);
1916
+ if (Object.keys(newOverrides).length > 0 && hasOverrideChanges) {
1917
+ logger.step("Writing version overrides file...");
1881
1918
  try {
1882
1919
  await mkdir(join(options.workspaceRoot, ".github"), { recursive: true });
1883
1920
  await writeFile(overridesPath, JSON.stringify(newOverrides, null, 2), "utf-8");
@@ -1885,7 +1922,7 @@ async function prepareWorkflow(options) {
1885
1922
  } catch (e) {
1886
1923
  logger.error("Failed to write version overrides file:", e);
1887
1924
  }
1888
- }
1925
+ } else if (Object.keys(newOverrides).length > 0) logger.step("Version overrides unchanged. Skipping write.");
1889
1926
  if (Object.keys(newOverrides).length === 0 && Object.keys(existingOverrides).length > 0) {
1890
1927
  let shouldRemoveOverrides = false;
1891
1928
  for (const update of allUpdates) {
@@ -1910,7 +1947,10 @@ async function prepareWorkflow(options) {
1910
1947
  if (allUpdates.filter((u) => u.hasDirectChanges).length === 0) logger.warn("No packages have changes requiring a release");
1911
1948
  logger.section("🔄 Version Updates");
1912
1949
  logger.item(`Updating ${allUpdates.length} packages (including dependents)`);
1913
- for (const update of allUpdates) logger.item(`${update.package.name}: ${update.currentVersion} → ${update.newVersion}`);
1950
+ for (const update of allUpdates) {
1951
+ const suffix = update.changeKind === "as-is" ? farver.dim(" (as-is)") : "";
1952
+ logger.item(`${update.package.name}: ${update.currentVersion} → ${update.newVersion}${suffix}`);
1953
+ }
1914
1954
  await applyUpdates();
1915
1955
  if (options.changelog?.enabled) {
1916
1956
  logger.step("Updating changelogs");
@@ -1960,6 +2000,8 @@ async function prepareWorkflow(options) {
1960
2000
  if (!prResult.ok) exitWithError("Failed to sync release pull request.", void 0, prResult.error);
1961
2001
  if (prResult.value.pullRequest) {
1962
2002
  logger.item("No updates needed, PR is already up to date");
2003
+ const checkoutResult = await checkoutBranch(options.branch.default, options.workspaceRoot);
2004
+ if (!checkoutResult.ok) exitWithError(`Failed to checkout branch: ${options.branch.default}`, void 0, checkoutResult.error);
1963
2005
  return {
1964
2006
  updates: allUpdates,
1965
2007
  prUrl: prResult.value.pullRequest.html_url,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ucdjs/release-scripts",
3
- "version": "0.1.0-beta.44",
3
+ "version": "0.1.0-beta.46",
4
4
  "description": "@ucdjs release scripts",
5
5
  "type": "module",
6
6
  "license": "MIT",