@ucdjs/release-scripts 0.1.0-beta.41 → 0.1.0-beta.43
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.mjs +177 -54
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -60,6 +60,51 @@ const args = mri(process.argv.slice(2));
|
|
|
60
60
|
const isDryRun = !!args.dry;
|
|
61
61
|
const isVerbose = !!args.verbose;
|
|
62
62
|
const isForce = !!args.force;
|
|
63
|
+
function toTrimmedString(value) {
|
|
64
|
+
if (typeof value === "string") {
|
|
65
|
+
const normalized = value.trim();
|
|
66
|
+
return normalized.length > 0 ? normalized : void 0;
|
|
67
|
+
}
|
|
68
|
+
if (value instanceof Uint8Array) {
|
|
69
|
+
const normalized = new TextDecoder().decode(value).trim();
|
|
70
|
+
return normalized.length > 0 ? normalized : void 0;
|
|
71
|
+
}
|
|
72
|
+
if (isRecord(value) && typeof value.toString === "function") {
|
|
73
|
+
const rendered = value.toString();
|
|
74
|
+
if (typeof rendered === "string" && rendered !== "[object Object]") {
|
|
75
|
+
const normalized = rendered.trim();
|
|
76
|
+
return normalized.length > 0 ? normalized : void 0;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
function getNestedField(record, keys) {
|
|
81
|
+
let current = record;
|
|
82
|
+
for (const key of keys) {
|
|
83
|
+
if (!isRecord(current) || !(key in current)) return;
|
|
84
|
+
current = current[key];
|
|
85
|
+
}
|
|
86
|
+
return current;
|
|
87
|
+
}
|
|
88
|
+
function extractStderrLike(record) {
|
|
89
|
+
const candidates = [
|
|
90
|
+
record.stderr,
|
|
91
|
+
record.stdout,
|
|
92
|
+
record.shortMessage,
|
|
93
|
+
record.originalMessage,
|
|
94
|
+
getNestedField(record, ["result", "stderr"]),
|
|
95
|
+
getNestedField(record, ["result", "stdout"]),
|
|
96
|
+
getNestedField(record, ["output", "stderr"]),
|
|
97
|
+
getNestedField(record, ["output", "stdout"]),
|
|
98
|
+
getNestedField(record, ["cause", "stderr"]),
|
|
99
|
+
getNestedField(record, ["cause", "stdout"]),
|
|
100
|
+
getNestedField(record, ["cause", "shortMessage"]),
|
|
101
|
+
getNestedField(record, ["cause", "originalMessage"])
|
|
102
|
+
];
|
|
103
|
+
for (const candidate of candidates) {
|
|
104
|
+
const rendered = toTrimmedString(candidate);
|
|
105
|
+
if (rendered) return rendered;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
63
108
|
const ucdjsReleaseOverridesPath = ".github/ucdjs-release.overrides.json";
|
|
64
109
|
const isCI = typeof process.env.CI === "string" && process.env.CI !== "" && process.env.CI.toLowerCase() !== "false";
|
|
65
110
|
const logger = {
|
|
@@ -123,8 +168,49 @@ async function dryRun(bin, args, opts) {
|
|
|
123
168
|
return logger.verbose(farver.blue(`[dryrun] ${bin} ${args.join(" ")}`), opts || "");
|
|
124
169
|
}
|
|
125
170
|
const runIfNotDry = isDryRun ? dryRun : run;
|
|
126
|
-
function
|
|
171
|
+
function isRecord(value) {
|
|
172
|
+
return typeof value === "object" && value !== null;
|
|
173
|
+
}
|
|
174
|
+
function formatUnknownError(error) {
|
|
175
|
+
if (error instanceof Error) {
|
|
176
|
+
const base = {
|
|
177
|
+
message: error.message || error.name,
|
|
178
|
+
stack: error.stack
|
|
179
|
+
};
|
|
180
|
+
const maybeError = error;
|
|
181
|
+
if (typeof maybeError.code === "string") base.code = maybeError.code;
|
|
182
|
+
if (typeof maybeError.status === "number") base.status = maybeError.status;
|
|
183
|
+
base.stderr = extractStderrLike(maybeError);
|
|
184
|
+
if (typeof maybeError.shortMessage === "string" && maybeError.shortMessage.trim() && base.message.startsWith("Process exited with non-zero status")) base.message = maybeError.shortMessage.trim();
|
|
185
|
+
if (!base.stderr && typeof maybeError.cause === "string" && maybeError.cause.trim()) base.stderr = maybeError.cause.trim();
|
|
186
|
+
return base;
|
|
187
|
+
}
|
|
188
|
+
if (typeof error === "string") return { message: error };
|
|
189
|
+
if (isRecord(error)) {
|
|
190
|
+
const formatted = { message: typeof error.message === "string" ? error.message : typeof error.error === "string" ? error.error : JSON.stringify(error) };
|
|
191
|
+
if (typeof error.code === "string") formatted.code = error.code;
|
|
192
|
+
if (typeof error.status === "number") formatted.status = error.status;
|
|
193
|
+
formatted.stderr = extractStderrLike(error);
|
|
194
|
+
return formatted;
|
|
195
|
+
}
|
|
196
|
+
return { message: String(error) };
|
|
197
|
+
}
|
|
198
|
+
function exitWithError(message, hint, cause) {
|
|
127
199
|
logger.error(farver.bold(message));
|
|
200
|
+
if (cause !== void 0) {
|
|
201
|
+
const formatted = formatUnknownError(cause);
|
|
202
|
+
if (formatted.message && formatted.message !== message) console.error(farver.gray(` Cause: ${formatted.message}`));
|
|
203
|
+
if (formatted.code) console.error(farver.gray(` Code: ${formatted.code}`));
|
|
204
|
+
if (typeof formatted.status === "number") console.error(farver.gray(` Status: ${formatted.status}`));
|
|
205
|
+
if (formatted.stderr) {
|
|
206
|
+
console.error(farver.gray(" Stderr:"));
|
|
207
|
+
console.error(farver.gray(` ${formatted.stderr}`));
|
|
208
|
+
}
|
|
209
|
+
if (isVerbose && formatted.stack) {
|
|
210
|
+
console.error(farver.gray(" Stack:"));
|
|
211
|
+
console.error(farver.gray(` ${formatted.stack}`));
|
|
212
|
+
}
|
|
213
|
+
}
|
|
128
214
|
if (hint) console.error(farver.gray(` ${hint}`));
|
|
129
215
|
process.exit(1);
|
|
130
216
|
}
|
|
@@ -140,6 +226,15 @@ if (isDryRun || isVerbose || isForce) {
|
|
|
140
226
|
|
|
141
227
|
//#endregion
|
|
142
228
|
//#region src/core/github.ts
|
|
229
|
+
function toGitHubError(operation, error) {
|
|
230
|
+
const formatted = formatUnknownError(error);
|
|
231
|
+
return {
|
|
232
|
+
type: "github",
|
|
233
|
+
operation,
|
|
234
|
+
message: formatted.message,
|
|
235
|
+
status: formatted.status
|
|
236
|
+
};
|
|
237
|
+
}
|
|
143
238
|
var GitHubClient = class {
|
|
144
239
|
owner;
|
|
145
240
|
repo;
|
|
@@ -152,18 +247,36 @@ var GitHubClient = class {
|
|
|
152
247
|
}
|
|
153
248
|
async request(path, init = {}) {
|
|
154
249
|
const url = path.startsWith("http") ? path : `${this.apiBase}${path}`;
|
|
155
|
-
const
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
250
|
+
const method = init.method ?? "GET";
|
|
251
|
+
let res;
|
|
252
|
+
try {
|
|
253
|
+
res = await fetch(url, {
|
|
254
|
+
...init,
|
|
255
|
+
headers: {
|
|
256
|
+
...init.headers,
|
|
257
|
+
"Accept": "application/vnd.github.v3+json",
|
|
258
|
+
"Authorization": `token ${this.githubToken}`,
|
|
259
|
+
"User-Agent": "ucdjs-release-scripts (+https://github.com/ucdjs/ucdjs-release-scripts)"
|
|
260
|
+
}
|
|
261
|
+
});
|
|
262
|
+
} catch (error) {
|
|
263
|
+
throw Object.assign(/* @__PURE__ */ new Error(`[${method} ${path}] GitHub request failed: ${formatUnknownError(error).message}`), { status: void 0 });
|
|
264
|
+
}
|
|
164
265
|
if (!res.ok) {
|
|
165
266
|
const errorText = await res.text();
|
|
166
|
-
|
|
267
|
+
const parsedMessage = (() => {
|
|
268
|
+
try {
|
|
269
|
+
const parsed = JSON.parse(errorText);
|
|
270
|
+
if (typeof parsed.message === "string" && parsed.message.trim()) {
|
|
271
|
+
if (Array.isArray(parsed.errors) && parsed.errors.length > 0) return `${parsed.message} (${JSON.stringify(parsed.errors)})`;
|
|
272
|
+
return parsed.message;
|
|
273
|
+
}
|
|
274
|
+
return errorText;
|
|
275
|
+
} catch {
|
|
276
|
+
return errorText;
|
|
277
|
+
}
|
|
278
|
+
})();
|
|
279
|
+
throw Object.assign(/* @__PURE__ */ new Error(`[${method} ${path}] GitHub API request failed (${res.status} ${res.statusText}): ${parsedMessage || "No response body"}`), { status: res.status });
|
|
167
280
|
}
|
|
168
281
|
if (res.status === 204) return;
|
|
169
282
|
return res.json();
|
|
@@ -238,14 +351,14 @@ var GitHubClient = class {
|
|
|
238
351
|
if (!data.items || data.items.length === 0) return info;
|
|
239
352
|
info.login = data.items[0].login;
|
|
240
353
|
} catch (err) {
|
|
241
|
-
logger.warn(`Failed to resolve author info for email ${info.email}: ${err.message}`);
|
|
354
|
+
logger.warn(`Failed to resolve author info for email ${info.email}: ${formatUnknownError(err).message}`);
|
|
242
355
|
}
|
|
243
356
|
if (info.login) return info;
|
|
244
357
|
if (info.commits.length > 0) try {
|
|
245
358
|
const data = await this.request(`/repos/${this.owner}/${this.repo}/commits/${info.commits[0]}`);
|
|
246
359
|
if (data.author && data.author.login) info.login = data.author.login;
|
|
247
360
|
} catch (err) {
|
|
248
|
-
logger.warn(`Failed to resolve author info from commits for email ${info.email}: ${err.message}`);
|
|
361
|
+
logger.warn(`Failed to resolve author info from commits for email ${info.email}: ${formatUnknownError(err).message}`);
|
|
249
362
|
}
|
|
250
363
|
return info;
|
|
251
364
|
}
|
|
@@ -391,11 +504,12 @@ function err(error) {
|
|
|
391
504
|
//#endregion
|
|
392
505
|
//#region src/core/git.ts
|
|
393
506
|
function toGitError(operation, error) {
|
|
507
|
+
const formatted = formatUnknownError(error);
|
|
394
508
|
return {
|
|
395
509
|
type: "git",
|
|
396
510
|
operation,
|
|
397
|
-
message:
|
|
398
|
-
stderr:
|
|
511
|
+
message: formatted.message,
|
|
512
|
+
stderr: formatted.stderr
|
|
399
513
|
};
|
|
400
514
|
}
|
|
401
515
|
async function isWorkingDirectoryClean(workspaceRoot) {
|
|
@@ -425,7 +539,8 @@ async function doesBranchExist(branch, workspaceRoot) {
|
|
|
425
539
|
stdio: "pipe"
|
|
426
540
|
} });
|
|
427
541
|
return ok(true);
|
|
428
|
-
} catch {
|
|
542
|
+
} catch (error) {
|
|
543
|
+
logger.verbose(`Failed to verify branch "${branch}": ${formatUnknownError(error).message}`);
|
|
429
544
|
return ok(false);
|
|
430
545
|
}
|
|
431
546
|
}
|
|
@@ -495,8 +610,8 @@ async function checkoutBranch(branch, workspaceRoot) {
|
|
|
495
610
|
stdio: "pipe"
|
|
496
611
|
} });
|
|
497
612
|
logger.verbose(`Available branches:\n${branchResult.stdout}`);
|
|
498
|
-
} catch {
|
|
499
|
-
logger.verbose(
|
|
613
|
+
} catch (error) {
|
|
614
|
+
logger.verbose(`Could not list available branches: ${formatUnknownError(error).message}`);
|
|
500
615
|
}
|
|
501
616
|
return err(gitError);
|
|
502
617
|
}
|
|
@@ -539,7 +654,8 @@ async function isBranchAheadOfRemote(branch, workspaceRoot) {
|
|
|
539
654
|
stdio: "pipe"
|
|
540
655
|
} });
|
|
541
656
|
return ok(Number.parseInt(result.stdout.trim(), 10) > 0);
|
|
542
|
-
} catch {
|
|
657
|
+
} catch (error) {
|
|
658
|
+
logger.verbose(`Failed to compare branch "${branch}" with remote: ${formatUnknownError(error).message}`);
|
|
543
659
|
return ok(true);
|
|
544
660
|
}
|
|
545
661
|
}
|
|
@@ -575,7 +691,7 @@ async function pushBranch(branch, workspaceRoot, options) {
|
|
|
575
691
|
"origin",
|
|
576
692
|
branch
|
|
577
693
|
];
|
|
578
|
-
if (options?.forceWithLease) {
|
|
694
|
+
if (options?.forceWithLease) try {
|
|
579
695
|
await run("git", [
|
|
580
696
|
"fetch",
|
|
581
697
|
"origin",
|
|
@@ -586,7 +702,12 @@ async function pushBranch(branch, workspaceRoot, options) {
|
|
|
586
702
|
} });
|
|
587
703
|
args.push("--force-with-lease");
|
|
588
704
|
logger.info(`Pushing branch: ${farver.green(branch)} ${farver.dim("(with lease)")}`);
|
|
589
|
-
}
|
|
705
|
+
} catch (error) {
|
|
706
|
+
const fetchError = toGitError("pushBranch.fetch", error);
|
|
707
|
+
if (fetchError.stderr?.includes("couldn't find remote ref") || fetchError.message.includes("couldn't find remote ref")) logger.verbose(`Remote branch origin/${branch} does not exist yet, falling back to regular push without --force-with-lease.`);
|
|
708
|
+
else return err(fetchError);
|
|
709
|
+
}
|
|
710
|
+
else if (options?.force) {
|
|
590
711
|
args.push("--force");
|
|
591
712
|
logger.info(`Force pushing branch: ${farver.green(branch)}`);
|
|
592
713
|
} else logger.info(`Pushing branch: ${farver.green(branch)}`);
|
|
@@ -605,7 +726,8 @@ async function readFileFromGit(workspaceRoot, ref, filePath) {
|
|
|
605
726
|
cwd: workspaceRoot,
|
|
606
727
|
stdio: "pipe"
|
|
607
728
|
} })).stdout);
|
|
608
|
-
} catch {
|
|
729
|
+
} catch (error) {
|
|
730
|
+
logger.verbose(`Failed to read ${filePath} from ${ref}: ${formatUnknownError(error).message}`);
|
|
609
731
|
return ok(null);
|
|
610
732
|
}
|
|
611
733
|
}
|
|
@@ -1663,11 +1785,7 @@ async function syncPullRequest(options) {
|
|
|
1663
1785
|
} catch (error) {
|
|
1664
1786
|
return {
|
|
1665
1787
|
ok: false,
|
|
1666
|
-
error:
|
|
1667
|
-
type: "github",
|
|
1668
|
-
operation: "getExistingPullRequest",
|
|
1669
|
-
message: error instanceof Error ? error.message : String(error)
|
|
1670
|
-
}
|
|
1788
|
+
error: toGitHubError("getExistingPullRequest", error)
|
|
1671
1789
|
};
|
|
1672
1790
|
}
|
|
1673
1791
|
const doesExist = !!existing;
|
|
@@ -1685,11 +1803,7 @@ async function syncPullRequest(options) {
|
|
|
1685
1803
|
} catch (error) {
|
|
1686
1804
|
return {
|
|
1687
1805
|
ok: false,
|
|
1688
|
-
error:
|
|
1689
|
-
type: "github",
|
|
1690
|
-
operation: "upsertPullRequest",
|
|
1691
|
-
message: error instanceof Error ? error.message : String(error)
|
|
1692
|
-
}
|
|
1806
|
+
error: toGitHubError("upsertPullRequest", error)
|
|
1693
1807
|
};
|
|
1694
1808
|
}
|
|
1695
1809
|
return ok({
|
|
@@ -1703,10 +1817,11 @@ async function syncPullRequest(options) {
|
|
|
1703
1817
|
async function prepareWorkflow(options) {
|
|
1704
1818
|
if (options.safeguards) {
|
|
1705
1819
|
const clean = await isWorkingDirectoryClean(options.workspaceRoot);
|
|
1706
|
-
if (!clean.ok
|
|
1820
|
+
if (!clean.ok) exitWithError("Failed to verify working directory state.", "Ensure this is a valid git repository and try again.", clean.error);
|
|
1821
|
+
if (!clean.value) exitWithError("Working directory is not clean. Please commit or stash your changes before proceeding.");
|
|
1707
1822
|
}
|
|
1708
1823
|
const discovered = await discoverWorkspacePackages(options.workspaceRoot, options);
|
|
1709
|
-
if (!discovered.ok) exitWithError(
|
|
1824
|
+
if (!discovered.ok) exitWithError("Failed to discover packages.", void 0, discovered.error);
|
|
1710
1825
|
const ensured = ensureHasPackages(discovered.value);
|
|
1711
1826
|
if (!ensured.ok) {
|
|
1712
1827
|
logger.warn(ensured.error.message);
|
|
@@ -1725,15 +1840,16 @@ async function prepareWorkflow(options) {
|
|
|
1725
1840
|
releaseBranch: options.branch.release,
|
|
1726
1841
|
defaultBranch: options.branch.default
|
|
1727
1842
|
});
|
|
1728
|
-
if (!prepareBranchResult.ok) exitWithError(prepareBranchResult.error
|
|
1843
|
+
if (!prepareBranchResult.ok) exitWithError("Failed to prepare release branch.", void 0, prepareBranchResult.error);
|
|
1729
1844
|
const overridesPath = join(options.workspaceRoot, ucdjsReleaseOverridesPath);
|
|
1730
1845
|
let existingOverrides = {};
|
|
1731
1846
|
try {
|
|
1732
1847
|
const overridesContent = await readFile(overridesPath, "utf-8");
|
|
1733
1848
|
existingOverrides = JSON.parse(overridesContent);
|
|
1734
1849
|
logger.info("Found existing version overrides file.");
|
|
1735
|
-
} catch {
|
|
1850
|
+
} catch (error) {
|
|
1736
1851
|
logger.info("No existing version overrides file found. Continuing...");
|
|
1852
|
+
logger.verbose(`Reading overrides file failed: ${formatUnknownError(error).message}`);
|
|
1737
1853
|
}
|
|
1738
1854
|
const updatesResult = await calculateUpdates({
|
|
1739
1855
|
workspacePackages,
|
|
@@ -1742,7 +1858,7 @@ async function prepareWorkflow(options) {
|
|
|
1742
1858
|
globalCommitMode: options.globalCommitMode === "none" ? false : options.globalCommitMode,
|
|
1743
1859
|
overrides: existingOverrides
|
|
1744
1860
|
});
|
|
1745
|
-
if (!updatesResult.ok) exitWithError(updatesResult.error
|
|
1861
|
+
if (!updatesResult.ok) exitWithError("Failed to calculate package updates.", void 0, updatesResult.error);
|
|
1746
1862
|
const { allUpdates, applyUpdates, overrides: newOverrides } = updatesResult.value;
|
|
1747
1863
|
if (Object.keys(newOverrides).length > 0) {
|
|
1748
1864
|
logger.info("Writing version overrides file...");
|
|
@@ -1815,7 +1931,7 @@ async function prepareWorkflow(options) {
|
|
|
1815
1931
|
commitMessage: "chore: update release versions",
|
|
1816
1932
|
hasChanges: true
|
|
1817
1933
|
});
|
|
1818
|
-
if (!hasChangesToPush.ok) exitWithError(hasChangesToPush.error
|
|
1934
|
+
if (!hasChangesToPush.ok) exitWithError("Failed to sync release changes.", void 0, hasChangesToPush.error);
|
|
1819
1935
|
if (!hasChangesToPush.value) {
|
|
1820
1936
|
const prResult = await syncPullRequest({
|
|
1821
1937
|
github: options.githubClient,
|
|
@@ -1825,7 +1941,7 @@ async function prepareWorkflow(options) {
|
|
|
1825
1941
|
pullRequestBody: options.pullRequest?.body,
|
|
1826
1942
|
updates: allUpdates
|
|
1827
1943
|
});
|
|
1828
|
-
if (!prResult.ok) exitWithError(prResult.error
|
|
1944
|
+
if (!prResult.ok) exitWithError("Failed to sync release pull request.", void 0, prResult.error);
|
|
1829
1945
|
if (prResult.value.pullRequest) {
|
|
1830
1946
|
logger.item("No updates needed, PR is already up to date");
|
|
1831
1947
|
return {
|
|
@@ -1845,13 +1961,14 @@ async function prepareWorkflow(options) {
|
|
|
1845
1961
|
pullRequestBody: options.pullRequest?.body,
|
|
1846
1962
|
updates: allUpdates
|
|
1847
1963
|
});
|
|
1848
|
-
if (!prResult.ok) exitWithError(prResult.error
|
|
1964
|
+
if (!prResult.ok) exitWithError("Failed to sync release pull request.", void 0, prResult.error);
|
|
1849
1965
|
if (prResult.value.pullRequest?.html_url) {
|
|
1850
1966
|
logger.section("🚀 Pull Request");
|
|
1851
1967
|
logger.success(`Pull request ${prResult.value.created ? "created" : "updated"}: ${prResult.value.pullRequest.html_url}`);
|
|
1852
1968
|
}
|
|
1853
1969
|
const returnToDefault = await checkoutBranch(options.branch.default, options.workspaceRoot);
|
|
1854
|
-
if (!returnToDefault.ok
|
|
1970
|
+
if (!returnToDefault.ok) exitWithError(`Failed to checkout branch: ${options.branch.default}`, void 0, returnToDefault.error);
|
|
1971
|
+
if (!returnToDefault.value) exitWithError(`Failed to checkout branch: ${options.branch.default}`);
|
|
1855
1972
|
return {
|
|
1856
1973
|
updates: allUpdates,
|
|
1857
1974
|
prUrl: prResult.value.pullRequest?.html_url,
|
|
@@ -1862,11 +1979,14 @@ async function prepareWorkflow(options) {
|
|
|
1862
1979
|
//#endregion
|
|
1863
1980
|
//#region src/core/npm.ts
|
|
1864
1981
|
function toNPMError(operation, error, code) {
|
|
1982
|
+
const formatted = formatUnknownError(error);
|
|
1865
1983
|
return {
|
|
1866
1984
|
type: "npm",
|
|
1867
1985
|
operation,
|
|
1868
|
-
message:
|
|
1869
|
-
code
|
|
1986
|
+
message: formatted.message,
|
|
1987
|
+
code: code || formatted.code,
|
|
1988
|
+
stderr: formatted.stderr,
|
|
1989
|
+
status: formatted.status
|
|
1870
1990
|
};
|
|
1871
1991
|
}
|
|
1872
1992
|
/**
|
|
@@ -1961,7 +2081,7 @@ async function publishPackage(packageName, workspaceRoot, options) {
|
|
|
1961
2081
|
} });
|
|
1962
2082
|
return ok(void 0);
|
|
1963
2083
|
} catch (error) {
|
|
1964
|
-
const errorMessage = error
|
|
2084
|
+
const errorMessage = formatUnknownError(error).message;
|
|
1965
2085
|
return err(toNPMError("publishPackage", error, errorMessage.includes("E403") ? "E403" : errorMessage.includes("EPUBLISHCONFLICT") ? "EPUBLISHCONFLICT" : errorMessage.includes("EOTP") ? "EOTP" : void 0));
|
|
1966
2086
|
}
|
|
1967
2087
|
}
|
|
@@ -1971,7 +2091,7 @@ async function publishPackage(packageName, workspaceRoot, options) {
|
|
|
1971
2091
|
async function publishWorkflow(options) {
|
|
1972
2092
|
logger.section("📦 Publishing Packages");
|
|
1973
2093
|
const discovered = await discoverWorkspacePackages(options.workspaceRoot, options);
|
|
1974
|
-
if (!discovered.ok) exitWithError(
|
|
2094
|
+
if (!discovered.ok) exitWithError("Failed to discover packages.", void 0, discovered.error);
|
|
1975
2095
|
const workspacePackages = discovered.value;
|
|
1976
2096
|
logger.item(`Found ${workspacePackages.length} packages in workspace`);
|
|
1977
2097
|
const graph = buildPackageDependencyGraph(workspacePackages);
|
|
@@ -1997,7 +2117,7 @@ async function publishWorkflow(options) {
|
|
|
1997
2117
|
if (!existsResult.ok) {
|
|
1998
2118
|
logger.error(`Failed to check version: ${existsResult.error.message}`);
|
|
1999
2119
|
status.failed.push(packageName);
|
|
2000
|
-
exitWithError(`Publishing failed for ${packageName}
|
|
2120
|
+
exitWithError(`Publishing failed for ${packageName}.`, "Check your network connection and NPM registry access", existsResult.error);
|
|
2001
2121
|
}
|
|
2002
2122
|
if (existsResult.value) {
|
|
2003
2123
|
logger.info(`Version ${farver.cyan(version)} already exists on NPM, skipping`);
|
|
@@ -2010,7 +2130,7 @@ async function publishWorkflow(options) {
|
|
|
2010
2130
|
if (!buildResult.ok) {
|
|
2011
2131
|
logger.error(`Failed to build package: ${buildResult.error.message}`);
|
|
2012
2132
|
status.failed.push(packageName);
|
|
2013
|
-
exitWithError(`Publishing failed for ${packageName}: build failed`, "Check your build scripts and dependencies");
|
|
2133
|
+
exitWithError(`Publishing failed for ${packageName}: build failed`, "Check your build scripts and dependencies", buildResult.error);
|
|
2014
2134
|
}
|
|
2015
2135
|
}
|
|
2016
2136
|
logger.step(`Publishing ${farver.cyan(`${packageName}@${version}`)} to NPM...`);
|
|
@@ -2022,7 +2142,7 @@ async function publishWorkflow(options) {
|
|
|
2022
2142
|
if (publishResult.error.code === "E403") hint = "Authentication failed. Ensure your NPM token or OIDC configuration is correct";
|
|
2023
2143
|
else if (publishResult.error.code === "EPUBLISHCONFLICT") hint = "Version conflict. The version may have been published recently";
|
|
2024
2144
|
else if (publishResult.error.code === "EOTP") hint = "2FA/OTP required. Provide the otp option or use OIDC authentication";
|
|
2025
|
-
exitWithError(`Publishing failed for ${packageName}`, hint);
|
|
2145
|
+
exitWithError(`Publishing failed for ${packageName}`, hint, publishResult.error);
|
|
2026
2146
|
}
|
|
2027
2147
|
logger.success(`Published ${farver.cyan(`${packageName}@${version}`)}`);
|
|
2028
2148
|
status.published.push(packageName);
|
|
@@ -2053,7 +2173,8 @@ async function publishWorkflow(options) {
|
|
|
2053
2173
|
async function verifyWorkflow(options) {
|
|
2054
2174
|
if (options.safeguards) {
|
|
2055
2175
|
const clean = await isWorkingDirectoryClean(options.workspaceRoot);
|
|
2056
|
-
if (!clean.ok
|
|
2176
|
+
if (!clean.ok) exitWithError("Failed to verify working directory state.", "Ensure this is a valid git repository and try again.", clean.error);
|
|
2177
|
+
if (!clean.value) exitWithError("Working directory is not clean. Please commit or stash your changes before proceeding.");
|
|
2057
2178
|
}
|
|
2058
2179
|
const releaseBranch = options.branch.release;
|
|
2059
2180
|
const defaultBranch = options.branch.default;
|
|
@@ -2064,10 +2185,11 @@ async function verifyWorkflow(options) {
|
|
|
2064
2185
|
}
|
|
2065
2186
|
logger.info(`Found release PR #${releasePr.number}. Verifying against default branch "${defaultBranch}"...`);
|
|
2066
2187
|
const originalBranch = await getCurrentBranch(options.workspaceRoot);
|
|
2067
|
-
if (!originalBranch.ok) exitWithError(originalBranch.error
|
|
2188
|
+
if (!originalBranch.ok) exitWithError("Failed to detect current branch.", void 0, originalBranch.error);
|
|
2068
2189
|
if (originalBranch.value !== defaultBranch) {
|
|
2069
2190
|
const checkout = await checkoutBranch(defaultBranch, options.workspaceRoot);
|
|
2070
|
-
if (!checkout.ok
|
|
2191
|
+
if (!checkout.ok) exitWithError(`Failed to checkout branch: ${defaultBranch}`, void 0, checkout.error);
|
|
2192
|
+
if (!checkout.value) exitWithError(`Failed to checkout branch: ${defaultBranch}`);
|
|
2071
2193
|
}
|
|
2072
2194
|
let existingOverrides = {};
|
|
2073
2195
|
try {
|
|
@@ -2076,11 +2198,12 @@ async function verifyWorkflow(options) {
|
|
|
2076
2198
|
existingOverrides = JSON.parse(overridesContent.value);
|
|
2077
2199
|
logger.info("Found existing version overrides file on release branch.");
|
|
2078
2200
|
}
|
|
2079
|
-
} catch {
|
|
2201
|
+
} catch (error) {
|
|
2080
2202
|
logger.info("No version overrides file found on release branch. Continuing...");
|
|
2203
|
+
logger.verbose(`Reading release overrides failed: ${formatUnknownError(error).message}`);
|
|
2081
2204
|
}
|
|
2082
2205
|
const discovered = await discoverWorkspacePackages(options.workspaceRoot, options);
|
|
2083
|
-
if (!discovered.ok) exitWithError(
|
|
2206
|
+
if (!discovered.ok) exitWithError("Failed to discover packages.", void 0, discovered.error);
|
|
2084
2207
|
const ensured = ensureHasPackages(discovered.value);
|
|
2085
2208
|
if (!ensured.ok) {
|
|
2086
2209
|
logger.warn(ensured.error.message);
|
|
@@ -2094,7 +2217,7 @@ async function verifyWorkflow(options) {
|
|
|
2094
2217
|
globalCommitMode: options.globalCommitMode === "none" ? false : options.globalCommitMode,
|
|
2095
2218
|
overrides: existingOverrides
|
|
2096
2219
|
});
|
|
2097
|
-
if (!updatesResult.ok) exitWithError(updatesResult.error
|
|
2220
|
+
if (!updatesResult.ok) exitWithError("Failed to calculate expected package updates.", void 0, updatesResult.error);
|
|
2098
2221
|
const expectedUpdates = updatesResult.value.allUpdates;
|
|
2099
2222
|
const expectedVersionMap = new Map(expectedUpdates.map((u) => [u.package.name, u.newVersion]));
|
|
2100
2223
|
const prVersionMap = /* @__PURE__ */ new Map();
|