diff --git a/scripts/src/gh.ts b/scripts/src/gh.ts index c7b143c9..20f99dde 100644 --- a/scripts/src/gh.ts +++ b/scripts/src/gh.ts @@ -6732,12 +6732,12 @@ async function issueBoardAudit(repo: string, token: string, options: GitHubOptio } async function issueCreate(repo: string, token: string, options: GitHubOptions): Promise { - if (options.title === undefined) throw new Error("issue create requires --title "); + if (options.title === undefined) return withIssueCreateRendered(validationError("issue create", repo, "issue create requires --title <title>")); if (options.body !== undefined) { - return validationError("issue create", repo, "issue create does not support --body; use --body-stdin with a quoted heredoc for Markdown", { + return withIssueCreateRendered(validationError("issue create", repo, "issue create does not support --body; use --body-stdin with a quoted heredoc for Markdown", { title: options.title, bodySource: "inline", - }); + })); } const { body, bodySource } = readMarkdownBody({ ...options, @@ -6760,16 +6760,16 @@ async function issueCreate(repo: string, token: string, options: GitHubOptions): const payload: Record<string, unknown> = { title: options.title, body }; if (labels.length > 0) payload.labels = labels; const issue = await githubRequest<GitHubIssue>(token, "POST", `/repos/${owner}/${name}/issues`, payload); - if (isGitHubError(issue)) return commandError("issue create", repo, issue, { title: options.title, labels }); + if (isGitHubError(issue)) return withIssueCreateRendered(commandError("issue create", repo, issue, { title: options.title, labels })); const appliedLabels = issueLabelNames(issue); const missingLabels = labels.filter((label) => !appliedLabels.includes(label)); if (missingLabels.length > 0) { - return validationError("issue create", repo, "GitHub created the issue but did not return all requested labels; refusing to report silent label success", { + return withIssueCreateRendered(validationError("issue create", repo, "GitHub created the issue but did not return all requested labels; refusing to report silent label success", { issue: issueSummary(issue), requestedLabels: labels, appliedLabels, missingLabels, - }); + })); } return withIssueCreateRendered({ ok: true, command: "issue create", repo, issue: issueSummary(issue), labels, bodySource, rest: true }); } @@ -6786,14 +6786,19 @@ function renderIssueCreateTable(result: GitHubCommandResult): string { const issue = isRecord(result.issue) ? result.issue : {}; const number = ghText(issue.number ?? result.number); const title = ghText(issue.title ?? result.title); - const status = result.dryRun === true ? "dry-run" : "created"; + const ok = result.ok !== false; + const details = isRecord(result.details) ? result.details : {}; + const status = ok ? (result.dryRun === true ? "dry-run" : "created") : "failed"; + const reason = ok ? "-" : ghText(result.degradedReason ?? details.degradedReason ?? "validation-failed"); + const message = ghText(result.message ?? details.message); const labels = Array.isArray(result.labels) ? result.labels.map(String).join(",") : ghText(result.labels); const lines = [ `gh issue create (${status})`, "", - ghTable(["ISSUE", "STATUS", "LABELS", "TITLE"], [[ + ghTable(["ISSUE", "STATUS", "REASON", "LABELS", "TITLE"], [[ number === "-" ? "-" : `#${number}`, status, + ghShort(reason, 32), ghShort(labels, 40), ghShort(title, 96), ]]), @@ -6803,7 +6808,11 @@ function renderIssueCreateTable(result: GitHubCommandResult): string { "", "Next:", ]; - if (status === "created" && number !== "-") { + if (!ok) { + const nextIndex = lines.indexOf("Next:"); + if (nextIndex >= 0) lines.splice(nextIndex, 0, ` message=${ghShort(message, 160)}`, ""); + lines.push(" use --body-stdin with a quoted heredoc for Markdown issue bodies"); + } else if (status === "created" && number !== "-") { lines.push(` bun scripts/cli.ts gh issue view ${number} --repo ${ghText(result.repo)}`); } else { lines.push(" rerun without --dry-run to create the issue");