@ucdjs/release-scripts 0.1.0-beta.31 ā 0.1.0-beta.33
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 +3 -0
- package/dist/index.mjs +378 -50
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
package/dist/index.mjs
CHANGED
|
@@ -7,6 +7,7 @@ import * as CommitParser from "commit-parser";
|
|
|
7
7
|
import process from "node:process";
|
|
8
8
|
import semver from "semver";
|
|
9
9
|
import fs from "node:fs/promises";
|
|
10
|
+
import prompts from "prompts";
|
|
10
11
|
|
|
11
12
|
//#region src/utils/changelog-formatters.ts
|
|
12
13
|
const eta$1 = new Eta();
|
|
@@ -243,23 +244,25 @@ const DEFAULT_TYPES = {
|
|
|
243
244
|
}
|
|
244
245
|
};
|
|
245
246
|
function normalizeReleaseScriptsOptions(options) {
|
|
246
|
-
const { workspaceRoot = process.cwd(), githubToken = "", repo: fullRepo, packages = true, branch = {}, globalCommitMode = "dependencies", pullRequest = {}, changelog = {}, types = {}, dryRun = false, npm = {} } = options;
|
|
247
|
+
const { workspaceRoot = process.cwd(), githubToken = "", repo: fullRepo, packages = true, branch = {}, globalCommitMode = "dependencies", pullRequest = {}, changelog = {}, types = {}, dryRun = false, npm = {}, prompts = {} } = options;
|
|
247
248
|
const token = githubToken.trim();
|
|
248
249
|
if (!token) throw new Error("GitHub token is required. Pass it in via options.");
|
|
249
250
|
if (!fullRepo || !fullRepo.trim() || !fullRepo.includes("/")) throw new Error("Repository (repo) is required. Specify in 'owner/repo' format (e.g., 'octocat/hello-world').");
|
|
250
251
|
const [owner, repo] = fullRepo.split("/");
|
|
251
252
|
if (!owner || !repo) throw new Error(`Invalid repo format: "${fullRepo}". Expected format: "owner/repo" (e.g., "octocat/hello-world").`);
|
|
253
|
+
const normalizedPackages = typeof packages === "object" && !Array.isArray(packages) ? {
|
|
254
|
+
exclude: packages.exclude ?? [],
|
|
255
|
+
include: packages.include ?? [],
|
|
256
|
+
excludePrivate: packages.excludePrivate ?? false
|
|
257
|
+
} : packages;
|
|
258
|
+
const isCI = process.env.CI === "true" || process.env.GITHUB_ACTIONS === "true";
|
|
252
259
|
return {
|
|
253
260
|
dryRun,
|
|
254
261
|
workspaceRoot,
|
|
255
262
|
githubToken: token,
|
|
256
263
|
owner,
|
|
257
264
|
repo,
|
|
258
|
-
packages:
|
|
259
|
-
exclude: packages.exclude ?? [],
|
|
260
|
-
include: packages.include ?? [],
|
|
261
|
-
excludePrivate: packages.excludePrivate ?? false
|
|
262
|
-
} : packages,
|
|
265
|
+
packages: normalizedPackages,
|
|
263
266
|
branch: {
|
|
264
267
|
release: branch.release ?? "release/next",
|
|
265
268
|
default: branch.default ?? "main"
|
|
@@ -281,7 +284,8 @@ function normalizeReleaseScriptsOptions(options) {
|
|
|
281
284
|
npm: {
|
|
282
285
|
otp: npm.otp,
|
|
283
286
|
provenance: npm.provenance ?? true
|
|
284
|
-
}
|
|
287
|
+
},
|
|
288
|
+
prompts: { versions: prompts.versions ?? !isCI }
|
|
285
289
|
};
|
|
286
290
|
}
|
|
287
291
|
var ReleaseScriptsOptions = class extends Context.Tag("@ucdjs/release-scripts/ReleaseScriptsOptions")() {};
|
|
@@ -1003,6 +1007,281 @@ var VersionCalculatorService = class extends Effect.Service()("@ucdjs/release-sc
|
|
|
1003
1007
|
dependencies: []
|
|
1004
1008
|
}) {};
|
|
1005
1009
|
|
|
1010
|
+
//#endregion
|
|
1011
|
+
//#region src/services/version-prompt.service.ts
|
|
1012
|
+
const GREY = "\x1B[90m";
|
|
1013
|
+
const RESET = "\x1B[0m";
|
|
1014
|
+
const NON_VERSIONING_TYPES = new Set([
|
|
1015
|
+
"chore",
|
|
1016
|
+
"docs",
|
|
1017
|
+
"style",
|
|
1018
|
+
"test",
|
|
1019
|
+
"ci",
|
|
1020
|
+
"build",
|
|
1021
|
+
"refactor"
|
|
1022
|
+
]);
|
|
1023
|
+
function isVersioningCommit(commit) {
|
|
1024
|
+
return !NON_VERSIONING_TYPES.has(commit.type) || commit.isBreaking;
|
|
1025
|
+
}
|
|
1026
|
+
function formatCommit(commit) {
|
|
1027
|
+
const isGreyed = !isVersioningCommit(commit);
|
|
1028
|
+
const scope = commit.scope ? `(${commit.scope})` : "";
|
|
1029
|
+
const description = commit.isConventional ? commit.description : commit.message.split("\n")[0] ?? commit.message;
|
|
1030
|
+
const line = `${commit.shortHash} ${commit.type.padEnd(12)}${scope.padEnd(10)}: ${description}`;
|
|
1031
|
+
return isGreyed ? `${GREY}${line}${RESET}` : line;
|
|
1032
|
+
}
|
|
1033
|
+
function formatCommits(commits) {
|
|
1034
|
+
if (commits.length === 0) return " No commits since the last version";
|
|
1035
|
+
const lines = commits.slice(0, 10).map((c) => ` ${formatCommit(c)}`);
|
|
1036
|
+
if (commits.length > 10) lines.push(` ${GREY}... and ${commits.length - 10} more${RESET}`);
|
|
1037
|
+
return lines.join("\n");
|
|
1038
|
+
}
|
|
1039
|
+
function getPrereleaseInfo(version) {
|
|
1040
|
+
const parsed = semver.parse(version);
|
|
1041
|
+
if (!parsed) return null;
|
|
1042
|
+
if (parsed.prerelease.length === 0) return null;
|
|
1043
|
+
return {
|
|
1044
|
+
identifier: String(parsed.prerelease[0]),
|
|
1045
|
+
baseVersion: `${parsed.major}.${parsed.minor}.${parsed.patch}`
|
|
1046
|
+
};
|
|
1047
|
+
}
|
|
1048
|
+
function generateVersionOptions(currentVersion, conventionalBump, prereleaseInfo) {
|
|
1049
|
+
const options = [];
|
|
1050
|
+
const majorVersion = semver.inc(currentVersion, "major");
|
|
1051
|
+
const minorVersion = semver.inc(currentVersion, "minor");
|
|
1052
|
+
const patchVersion = semver.inc(currentVersion, "patch");
|
|
1053
|
+
if (majorVersion) options.push({
|
|
1054
|
+
title: `major ${majorVersion}`,
|
|
1055
|
+
value: {
|
|
1056
|
+
version: majorVersion,
|
|
1057
|
+
bumpType: "major"
|
|
1058
|
+
}
|
|
1059
|
+
});
|
|
1060
|
+
if (minorVersion) options.push({
|
|
1061
|
+
title: `minor ${minorVersion}`,
|
|
1062
|
+
value: {
|
|
1063
|
+
version: minorVersion,
|
|
1064
|
+
bumpType: "minor"
|
|
1065
|
+
}
|
|
1066
|
+
});
|
|
1067
|
+
if (patchVersion) options.push({
|
|
1068
|
+
title: `patch ${patchVersion}`,
|
|
1069
|
+
value: {
|
|
1070
|
+
version: patchVersion,
|
|
1071
|
+
bumpType: "patch"
|
|
1072
|
+
}
|
|
1073
|
+
});
|
|
1074
|
+
if (prereleaseInfo) {
|
|
1075
|
+
const nextPrerelease = semver.inc(currentVersion, "prerelease", prereleaseInfo.identifier);
|
|
1076
|
+
if (nextPrerelease) options.push({
|
|
1077
|
+
title: `next ${nextPrerelease}`,
|
|
1078
|
+
value: {
|
|
1079
|
+
version: nextPrerelease,
|
|
1080
|
+
bumpType: "patch"
|
|
1081
|
+
}
|
|
1082
|
+
});
|
|
1083
|
+
}
|
|
1084
|
+
const conventionalVersion = conventionalBump !== "none" ? semver.inc(currentVersion, conventionalBump) : null;
|
|
1085
|
+
if (conventionalVersion) options.push({
|
|
1086
|
+
title: `conventional ${conventionalVersion}`,
|
|
1087
|
+
value: {
|
|
1088
|
+
version: conventionalVersion,
|
|
1089
|
+
bumpType: conventionalBump
|
|
1090
|
+
}
|
|
1091
|
+
});
|
|
1092
|
+
if (prereleaseInfo) {
|
|
1093
|
+
const prePatch = semver.inc(currentVersion, "prepatch", prereleaseInfo.identifier);
|
|
1094
|
+
const preMinor = semver.inc(currentVersion, "preminor", prereleaseInfo.identifier);
|
|
1095
|
+
const preMajor = semver.inc(currentVersion, "premajor", prereleaseInfo.identifier);
|
|
1096
|
+
if (prePatch) options.push({
|
|
1097
|
+
title: `pre-patch ${prePatch}`,
|
|
1098
|
+
value: {
|
|
1099
|
+
version: prePatch,
|
|
1100
|
+
bumpType: "patch"
|
|
1101
|
+
}
|
|
1102
|
+
});
|
|
1103
|
+
if (preMinor) options.push({
|
|
1104
|
+
title: `pre-minor ${preMinor}`,
|
|
1105
|
+
value: {
|
|
1106
|
+
version: preMinor,
|
|
1107
|
+
bumpType: "minor"
|
|
1108
|
+
}
|
|
1109
|
+
});
|
|
1110
|
+
if (preMajor) options.push({
|
|
1111
|
+
title: `pre-major ${preMajor}`,
|
|
1112
|
+
value: {
|
|
1113
|
+
version: preMajor,
|
|
1114
|
+
bumpType: "major"
|
|
1115
|
+
}
|
|
1116
|
+
});
|
|
1117
|
+
} else {
|
|
1118
|
+
const betaPatch = semver.inc(currentVersion, "prepatch", "beta");
|
|
1119
|
+
const betaMinor = semver.inc(currentVersion, "preminor", "beta");
|
|
1120
|
+
const betaMajor = semver.inc(currentVersion, "premajor", "beta");
|
|
1121
|
+
if (betaPatch) options.push({
|
|
1122
|
+
title: `pre-patch ${betaPatch}`,
|
|
1123
|
+
value: {
|
|
1124
|
+
version: betaPatch,
|
|
1125
|
+
bumpType: "patch"
|
|
1126
|
+
}
|
|
1127
|
+
});
|
|
1128
|
+
if (betaMinor) options.push({
|
|
1129
|
+
title: `pre-minor ${betaMinor}`,
|
|
1130
|
+
value: {
|
|
1131
|
+
version: betaMinor,
|
|
1132
|
+
bumpType: "minor"
|
|
1133
|
+
}
|
|
1134
|
+
});
|
|
1135
|
+
if (betaMajor) options.push({
|
|
1136
|
+
title: `pre-major ${betaMajor}`,
|
|
1137
|
+
value: {
|
|
1138
|
+
version: betaMajor,
|
|
1139
|
+
bumpType: "major"
|
|
1140
|
+
}
|
|
1141
|
+
});
|
|
1142
|
+
}
|
|
1143
|
+
options.push({
|
|
1144
|
+
title: `as-is ${currentVersion}`,
|
|
1145
|
+
value: {
|
|
1146
|
+
version: currentVersion,
|
|
1147
|
+
bumpType: "none"
|
|
1148
|
+
}
|
|
1149
|
+
});
|
|
1150
|
+
options.push({
|
|
1151
|
+
title: "custom ...",
|
|
1152
|
+
value: {
|
|
1153
|
+
version: "custom",
|
|
1154
|
+
bumpType: "none"
|
|
1155
|
+
}
|
|
1156
|
+
});
|
|
1157
|
+
return options;
|
|
1158
|
+
}
|
|
1159
|
+
function findDefaultIndex(options, conventionalBump) {
|
|
1160
|
+
if (conventionalBump === "none") return 0;
|
|
1161
|
+
const conventionalIndex = options.findIndex((o) => o.title.startsWith("conventional"));
|
|
1162
|
+
return conventionalIndex >= 0 ? conventionalIndex : 0;
|
|
1163
|
+
}
|
|
1164
|
+
async function promptForCustomVersion(currentVersion) {
|
|
1165
|
+
return (await prompts({
|
|
1166
|
+
type: "text",
|
|
1167
|
+
name: "version",
|
|
1168
|
+
message: `Enter custom version (current: ${currentVersion})`,
|
|
1169
|
+
validate: (input) => {
|
|
1170
|
+
if (!semver.valid(input)) return "Please enter a valid semver version (e.g., 1.2.3)";
|
|
1171
|
+
return true;
|
|
1172
|
+
}
|
|
1173
|
+
})).version || null;
|
|
1174
|
+
}
|
|
1175
|
+
var VersionPromptService = class extends Effect.Service()("@ucdjs/release-scripts/VersionPromptService", {
|
|
1176
|
+
effect: Effect.gen(function* () {
|
|
1177
|
+
const config = yield* ReleaseScriptsOptions;
|
|
1178
|
+
let applyToAllRemainingChoice = null;
|
|
1179
|
+
function promptForVersion(pkg, conventionalBump, remainingCount) {
|
|
1180
|
+
return Effect.async((resume) => {
|
|
1181
|
+
const allCommits = [...pkg.commits, ...pkg.globalCommits];
|
|
1182
|
+
const prereleaseInfo = getPrereleaseInfo(pkg.version);
|
|
1183
|
+
const commitCount = allCommits.length;
|
|
1184
|
+
console.log("");
|
|
1185
|
+
console.log(`${commitCount} commit${commitCount === 1 ? "" : "s"} since the last version:`);
|
|
1186
|
+
console.log(formatCommits(allCommits));
|
|
1187
|
+
console.log("");
|
|
1188
|
+
if (applyToAllRemainingChoice) {
|
|
1189
|
+
const result = {
|
|
1190
|
+
newVersion: applyToAllRemainingChoice.version === "custom" ? pkg.version : applyToAllRemainingChoice.version,
|
|
1191
|
+
bumpType: applyToAllRemainingChoice.bumpType,
|
|
1192
|
+
applyToAllRemaining: false
|
|
1193
|
+
};
|
|
1194
|
+
resume(Effect.succeed(result));
|
|
1195
|
+
return;
|
|
1196
|
+
}
|
|
1197
|
+
const options = generateVersionOptions(pkg.version, conventionalBump, prereleaseInfo);
|
|
1198
|
+
const defaultIndex = findDefaultIndex(options, conventionalBump);
|
|
1199
|
+
if (remainingCount > 1) options.push({
|
|
1200
|
+
title: "apply-to-all āŗ",
|
|
1201
|
+
value: {
|
|
1202
|
+
version: "apply-to-all",
|
|
1203
|
+
bumpType: "none"
|
|
1204
|
+
}
|
|
1205
|
+
});
|
|
1206
|
+
prompts({
|
|
1207
|
+
type: "select",
|
|
1208
|
+
name: "choice",
|
|
1209
|
+
message: `Current version ${pkg.version}`,
|
|
1210
|
+
choices: options.map((o) => ({
|
|
1211
|
+
title: o.title,
|
|
1212
|
+
value: o.value
|
|
1213
|
+
})),
|
|
1214
|
+
initial: defaultIndex,
|
|
1215
|
+
hint: "Use arrow keys to navigate, enter to select"
|
|
1216
|
+
}).then(async (response) => {
|
|
1217
|
+
if (!response.choice) {
|
|
1218
|
+
const result = {
|
|
1219
|
+
newVersion: pkg.version,
|
|
1220
|
+
bumpType: "none",
|
|
1221
|
+
applyToAllRemaining: false
|
|
1222
|
+
};
|
|
1223
|
+
resume(Effect.succeed(result));
|
|
1224
|
+
return;
|
|
1225
|
+
}
|
|
1226
|
+
if (response.choice.version === "apply-to-all") {
|
|
1227
|
+
const applyOptions = options.filter((o) => o.value.version !== "custom" && o.value.version !== "apply-to-all");
|
|
1228
|
+
const applyResponse = await prompts({
|
|
1229
|
+
type: "select",
|
|
1230
|
+
name: "choice",
|
|
1231
|
+
message: `Apply to all ${remainingCount} remaining packages`,
|
|
1232
|
+
choices: applyOptions.map((o) => ({
|
|
1233
|
+
title: o.title,
|
|
1234
|
+
value: o.value
|
|
1235
|
+
})),
|
|
1236
|
+
initial: findDefaultIndex(applyOptions, conventionalBump)
|
|
1237
|
+
});
|
|
1238
|
+
if (applyResponse.choice) {
|
|
1239
|
+
if (applyResponse.choice.version === "custom") {
|
|
1240
|
+
const customVersion = await promptForCustomVersion(pkg.version);
|
|
1241
|
+
if (customVersion) applyToAllRemainingChoice = {
|
|
1242
|
+
version: customVersion,
|
|
1243
|
+
bumpType: applyResponse.choice.bumpType
|
|
1244
|
+
};
|
|
1245
|
+
} else applyToAllRemainingChoice = applyResponse.choice;
|
|
1246
|
+
const result = {
|
|
1247
|
+
newVersion: applyToAllRemainingChoice?.version || pkg.version,
|
|
1248
|
+
bumpType: applyToAllRemainingChoice?.bumpType || "none",
|
|
1249
|
+
applyToAllRemaining: true
|
|
1250
|
+
};
|
|
1251
|
+
resume(Effect.succeed(result));
|
|
1252
|
+
} else promptForVersion(pkg, conventionalBump, remainingCount).pipe(Effect.runPromise).then((r) => resume(Effect.succeed(r)));
|
|
1253
|
+
return;
|
|
1254
|
+
}
|
|
1255
|
+
let selectedVersion = response.choice.version;
|
|
1256
|
+
let selectedBumpType = response.choice.bumpType;
|
|
1257
|
+
if (selectedVersion === "custom") {
|
|
1258
|
+
const customVersion = await promptForCustomVersion(pkg.version);
|
|
1259
|
+
if (customVersion) selectedVersion = customVersion;
|
|
1260
|
+
else {
|
|
1261
|
+
selectedVersion = pkg.version;
|
|
1262
|
+
selectedBumpType = "none";
|
|
1263
|
+
}
|
|
1264
|
+
}
|
|
1265
|
+
const result = {
|
|
1266
|
+
newVersion: selectedVersion,
|
|
1267
|
+
bumpType: selectedBumpType,
|
|
1268
|
+
applyToAllRemaining: false
|
|
1269
|
+
};
|
|
1270
|
+
resume(Effect.succeed(result));
|
|
1271
|
+
});
|
|
1272
|
+
});
|
|
1273
|
+
}
|
|
1274
|
+
return {
|
|
1275
|
+
promptForVersion,
|
|
1276
|
+
isEnabled: config.prompts.versions,
|
|
1277
|
+
resetApplyToAll: () => {
|
|
1278
|
+
applyToAllRemainingChoice = null;
|
|
1279
|
+
}
|
|
1280
|
+
};
|
|
1281
|
+
}),
|
|
1282
|
+
dependencies: []
|
|
1283
|
+
}) {};
|
|
1284
|
+
|
|
1006
1285
|
//#endregion
|
|
1007
1286
|
//#region src/utils/helpers.ts
|
|
1008
1287
|
function loadOverrides(options) {
|
|
@@ -1197,43 +1476,90 @@ function constructPrepareProgram(config) {
|
|
|
1197
1476
|
const dependencyGraph = yield* DependencyGraphService;
|
|
1198
1477
|
const packageUpdater = yield* PackageUpdaterService;
|
|
1199
1478
|
const versionCalculator = yield* VersionCalculatorService;
|
|
1479
|
+
const versionPrompt = yield* VersionPromptService;
|
|
1200
1480
|
const workspace = yield* WorkspaceService;
|
|
1201
1481
|
yield* git.workspace.assertWorkspaceReady;
|
|
1202
1482
|
let releasePullRequest = yield* github.getPullRequestByBranch(config.branch.release);
|
|
1203
1483
|
const isNewRelease = !releasePullRequest;
|
|
1204
1484
|
const branchExists = yield* git.branches.exists(config.branch.release);
|
|
1205
1485
|
if (!branchExists) {
|
|
1206
|
-
yield* Console.log(
|
|
1486
|
+
yield* Console.log(`Creating release branch "${config.branch.release}" from "${config.branch.default}"...`);
|
|
1207
1487
|
yield* git.branches.create(config.branch.release, config.branch.default);
|
|
1208
|
-
yield* Console.log(
|
|
1488
|
+
yield* Console.log(`Release branch created.`);
|
|
1209
1489
|
}
|
|
1210
1490
|
if ((yield* git.branches.get) !== config.branch.release) {
|
|
1211
1491
|
yield* git.branches.checkout(config.branch.release);
|
|
1212
|
-
yield* Console.log(
|
|
1492
|
+
yield* Console.log(`Checked out to release branch "${config.branch.release}".`);
|
|
1213
1493
|
}
|
|
1214
1494
|
if (!isNewRelease || branchExists) {
|
|
1215
|
-
yield* Console.log(
|
|
1495
|
+
yield* Console.log(`Rebasing "${config.branch.release}" onto "${config.branch.default}"...`);
|
|
1216
1496
|
yield* git.branches.rebase(config.branch.default);
|
|
1217
|
-
yield* Console.log(
|
|
1497
|
+
yield* Console.log(`Rebase complete.`);
|
|
1218
1498
|
}
|
|
1219
1499
|
const overrides = yield* loadOverrides({
|
|
1220
1500
|
sha: config.branch.default,
|
|
1221
1501
|
overridesPath: ".github/ucdjs-release.overrides.json"
|
|
1222
1502
|
});
|
|
1223
|
-
if (Object.keys(overrides).length > 0) yield* Console.log("
|
|
1503
|
+
if (Object.keys(overrides).length > 0) yield* Console.log("Loaded version overrides:", overrides);
|
|
1224
1504
|
const originalBranch = yield* git.branches.get;
|
|
1225
1505
|
yield* git.branches.checkout(config.branch.default);
|
|
1226
1506
|
const packages = yield* workspace.discoverWorkspacePackages.pipe(Effect.flatMap(mergePackageCommitsIntoPackages), Effect.flatMap((pkgs) => mergeCommitsAffectingGloballyIntoPackage(pkgs, config.globalCommitMode)));
|
|
1227
|
-
yield* Console.log(
|
|
1228
|
-
const releases = yield* versionCalculator.calculateBumps(packages, overrides);
|
|
1507
|
+
yield* Console.log(`Discovered ${packages.length} packages with commits.`);
|
|
1229
1508
|
yield* dependencyGraph.topologicalOrder(packages);
|
|
1509
|
+
const releases = [];
|
|
1510
|
+
if (versionPrompt.isEnabled) {
|
|
1511
|
+
yield* Console.log("\nInteractive version selection enabled.\n");
|
|
1512
|
+
versionPrompt.resetApplyToAll();
|
|
1513
|
+
for (let i = 0; i < packages.length; i++) {
|
|
1514
|
+
const pkg = packages[i];
|
|
1515
|
+
const conventionalBump = determineBump([...pkg.commits, ...pkg.globalCommits]);
|
|
1516
|
+
const remainingCount = packages.length - i;
|
|
1517
|
+
const override = overrides[pkg.name];
|
|
1518
|
+
if (override) {
|
|
1519
|
+
if (!semver.valid(override)) return yield* Effect.fail(/* @__PURE__ */ new Error(`Invalid override version for ${pkg.name}: ${override}`));
|
|
1520
|
+
releases.push({
|
|
1521
|
+
package: {
|
|
1522
|
+
name: pkg.name,
|
|
1523
|
+
version: pkg.version,
|
|
1524
|
+
path: pkg.path,
|
|
1525
|
+
packageJson: pkg.packageJson,
|
|
1526
|
+
workspaceDependencies: pkg.workspaceDependencies,
|
|
1527
|
+
workspaceDevDependencies: pkg.workspaceDevDependencies
|
|
1528
|
+
},
|
|
1529
|
+
currentVersion: pkg.version,
|
|
1530
|
+
newVersion: override,
|
|
1531
|
+
bumpType: "none",
|
|
1532
|
+
hasDirectChanges: pkg.commits.length > 0
|
|
1533
|
+
});
|
|
1534
|
+
continue;
|
|
1535
|
+
}
|
|
1536
|
+
const result = yield* versionPrompt.promptForVersion(pkg, conventionalBump, remainingCount);
|
|
1537
|
+
releases.push({
|
|
1538
|
+
package: {
|
|
1539
|
+
name: pkg.name,
|
|
1540
|
+
version: pkg.version,
|
|
1541
|
+
path: pkg.path,
|
|
1542
|
+
packageJson: pkg.packageJson,
|
|
1543
|
+
workspaceDependencies: pkg.workspaceDependencies,
|
|
1544
|
+
workspaceDevDependencies: pkg.workspaceDevDependencies
|
|
1545
|
+
},
|
|
1546
|
+
currentVersion: pkg.version,
|
|
1547
|
+
newVersion: result.newVersion,
|
|
1548
|
+
bumpType: result.bumpType,
|
|
1549
|
+
hasDirectChanges: pkg.commits.length > 0
|
|
1550
|
+
});
|
|
1551
|
+
}
|
|
1552
|
+
} else {
|
|
1553
|
+
const calculatedReleases = yield* versionCalculator.calculateBumps(packages, overrides);
|
|
1554
|
+
releases.push(...calculatedReleases);
|
|
1555
|
+
}
|
|
1230
1556
|
const releasesCount = releases.length;
|
|
1231
|
-
yield* Console.log(
|
|
1557
|
+
yield* Console.log(`\n${releasesCount} package${releasesCount === 1 ? "" : "s"} will be released.`);
|
|
1232
1558
|
yield* git.branches.checkout(originalBranch);
|
|
1233
|
-
yield* Console.log("
|
|
1559
|
+
yield* Console.log("Updating package.json files...");
|
|
1234
1560
|
yield* packageUpdater.applyReleases(packages, releases);
|
|
1235
|
-
yield* Console.log("
|
|
1236
|
-
yield* Console.log("
|
|
1561
|
+
yield* Console.log("package.json files updated.");
|
|
1562
|
+
yield* Console.log("Generating changelogs...");
|
|
1237
1563
|
const changelogFiles = [];
|
|
1238
1564
|
for (const release of releases) {
|
|
1239
1565
|
const pkg = packages.find((p) => p.name === release.package.name);
|
|
@@ -1247,28 +1573,28 @@ function constructPrepareProgram(config) {
|
|
|
1247
1573
|
});
|
|
1248
1574
|
changelogFiles.push(result.filePath);
|
|
1249
1575
|
}
|
|
1250
|
-
yield* Console.log(
|
|
1576
|
+
yield* Console.log(`Generated ${changelogFiles.length} changelog file${changelogFiles.length === 1 ? "" : "s"}.`);
|
|
1251
1577
|
const filesToStage = [...releases.map((r) => `${r.package.path}/package.json`), ...changelogFiles];
|
|
1252
|
-
yield* Console.log(
|
|
1578
|
+
yield* Console.log(`Staging ${filesToStage.length} file${filesToStage.length === 1 ? "" : "s"}...`);
|
|
1253
1579
|
yield* git.commits.stage(filesToStage);
|
|
1254
1580
|
const commitMessage = `chore(release): prepare release
|
|
1255
1581
|
|
|
1256
1582
|
${releasesCount} package${releasesCount === 1 ? "" : "s"} updated:
|
|
1257
1583
|
${releases.map((r) => ` - ${r.package.name}@${r.newVersion}`).join("\n")}`;
|
|
1258
|
-
yield* Console.log("
|
|
1584
|
+
yield* Console.log("Creating commit...");
|
|
1259
1585
|
yield* git.commits.write(commitMessage);
|
|
1260
|
-
yield* Console.log("
|
|
1261
|
-
yield* Console.log(
|
|
1586
|
+
yield* Console.log("Commit created.");
|
|
1587
|
+
yield* Console.log(`Pushing to "${config.branch.release}"...`);
|
|
1262
1588
|
if (isNewRelease && !branchExists) yield* git.commits.push(config.branch.release);
|
|
1263
1589
|
else yield* git.commits.forcePush(config.branch.release);
|
|
1264
|
-
yield* Console.log(
|
|
1590
|
+
yield* Console.log(`Push complete.`);
|
|
1265
1591
|
const prBody = yield* github.generateReleasePRBody(releases.map((r) => ({
|
|
1266
1592
|
packageName: r.package.name,
|
|
1267
1593
|
version: r.newVersion,
|
|
1268
1594
|
previousVersion: r.package.version
|
|
1269
1595
|
})));
|
|
1270
1596
|
if (isNewRelease) {
|
|
1271
|
-
yield* Console.log("
|
|
1597
|
+
yield* Console.log("Creating release pull request...");
|
|
1272
1598
|
releasePullRequest = yield* github.createPullRequest({
|
|
1273
1599
|
title: config.pullRequest.title,
|
|
1274
1600
|
body: prBody,
|
|
@@ -1276,13 +1602,15 @@ ${releases.map((r) => ` - ${r.package.name}@${r.newVersion}`).join("\n")}`;
|
|
|
1276
1602
|
base: config.branch.default,
|
|
1277
1603
|
draft: true
|
|
1278
1604
|
});
|
|
1279
|
-
yield* Console.log(
|
|
1605
|
+
yield* Console.log(`Release pull request #${releasePullRequest.number} created.`);
|
|
1280
1606
|
} else {
|
|
1281
|
-
yield* Console.log("
|
|
1607
|
+
yield* Console.log("Updating pull request...");
|
|
1282
1608
|
yield* github.updatePullRequest(releasePullRequest.number, { body: prBody });
|
|
1283
|
-
yield* Console.log("
|
|
1609
|
+
yield* Console.log("Pull request updated.");
|
|
1284
1610
|
}
|
|
1285
|
-
yield* Console.log(`\
|
|
1611
|
+
yield* Console.log(`\nRelease preparation complete! View PR: #${releasePullRequest.number}`);
|
|
1612
|
+
yield* git.branches.checkout(config.branch.default);
|
|
1613
|
+
yield* Console.log(`Switched back to "${config.branch.default}".`);
|
|
1286
1614
|
});
|
|
1287
1615
|
}
|
|
1288
1616
|
|
|
@@ -1311,9 +1639,9 @@ function constructPublishProgram(config) {
|
|
|
1311
1639
|
yield* git.workspace.assertWorkspaceReady;
|
|
1312
1640
|
const currentBranch = yield* git.branches.get;
|
|
1313
1641
|
if (currentBranch !== config.branch.default) return yield* Effect.fail(/* @__PURE__ */ new Error(`Publish must be run on the default branch "${config.branch.default}". Current branch: "${currentBranch}"`));
|
|
1314
|
-
yield* Console.log(
|
|
1642
|
+
yield* Console.log(`On default branch "${config.branch.default}".`);
|
|
1315
1643
|
const publicPackages = (yield* workspace.discoverWorkspacePackages).filter((pkg) => !pkg.packageJson.private);
|
|
1316
|
-
yield* Console.log(
|
|
1644
|
+
yield* Console.log(`Found ${publicPackages.length} public package${publicPackages.length === 1 ? "" : "s"} to check.`);
|
|
1317
1645
|
const orderedPackages = yield* dependencyGraph.topologicalOrder(publicPackages);
|
|
1318
1646
|
const results = [];
|
|
1319
1647
|
for (const updateOrder of orderedPackages) {
|
|
@@ -1321,7 +1649,7 @@ function constructPublishProgram(config) {
|
|
|
1321
1649
|
const version = pkg.version;
|
|
1322
1650
|
const tagName = `${pkg.name}@${version}`;
|
|
1323
1651
|
if (yield* npm.versionExists(pkg.name, version)) {
|
|
1324
|
-
yield* Console.log(
|
|
1652
|
+
yield* Console.log(`Skipping ${pkg.name}@${version} - already published.`);
|
|
1325
1653
|
results.push({
|
|
1326
1654
|
packageName: pkg.name,
|
|
1327
1655
|
version,
|
|
@@ -1330,11 +1658,11 @@ function constructPublishProgram(config) {
|
|
|
1330
1658
|
});
|
|
1331
1659
|
continue;
|
|
1332
1660
|
}
|
|
1333
|
-
yield* Console.log(
|
|
1661
|
+
yield* Console.log(`Building ${pkg.name}...`);
|
|
1334
1662
|
yield* buildPackage(pkg.path);
|
|
1335
|
-
yield* Console.log(
|
|
1663
|
+
yield* Console.log(`Build complete for ${pkg.name}.`);
|
|
1336
1664
|
const distTag = getDistTag(version);
|
|
1337
|
-
yield* Console.log(
|
|
1665
|
+
yield* Console.log(`Publishing ${pkg.name}@${version} with tag "${distTag}"...`);
|
|
1338
1666
|
const publishResult = yield* npm.publish({
|
|
1339
1667
|
packagePath: pkg.path,
|
|
1340
1668
|
tagName: distTag,
|
|
@@ -1346,13 +1674,13 @@ function constructPublishProgram(config) {
|
|
|
1346
1674
|
error: err
|
|
1347
1675
|
})));
|
|
1348
1676
|
if (publishResult.success) {
|
|
1349
|
-
yield* Console.log(
|
|
1677
|
+
yield* Console.log(`Published ${pkg.name}@${version}.`);
|
|
1350
1678
|
if (!config.dryRun) {
|
|
1351
|
-
yield* Console.log(
|
|
1679
|
+
yield* Console.log(`Creating tag ${tagName}...`);
|
|
1352
1680
|
yield* git.tags.create(tagName, `Release ${tagName}`);
|
|
1353
1681
|
yield* git.tags.push(tagName);
|
|
1354
|
-
yield* Console.log(
|
|
1355
|
-
} else yield* Console.log(
|
|
1682
|
+
yield* Console.log(`Tag ${tagName} created and pushed.`);
|
|
1683
|
+
} else yield* Console.log(`[Dry Run] Would create and push tag ${tagName}.`);
|
|
1356
1684
|
results.push({
|
|
1357
1685
|
packageName: pkg.name,
|
|
1358
1686
|
version,
|
|
@@ -1360,7 +1688,7 @@ function constructPublishProgram(config) {
|
|
|
1360
1688
|
});
|
|
1361
1689
|
} else {
|
|
1362
1690
|
const error = publishResult.error;
|
|
1363
|
-
yield* Console.log(
|
|
1691
|
+
yield* Console.log(`Failed to publish ${pkg.name}@${version}: ${error.message}`);
|
|
1364
1692
|
results.push({
|
|
1365
1693
|
packageName: pkg.name,
|
|
1366
1694
|
version,
|
|
@@ -1372,17 +1700,17 @@ function constructPublishProgram(config) {
|
|
|
1372
1700
|
const published = results.filter((r) => r.status === "published");
|
|
1373
1701
|
const skipped = results.filter((r) => r.status === "skipped");
|
|
1374
1702
|
const failed = results.filter((r) => r.status === "failed");
|
|
1375
|
-
yield* Console.log("\
|
|
1703
|
+
yield* Console.log("\nPublish Summary:");
|
|
1376
1704
|
yield* Console.log(` Published: ${published.length}`);
|
|
1377
1705
|
yield* Console.log(` Skipped: ${skipped.length}`);
|
|
1378
1706
|
yield* Console.log(` Failed: ${failed.length}`);
|
|
1379
1707
|
if (failed.length > 0) {
|
|
1380
|
-
yield* Console.log("\
|
|
1708
|
+
yield* Console.log("\nFailed packages:");
|
|
1381
1709
|
for (const f of failed) yield* Console.log(` - ${f.packageName}@${f.version}: ${f.reason}`);
|
|
1382
1710
|
return yield* Effect.fail(/* @__PURE__ */ new Error("Some packages failed to publish."));
|
|
1383
1711
|
}
|
|
1384
|
-
if (published.length === 0 && skipped.length > 0) yield* Console.log("\
|
|
1385
|
-
else if (published.length > 0) yield* Console.log("\
|
|
1712
|
+
if (published.length === 0 && skipped.length > 0) yield* Console.log("\nAll packages were already published.");
|
|
1713
|
+
else if (published.length > 0) yield* Console.log("\nPublish complete!");
|
|
1386
1714
|
});
|
|
1387
1715
|
}
|
|
1388
1716
|
|
|
@@ -1468,10 +1796,10 @@ function constructVerifyProgram(config) {
|
|
|
1468
1796
|
yield* git.workspace.assertWorkspaceReady;
|
|
1469
1797
|
const releasePullRequest = yield* github.getPullRequestByBranch(config.branch.release);
|
|
1470
1798
|
if (!releasePullRequest || !releasePullRequest.head) return yield* Effect.fail(/* @__PURE__ */ new Error(`Release pull request for branch "${config.branch.release}" does not exist.`));
|
|
1471
|
-
yield* Console.log(
|
|
1799
|
+
yield* Console.log(`Release pull request #${releasePullRequest.number} exists.`);
|
|
1472
1800
|
if ((yield* git.branches.get) !== config.branch.default) {
|
|
1473
1801
|
yield* git.branches.checkout(config.branch.default);
|
|
1474
|
-
yield* Console.log(
|
|
1802
|
+
yield* Console.log(`Checked out to default branch "${config.branch.default}".`);
|
|
1475
1803
|
}
|
|
1476
1804
|
const overrides = yield* loadOverrides({
|
|
1477
1805
|
sha: releasePullRequest.head.sha,
|
|
@@ -1491,8 +1819,8 @@ function constructVerifyProgram(config) {
|
|
|
1491
1819
|
branchSnapshots.set(pkg.name, snapshot);
|
|
1492
1820
|
}
|
|
1493
1821
|
const drift = findDrift(packages, releases, branchSnapshots);
|
|
1494
|
-
if (drift.length === 0) yield* Console.log("
|
|
1495
|
-
else yield* Console.log("
|
|
1822
|
+
if (drift.length === 0) yield* Console.log("Release branch is in sync with expected releases.");
|
|
1823
|
+
else yield* Console.log("Release branch is out of sync:", drift);
|
|
1496
1824
|
const status = drift.length === 0 ? {
|
|
1497
1825
|
state: "success",
|
|
1498
1826
|
description: "Release artifacts in sync",
|
|
@@ -1511,7 +1839,7 @@ function constructVerifyProgram(config) {
|
|
|
1511
1839
|
//#region src/index.ts
|
|
1512
1840
|
async function createReleaseScripts(options) {
|
|
1513
1841
|
const config = normalizeReleaseScriptsOptions(options);
|
|
1514
|
-
const AppLayer = Layer.mergeAll(ChangelogService.Default, GitService.Default, GitHubService.Default, DependencyGraphService.Default, NPMService.Default, PackageUpdaterService.Default, VersionCalculatorService.Default, WorkspaceService.Default).pipe(Layer.provide(Layer.succeed(ReleaseScriptsOptions, config)), Layer.provide(NodeCommandExecutor.layer), Layer.provide(NodeFileSystem.layer));
|
|
1842
|
+
const AppLayer = Layer.mergeAll(ChangelogService.Default, GitService.Default, GitHubService.Default, DependencyGraphService.Default, NPMService.Default, PackageUpdaterService.Default, VersionCalculatorService.Default, VersionPromptService.Default, WorkspaceService.Default).pipe(Layer.provide(Layer.succeed(ReleaseScriptsOptions, config)), Layer.provide(NodeCommandExecutor.layer), Layer.provide(NodeFileSystem.layer));
|
|
1515
1843
|
const runProgram = (program) => {
|
|
1516
1844
|
const provided = program.pipe(Effect.provide(AppLayer));
|
|
1517
1845
|
return Effect.runPromise(provided);
|