fix: render gh merge result as table
This commit is contained in:
+76
-7
@@ -5131,7 +5131,7 @@ async function prMerge(repo: string, token: string, number: number, options: Git
|
||||
if (isGitHubError(pr)) return commandError("pr merge", repo, pr, { number, phase: "fetch-pr" });
|
||||
const summary = prSummary(pr);
|
||||
if (summary.merged === true) {
|
||||
return {
|
||||
return withPrMergeRendered({
|
||||
ok: true,
|
||||
command: "pr merge",
|
||||
repo,
|
||||
@@ -5141,23 +5141,24 @@ async function prMerge(repo: string, token: string, number: number, options: Git
|
||||
pullRequest: summary,
|
||||
branchDeletion: { attempted: false, skippedReason: "already-merged" },
|
||||
rest: true,
|
||||
};
|
||||
});
|
||||
}
|
||||
const metadata = await prGraphqlMetadata(repo, token, number);
|
||||
if (isGitHubError(metadata)) return commandError("pr merge", repo, metadata, { number, phase: "fetch-pr-closeout-metadata", pullRequest: summary });
|
||||
const statusChecks = statusRollupSummary(repo, number, metadata.statusCheckRollup, false);
|
||||
const mergeability = prCloseoutSummary(summary, prMetadataSummary(metadata), statusChecks);
|
||||
if (mergeability.readyForCommanderMerge !== true) {
|
||||
return validationError("pr merge", repo, "PR is not ready for merge; preflight blockers or pending states remain", {
|
||||
const details = {
|
||||
number,
|
||||
pullRequest: preflightPullRequestSummary(summary),
|
||||
mergeability,
|
||||
statusChecks,
|
||||
closeoutMetadata: prCloseoutMetadata(metadata),
|
||||
});
|
||||
};
|
||||
return withPrMergeRendered(validationError("pr merge", repo, "PR is not ready for merge; preflight blockers or pending states remain", details), details);
|
||||
}
|
||||
if (options.dryRun) {
|
||||
return {
|
||||
return withPrMergeRendered({
|
||||
ok: true,
|
||||
command: "pr merge",
|
||||
repo,
|
||||
@@ -5169,7 +5170,7 @@ async function prMerge(repo: string, token: string, number: number, options: Git
|
||||
pullRequest: preflightPullRequestSummary(summary),
|
||||
mergeability,
|
||||
statusChecks,
|
||||
};
|
||||
});
|
||||
}
|
||||
const merged = await githubRequest<Record<string, unknown>>(token, "PUT", `/repos/${owner}/${name}/pulls/${number}/merge`, {
|
||||
merge_method: options.mergeMethod,
|
||||
@@ -5178,7 +5179,7 @@ async function prMerge(repo: string, token: string, number: number, options: Git
|
||||
const after = await githubRequest<GitHubPullRequest>(token, "GET", `/repos/${owner}/${name}/pulls/${number}`);
|
||||
if (isGitHubError(after)) return commandError("pr merge", repo, after, { number, phase: "fetch-after-merge", mergeResult: merged });
|
||||
const branchDeletion = options.deleteBranch ? await deleteHeadBranchAfterMerge(repo, token, after) : { attempted: false, skippedReason: "delete-branch-not-requested" };
|
||||
return {
|
||||
return withPrMergeRendered({
|
||||
ok: true,
|
||||
command: "pr merge",
|
||||
repo,
|
||||
@@ -5188,9 +5189,77 @@ async function prMerge(repo: string, token: string, number: number, options: Git
|
||||
pullRequest: prSummary(after),
|
||||
branchDeletion,
|
||||
rest: true,
|
||||
});
|
||||
}
|
||||
|
||||
function withPrMergeRendered(result: GitHubCommandResult, fallbackDetails?: Record<string, unknown>): GitHubCommandResult {
|
||||
return {
|
||||
...result,
|
||||
contentType: "text/plain",
|
||||
renderedText: renderPrMergeTable(result, fallbackDetails),
|
||||
};
|
||||
}
|
||||
|
||||
function renderPrMergeTable(result: GitHubCommandResult, fallbackDetails?: Record<string, unknown>): string {
|
||||
const details = fallbackDetails ?? {};
|
||||
const pullRequest = isRecord(result.pullRequest)
|
||||
? result.pullRequest
|
||||
: isRecord(details.pullRequest)
|
||||
? details.pullRequest
|
||||
: {};
|
||||
const mergeability = isRecord(result.mergeability)
|
||||
? result.mergeability
|
||||
: isRecord(details.mergeability)
|
||||
? details.mergeability
|
||||
: {};
|
||||
const statusChecks = isRecord(result.statusChecks)
|
||||
? result.statusChecks
|
||||
: isRecord(details.statusChecks)
|
||||
? details.statusChecks
|
||||
: {};
|
||||
const counts = isRecord(statusChecks.counts) ? statusChecks.counts : {};
|
||||
const branchDeletion = isRecord(result.branchDeletion) ? result.branchDeletion : {};
|
||||
const status = result.ok === true
|
||||
? result.alreadyMerged === true
|
||||
? "already-merged"
|
||||
: result.dryRun === true
|
||||
? "dry-run"
|
||||
: "merged"
|
||||
: ghText(mergeability.conclusion) === "pending"
|
||||
? "pending"
|
||||
: "blocked";
|
||||
const blockers = Array.isArray(mergeability.blockers) ? mergeability.blockers.map(String) : [];
|
||||
const pending = Array.isArray(mergeability.pending) ? mergeability.pending.map(String) : [];
|
||||
const rows = [[
|
||||
`#${ghText(result.number ?? details.number)}`,
|
||||
status,
|
||||
ghText(result.method ?? result.mergeMethod),
|
||||
ghText(mergeability.mergeable),
|
||||
ghText(mergeability.mergeStateStatus),
|
||||
`${ghText(statusChecks.totalContexts)} total ${ghText(counts.success)} ok ${ghText(counts.failure)} fail ${ghText(counts.pending)} pending`,
|
||||
]];
|
||||
const lines = [
|
||||
`gh pr merge (${status})`,
|
||||
"",
|
||||
ghTable(["PR", "STATUS", "METHOD", "MERGEABLE", "MERGE_STATE", "CHECKS"], rows),
|
||||
"",
|
||||
"Summary:",
|
||||
` repo=${ghText(result.repo)} title=${ghShort(ghText(pullRequest.title), 96)}`,
|
||||
` blockers=${blockers.length === 0 ? "-" : blockers.join(",")} pending=${pending.length === 0 ? "-" : pending.join(",")}`,
|
||||
` branchDeletion=${ghText(branchDeletion.ok ?? branchDeletion.skippedReason ?? branchDeletion.attempted)}`,
|
||||
"",
|
||||
"Next:",
|
||||
];
|
||||
if (result.ok === true && result.alreadyMerged !== true && result.dryRun !== true) {
|
||||
lines.push(` bun scripts/cli.ts gh pr view ${ghText(result.number ?? details.number)} --repo ${ghText(result.repo)}`);
|
||||
} else {
|
||||
lines.push(` bun scripts/cli.ts gh pr preflight ${ghText(result.number ?? details.number)} --repo ${ghText(result.repo)}`);
|
||||
}
|
||||
lines.push("", "Disclosure:");
|
||||
lines.push(" default view is a bounded table; use --full or --raw on read/preflight commands for structured metadata.");
|
||||
return lines.join("\n");
|
||||
}
|
||||
|
||||
async function prPreflight(repo: string, number: number, commandName: "preflight" | "pr preflight" | "pr closeout", includeRaw: boolean): Promise<GitHubCommandResult> {
|
||||
const auth = await authStatus(repo);
|
||||
const authCapability = compactAuthCapability(auth);
|
||||
|
||||
Reference in New Issue
Block a user