Files
awesome-copilot/.github/extensions/open-pr-board/lib/decisions.mjs
T

55 lines
2.2 KiB
JavaScript

import * as gh from "./github.mjs";
const DECISION_KINDS = ["approve", "request-changes", "comment", "close"];
const MAX_COMMENT_LENGTH = 60000;
const decisionsInFlight = new Set();
export async function applyDecisionOnGitHub({ store, number, kind, comment, refresh, github = gh }) {
if (!DECISION_KINDS.includes(kind)) throw new Error(`Unknown decision "${kind}".`);
const key = `${store.repo}#${number}`;
if (decisionsInFlight.has(key)) throw new Error(`#${number} already has a GitHub action in progress.`);
decisionsInFlight.add(key);
try {
const item = store.getItem(number);
if (!item) throw new Error(`Pull request #${number} is not on the board. Refresh first.`);
if (item.decision) throw new Error(`#${number} was already actioned (${item.decision.kind}).`);
const body = String(comment ?? "").trim().slice(0, MAX_COMMENT_LENGTH);
if ((kind === "request-changes" || kind === "comment") && !body) {
throw new Error(`A ${kind} decision needs a non-empty comment.`);
}
let result;
if (kind === "approve") {
result = await github.approveAndEnableAutoMerge(store.repo, number, { body, headRefOid: item.headRefOid });
} else if (kind === "close") {
result = await github.closePullRequest(store.repo, number, { body });
} else {
result = await github.submitPullRequestReview(store.repo, number, { kind, body });
}
const warnings = result.warning ? [result.warning] : [];
try {
await store.recordDecision(number, { kind, comment: body, status: result.status });
} catch (error) {
warnings.push(`GitHub was updated, but the board could not record the action: ${error.message}`);
}
try {
await refresh(store);
} catch (error) {
warnings.push(`GitHub was updated, but the board could not refresh: ${error.message}`);
}
return {
number,
kind,
comment: body,
posted: true,
status: result.status,
warning: warnings.length ? warnings.join(" ") : null,
url: item.url,
};
} finally {
decisionsInFlight.delete(key);
}
}