@ucdjs/release-scripts 0.1.0-beta.45 → 0.1.0-beta.47
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 +4 -0
- package/dist/index.mjs +129 -49
- package/package.json +1 -1
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
|
@@ -8,8 +8,8 @@ import farver from "farver";
|
|
|
8
8
|
import mri from "mri";
|
|
9
9
|
import { exec } from "tinyexec";
|
|
10
10
|
import { dedent } from "@luxass/utils";
|
|
11
|
+
import semver, { compare, gt } from "semver";
|
|
11
12
|
import prompts from "prompts";
|
|
12
|
-
import { compare, gt } from "semver";
|
|
13
13
|
|
|
14
14
|
//#region src/operations/changelog-format.ts
|
|
15
15
|
function formatCommitLine({ commit, owner, repo, authors }) {
|
|
@@ -1003,42 +1003,38 @@ function parseChangelog(content) {
|
|
|
1003
1003
|
//#endregion
|
|
1004
1004
|
//#region src/operations/semver.ts
|
|
1005
1005
|
function isValidSemver(version) {
|
|
1006
|
-
return
|
|
1006
|
+
return semver.valid(version) != null;
|
|
1007
1007
|
}
|
|
1008
1008
|
function getNextVersion(currentVersion, bump) {
|
|
1009
1009
|
if (bump === "none") return currentVersion;
|
|
1010
1010
|
if (!isValidSemver(currentVersion)) throw new Error(`Cannot bump version for invalid semver: ${currentVersion}`);
|
|
1011
|
-
const
|
|
1012
|
-
if (!
|
|
1013
|
-
|
|
1014
|
-
let newMajor = Number.parseInt(major, 10);
|
|
1015
|
-
let newMinor = Number.parseInt(minor, 10);
|
|
1016
|
-
let newPatch = Number.parseInt(patch, 10);
|
|
1017
|
-
switch (bump) {
|
|
1018
|
-
case "major":
|
|
1019
|
-
newMajor += 1;
|
|
1020
|
-
newMinor = 0;
|
|
1021
|
-
newPatch = 0;
|
|
1022
|
-
break;
|
|
1023
|
-
case "minor":
|
|
1024
|
-
newMinor += 1;
|
|
1025
|
-
newPatch = 0;
|
|
1026
|
-
break;
|
|
1027
|
-
case "patch":
|
|
1028
|
-
newPatch += 1;
|
|
1029
|
-
break;
|
|
1030
|
-
}
|
|
1031
|
-
return `${newMajor}.${newMinor}.${newPatch}`;
|
|
1011
|
+
const next = semver.inc(currentVersion, bump);
|
|
1012
|
+
if (!next) throw new Error(`Failed to bump version ${currentVersion} with bump ${bump}`);
|
|
1013
|
+
return next;
|
|
1032
1014
|
}
|
|
1033
1015
|
function calculateBumpType(oldVersion, newVersion) {
|
|
1034
1016
|
if (!isValidSemver(oldVersion) || !isValidSemver(newVersion)) throw new Error(`Cannot calculate bump type for invalid semver: ${oldVersion} or ${newVersion}`);
|
|
1035
|
-
const
|
|
1036
|
-
|
|
1037
|
-
if (
|
|
1038
|
-
if (
|
|
1039
|
-
if (
|
|
1017
|
+
const diff = semver.diff(oldVersion, newVersion);
|
|
1018
|
+
if (!diff) return "none";
|
|
1019
|
+
if (diff === "major" || diff === "premajor") return "major";
|
|
1020
|
+
if (diff === "minor" || diff === "preminor") return "minor";
|
|
1021
|
+
if (diff === "patch" || diff === "prepatch" || diff === "prerelease") return "patch";
|
|
1022
|
+
if (semver.gt(newVersion, oldVersion)) return "patch";
|
|
1040
1023
|
return "none";
|
|
1041
1024
|
}
|
|
1025
|
+
function getPrereleaseIdentifier(version) {
|
|
1026
|
+
const parsed = semver.parse(version);
|
|
1027
|
+
if (!parsed || parsed.prerelease.length === 0) return;
|
|
1028
|
+
const identifier = parsed.prerelease[0];
|
|
1029
|
+
return typeof identifier === "string" ? identifier : void 0;
|
|
1030
|
+
}
|
|
1031
|
+
function getNextPrereleaseVersion(currentVersion, mode, identifier) {
|
|
1032
|
+
if (!isValidSemver(currentVersion)) throw new Error(`Cannot bump prerelease for invalid semver: ${currentVersion}`);
|
|
1033
|
+
const releaseType = mode === "next" ? "prerelease" : mode;
|
|
1034
|
+
const next = identifier ? semver.inc(currentVersion, releaseType, identifier) : semver.inc(currentVersion, releaseType);
|
|
1035
|
+
if (!next) throw new Error(`Failed to compute prerelease version for ${currentVersion}`);
|
|
1036
|
+
return next;
|
|
1037
|
+
}
|
|
1042
1038
|
|
|
1043
1039
|
//#endregion
|
|
1044
1040
|
//#region src/core/prompts.ts
|
|
@@ -1059,7 +1055,20 @@ async function selectPackagePrompt(packages) {
|
|
|
1059
1055
|
if (!response.selectedPackages || response.selectedPackages.length === 0) return [];
|
|
1060
1056
|
return response.selectedPackages;
|
|
1061
1057
|
}
|
|
1062
|
-
async function selectVersionPrompt(workspaceRoot, pkg, currentVersion, suggestedVersion) {
|
|
1058
|
+
async function selectVersionPrompt(workspaceRoot, pkg, currentVersion, suggestedVersion, options) {
|
|
1059
|
+
const defaultChoice = options?.defaultChoice ?? "auto";
|
|
1060
|
+
const suggestedSuffix = options?.suggestedHint ? farver.dim(` (${options.suggestedHint})`) : "";
|
|
1061
|
+
const prereleaseIdentifier = getPrereleaseIdentifier(currentVersion);
|
|
1062
|
+
const nextDefaultPrerelease = getNextPrereleaseVersion(currentVersion, "next", prereleaseIdentifier === "alpha" || prereleaseIdentifier === "beta" ? prereleaseIdentifier : "beta");
|
|
1063
|
+
const nextBeta = getNextPrereleaseVersion(currentVersion, "next", "beta");
|
|
1064
|
+
const nextAlpha = getNextPrereleaseVersion(currentVersion, "next", "alpha");
|
|
1065
|
+
const prePatchBeta = getNextPrereleaseVersion(currentVersion, "prepatch", "beta");
|
|
1066
|
+
const preMinorBeta = getNextPrereleaseVersion(currentVersion, "preminor", "beta");
|
|
1067
|
+
const preMajorBeta = getNextPrereleaseVersion(currentVersion, "premajor", "beta");
|
|
1068
|
+
const prePatchAlpha = getNextPrereleaseVersion(currentVersion, "prepatch", "alpha");
|
|
1069
|
+
const preMinorAlpha = getNextPrereleaseVersion(currentVersion, "preminor", "alpha");
|
|
1070
|
+
const preMajorAlpha = getNextPrereleaseVersion(currentVersion, "premajor", "alpha");
|
|
1071
|
+
const initial = defaultChoice === "skip" ? 0 : defaultChoice === "suggested" ? 4 : defaultChoice === "as-is" ? 5 : suggestedVersion === currentVersion ? 0 : 4;
|
|
1063
1072
|
const answers = await prompts([{
|
|
1064
1073
|
type: "autocomplete",
|
|
1065
1074
|
name: "version",
|
|
@@ -1081,9 +1090,45 @@ async function selectVersionPrompt(workspaceRoot, pkg, currentVersion, suggested
|
|
|
1081
1090
|
value: "patch",
|
|
1082
1091
|
title: `patch ${farver.bold(getNextVersion(pkg.version, "patch"))}`
|
|
1083
1092
|
},
|
|
1093
|
+
{
|
|
1094
|
+
value: "next",
|
|
1095
|
+
title: `next ${farver.bold(nextDefaultPrerelease)}`
|
|
1096
|
+
},
|
|
1097
|
+
{
|
|
1098
|
+
value: "prepatch-beta",
|
|
1099
|
+
title: `pre-patch (beta) ${farver.bold(prePatchBeta)}`
|
|
1100
|
+
},
|
|
1101
|
+
{
|
|
1102
|
+
value: "preminor-beta",
|
|
1103
|
+
title: `pre-minor (beta) ${farver.bold(preMinorBeta)}`
|
|
1104
|
+
},
|
|
1105
|
+
{
|
|
1106
|
+
value: "premajor-beta",
|
|
1107
|
+
title: `pre-major (beta) ${farver.bold(preMajorBeta)}`
|
|
1108
|
+
},
|
|
1109
|
+
{
|
|
1110
|
+
value: "prepatch-alpha",
|
|
1111
|
+
title: `pre-patch (alpha) ${farver.bold(prePatchAlpha)}`
|
|
1112
|
+
},
|
|
1113
|
+
{
|
|
1114
|
+
value: "preminor-alpha",
|
|
1115
|
+
title: `pre-minor (alpha) ${farver.bold(preMinorAlpha)}`
|
|
1116
|
+
},
|
|
1117
|
+
{
|
|
1118
|
+
value: "premajor-alpha",
|
|
1119
|
+
title: `pre-major (alpha) ${farver.bold(preMajorAlpha)}`
|
|
1120
|
+
},
|
|
1121
|
+
{
|
|
1122
|
+
value: "next-beta",
|
|
1123
|
+
title: `next beta ${farver.bold(nextBeta)}`
|
|
1124
|
+
},
|
|
1125
|
+
{
|
|
1126
|
+
value: "next-alpha",
|
|
1127
|
+
title: `next alpha ${farver.bold(nextAlpha)}`
|
|
1128
|
+
},
|
|
1084
1129
|
{
|
|
1085
1130
|
value: "suggested",
|
|
1086
|
-
title: `suggested ${farver.bold(suggestedVersion)}`
|
|
1131
|
+
title: `suggested ${farver.bold(suggestedVersion)}${suggestedSuffix}`
|
|
1087
1132
|
},
|
|
1088
1133
|
{
|
|
1089
1134
|
value: "as-is",
|
|
@@ -1094,7 +1139,7 @@ async function selectVersionPrompt(workspaceRoot, pkg, currentVersion, suggested
|
|
|
1094
1139
|
title: "custom"
|
|
1095
1140
|
}
|
|
1096
1141
|
],
|
|
1097
|
-
initial
|
|
1142
|
+
initial
|
|
1098
1143
|
}, {
|
|
1099
1144
|
type: (prev) => prev === "custom" ? "text" : null,
|
|
1100
1145
|
name: "custom",
|
|
@@ -1112,6 +1157,15 @@ async function selectVersionPrompt(workspaceRoot, pkg, currentVersion, suggested
|
|
|
1112
1157
|
if (!answers.custom) return null;
|
|
1113
1158
|
return answers.custom;
|
|
1114
1159
|
} else if (answers.version === "as-is") return currentVersion;
|
|
1160
|
+
else if (answers.version === "next") return nextDefaultPrerelease;
|
|
1161
|
+
else if (answers.version === "next-beta") return nextBeta;
|
|
1162
|
+
else if (answers.version === "next-alpha") return nextAlpha;
|
|
1163
|
+
else if (answers.version === "prepatch-beta") return prePatchBeta;
|
|
1164
|
+
else if (answers.version === "preminor-beta") return preMinorBeta;
|
|
1165
|
+
else if (answers.version === "premajor-beta") return preMajorBeta;
|
|
1166
|
+
else if (answers.version === "prepatch-alpha") return prePatchAlpha;
|
|
1167
|
+
else if (answers.version === "preminor-alpha") return preMinorAlpha;
|
|
1168
|
+
else if (answers.version === "premajor-alpha") return preMajorAlpha;
|
|
1115
1169
|
else return getNextVersion(pkg.version, answers.version);
|
|
1116
1170
|
}
|
|
1117
1171
|
|
|
@@ -1415,7 +1469,8 @@ function createVersionUpdate(pkg, bump, hasDirectChanges) {
|
|
|
1415
1469
|
currentVersion: pkg.version,
|
|
1416
1470
|
newVersion,
|
|
1417
1471
|
bumpType: bump,
|
|
1418
|
-
hasDirectChanges
|
|
1472
|
+
hasDirectChanges,
|
|
1473
|
+
changeKind: "dependent"
|
|
1419
1474
|
};
|
|
1420
1475
|
}
|
|
1421
1476
|
function determineBumpType(commit) {
|
|
@@ -1637,40 +1692,50 @@ async function calculateVersionUpdates({ workspacePackages, packageCommits, work
|
|
|
1637
1692
|
logger.section(`📝 Commits for ${farver.cyan(pkg.name)}`);
|
|
1638
1693
|
formatCommitsForDisplay(allCommitsForPackage).split("\n").forEach((line) => logger.item(line));
|
|
1639
1694
|
logger.emptyLine();
|
|
1640
|
-
const selectedVersion = await selectVersionPrompt(workspaceRoot, pkg, pkg.version, newVersion
|
|
1695
|
+
const selectedVersion = await selectVersionPrompt(workspaceRoot, pkg, pkg.version, newVersion, {
|
|
1696
|
+
defaultChoice: override ? "suggested" : "auto",
|
|
1697
|
+
suggestedHint: override ? "from override" : void 0
|
|
1698
|
+
});
|
|
1641
1699
|
if (selectedVersion === null) continue;
|
|
1642
1700
|
const userBump = calculateBumpType(pkg.version, selectedVersion);
|
|
1643
1701
|
finalBumpType = userBump;
|
|
1644
1702
|
if (selectedVersion === pkg.version) {
|
|
1645
1703
|
excludedPackages.add(pkgName);
|
|
1646
1704
|
if (determinedBump !== "none") {
|
|
1647
|
-
|
|
1705
|
+
const nextOverride = {
|
|
1648
1706
|
type: "none",
|
|
1649
1707
|
version: pkg.version
|
|
1650
1708
|
};
|
|
1651
|
-
|
|
1709
|
+
if (!override || override.type !== nextOverride.type || override.version !== nextOverride.version) {
|
|
1710
|
+
newOverrides[pkgName] = nextOverride;
|
|
1711
|
+
logger.info(`Override set for ${pkgName}: suggested as-is (${pkg.version}) from auto ${determinedBump}`);
|
|
1712
|
+
}
|
|
1652
1713
|
} else if (newOverrides[pkgName]) {
|
|
1653
1714
|
delete newOverrides[pkgName];
|
|
1654
|
-
logger.info(`
|
|
1715
|
+
logger.info(`Override cleared for ${pkgName}.`);
|
|
1655
1716
|
}
|
|
1656
1717
|
versionUpdates.push({
|
|
1657
1718
|
package: pkg,
|
|
1658
1719
|
currentVersion: pkg.version,
|
|
1659
1720
|
newVersion: pkg.version,
|
|
1660
1721
|
bumpType: "none",
|
|
1661
|
-
hasDirectChanges: allCommitsForPackage.length > 0
|
|
1722
|
+
hasDirectChanges: allCommitsForPackage.length > 0,
|
|
1723
|
+
changeKind: "as-is"
|
|
1662
1724
|
});
|
|
1663
1725
|
continue;
|
|
1664
1726
|
}
|
|
1665
1727
|
if (bumpRanks[userBump] < bumpRanks[determinedBump]) {
|
|
1666
|
-
|
|
1728
|
+
const nextOverride = {
|
|
1667
1729
|
type: userBump,
|
|
1668
1730
|
version: selectedVersion
|
|
1669
1731
|
};
|
|
1670
|
-
|
|
1732
|
+
if (!override || override.type !== nextOverride.type || override.version !== nextOverride.version) {
|
|
1733
|
+
newOverrides[pkgName] = nextOverride;
|
|
1734
|
+
logger.info(`Override set for ${pkgName}: suggested ${userBump} (${selectedVersion}) from auto ${determinedBump}`);
|
|
1735
|
+
}
|
|
1671
1736
|
} else if (newOverrides[pkgName] && bumpRanks[userBump] >= bumpRanks[determinedBump]) {
|
|
1672
1737
|
delete newOverrides[pkgName];
|
|
1673
|
-
logger.info(`
|
|
1738
|
+
logger.info(`Override cleared for ${pkgName}.`);
|
|
1674
1739
|
}
|
|
1675
1740
|
newVersion = selectedVersion;
|
|
1676
1741
|
}
|
|
@@ -1679,7 +1744,8 @@ async function calculateVersionUpdates({ workspacePackages, packageCommits, work
|
|
|
1679
1744
|
currentVersion: pkg.version,
|
|
1680
1745
|
newVersion,
|
|
1681
1746
|
bumpType: finalBumpType,
|
|
1682
|
-
hasDirectChanges: allCommitsForPackage.length > 0
|
|
1747
|
+
hasDirectChanges: allCommitsForPackage.length > 0,
|
|
1748
|
+
changeKind: canPrompt ? "manual" : "auto"
|
|
1683
1749
|
});
|
|
1684
1750
|
}
|
|
1685
1751
|
if (!isCI && showPrompt) for (const pkg of workspacePackages) {
|
|
@@ -1699,7 +1765,8 @@ async function calculateVersionUpdates({ workspacePackages, packageCommits, work
|
|
|
1699
1765
|
currentVersion: pkg.version,
|
|
1700
1766
|
newVersion,
|
|
1701
1767
|
bumpType,
|
|
1702
|
-
hasDirectChanges: false
|
|
1768
|
+
hasDirectChanges: false,
|
|
1769
|
+
changeKind: "manual"
|
|
1703
1770
|
});
|
|
1704
1771
|
}
|
|
1705
1772
|
return {
|
|
@@ -1896,8 +1963,9 @@ async function prepareWorkflow(options) {
|
|
|
1896
1963
|
});
|
|
1897
1964
|
if (!updatesResult.ok) exitWithError("Failed to calculate package updates.", void 0, updatesResult.error);
|
|
1898
1965
|
const { allUpdates, applyUpdates, overrides: newOverrides } = updatesResult.value;
|
|
1899
|
-
|
|
1900
|
-
|
|
1966
|
+
const hasOverrideChanges = JSON.stringify(existingOverrides) !== JSON.stringify(newOverrides);
|
|
1967
|
+
if (Object.keys(newOverrides).length > 0 && hasOverrideChanges) {
|
|
1968
|
+
logger.step("Writing version overrides file...");
|
|
1901
1969
|
try {
|
|
1902
1970
|
await mkdir(join(options.workspaceRoot, ".github"), { recursive: true });
|
|
1903
1971
|
await writeFile(overridesPath, JSON.stringify(newOverrides, null, 2), "utf-8");
|
|
@@ -1905,7 +1973,7 @@ async function prepareWorkflow(options) {
|
|
|
1905
1973
|
} catch (e) {
|
|
1906
1974
|
logger.error("Failed to write version overrides file:", e);
|
|
1907
1975
|
}
|
|
1908
|
-
}
|
|
1976
|
+
} else if (Object.keys(newOverrides).length > 0) logger.step("Version overrides unchanged. Skipping write.");
|
|
1909
1977
|
if (Object.keys(newOverrides).length === 0 && Object.keys(existingOverrides).length > 0) {
|
|
1910
1978
|
let shouldRemoveOverrides = false;
|
|
1911
1979
|
for (const update of allUpdates) {
|
|
@@ -1931,7 +1999,7 @@ async function prepareWorkflow(options) {
|
|
|
1931
1999
|
logger.section("🔄 Version Updates");
|
|
1932
2000
|
logger.item(`Updating ${allUpdates.length} packages (including dependents)`);
|
|
1933
2001
|
for (const update of allUpdates) {
|
|
1934
|
-
const suffix = update.
|
|
2002
|
+
const suffix = update.changeKind === "as-is" ? farver.dim(" (as-is)") : "";
|
|
1935
2003
|
logger.item(`${update.package.name}: ${update.currentVersion} → ${update.newVersion}${suffix}`);
|
|
1936
2004
|
}
|
|
1937
2005
|
await applyUpdates();
|
|
@@ -1983,6 +2051,8 @@ async function prepareWorkflow(options) {
|
|
|
1983
2051
|
if (!prResult.ok) exitWithError("Failed to sync release pull request.", void 0, prResult.error);
|
|
1984
2052
|
if (prResult.value.pullRequest) {
|
|
1985
2053
|
logger.item("No updates needed, PR is already up to date");
|
|
2054
|
+
const checkoutResult = await checkoutBranch(options.branch.default, options.workspaceRoot);
|
|
2055
|
+
if (!checkoutResult.ok) exitWithError(`Failed to checkout branch: ${options.branch.default}`, void 0, checkoutResult.error);
|
|
1986
2056
|
return {
|
|
1987
2057
|
updates: allUpdates,
|
|
1988
2058
|
prUrl: prResult.value.pullRequest.html_url,
|
|
@@ -2095,11 +2165,12 @@ async function buildPackage(packageName, workspaceRoot, options) {
|
|
|
2095
2165
|
* Publish a package to NPM
|
|
2096
2166
|
* Uses pnpm to handle workspace protocol and catalog: resolution automatically
|
|
2097
2167
|
* @param packageName - The package name to publish
|
|
2168
|
+
* @param version - The package version to publish
|
|
2098
2169
|
* @param workspaceRoot - Path to the workspace root
|
|
2099
2170
|
* @param options - Normalized release scripts options
|
|
2100
2171
|
* @returns Result indicating success or failure
|
|
2101
2172
|
*/
|
|
2102
|
-
async function publishPackage(packageName, workspaceRoot, options) {
|
|
2173
|
+
async function publishPackage(packageName, version, workspaceRoot, options) {
|
|
2103
2174
|
const args = [
|
|
2104
2175
|
"--filter",
|
|
2105
2176
|
packageName,
|
|
@@ -2109,7 +2180,16 @@ async function publishPackage(packageName, workspaceRoot, options) {
|
|
|
2109
2180
|
"--no-git-checks"
|
|
2110
2181
|
];
|
|
2111
2182
|
if (options.npm.otp) args.push("--otp", options.npm.otp);
|
|
2112
|
-
|
|
2183
|
+
const explicitTag = process.env.NPM_CONFIG_TAG;
|
|
2184
|
+
const prereleaseTag = (() => {
|
|
2185
|
+
const prerelease = semver.prerelease(version);
|
|
2186
|
+
if (!prerelease || prerelease.length === 0) return;
|
|
2187
|
+
const identifier = prerelease[0];
|
|
2188
|
+
if (identifier === "alpha" || identifier === "beta") return identifier;
|
|
2189
|
+
return "next";
|
|
2190
|
+
})();
|
|
2191
|
+
const publishTag = explicitTag || prereleaseTag;
|
|
2192
|
+
if (publishTag) args.push("--tag", publishTag);
|
|
2113
2193
|
const env = { ...process.env };
|
|
2114
2194
|
if (options.npm.provenance) env.NPM_CONFIG_PROVENANCE = "true";
|
|
2115
2195
|
try {
|
|
@@ -2173,7 +2253,7 @@ async function publishWorkflow(options) {
|
|
|
2173
2253
|
}
|
|
2174
2254
|
}
|
|
2175
2255
|
logger.step(`Publishing ${farver.cyan(`${packageName}@${version}`)} to NPM...`);
|
|
2176
|
-
const publishResult = await publishPackage(packageName, options.workspaceRoot, options);
|
|
2256
|
+
const publishResult = await publishPackage(packageName, version, options.workspaceRoot, options);
|
|
2177
2257
|
if (!publishResult.ok) {
|
|
2178
2258
|
logger.error(`Failed to publish: ${publishResult.error.message}`);
|
|
2179
2259
|
status.failed.push(packageName);
|