fix(cli): expose PR closeout metadata
Host commander merge after read-only audit. PR #72 is CLEAN/MERGEABLE and limited to UniDesk CLI PR closeout metadata: mergeability/status fields for gh pr read/view plus contract test/docs. Runner validation reported gh-cli-pr-contract-test and live metadata query; no HWLAB business code touched.
This commit is contained in:
@@ -103,6 +103,30 @@ async function startMockGitHub(): Promise<{ baseUrl: string; requests: MockReque
|
||||
sendJson(res, 200, pullRequest);
|
||||
return;
|
||||
}
|
||||
if (req.method === "POST" && req.url === "/graphql") {
|
||||
sendJson(res, 200, {
|
||||
data: {
|
||||
repository: {
|
||||
pullRequest: {
|
||||
mergeable: "MERGEABLE",
|
||||
mergeStateStatus: "CLEAN",
|
||||
headRefName: "feature/pr-contract",
|
||||
baseRefName: "master",
|
||||
statusCheckRollup: {
|
||||
state: "SUCCESS",
|
||||
contexts: {
|
||||
nodes: [
|
||||
{ __typename: "CheckRun", name: "contract", status: "COMPLETED", conclusion: "SUCCESS" },
|
||||
{ __typename: "StatusContext", context: "legacy-ci", state: "SUCCESS", targetUrl: "https://ci.example.test/42", description: "ok" },
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (req.method === "PATCH" && req.url === "/repos/pikasTech/unidesk/pulls/42") {
|
||||
const parsed = JSON.parse(body) as JsonRecord;
|
||||
sendJson(res, 200, { ...pullRequest, title: String(parsed.title ?? pullRequest.title), body: String(parsed.body ?? pullRequest.body), state: String(parsed.state ?? pullRequest.state), updated_at: "2026-05-20T06:00:00Z" });
|
||||
@@ -180,6 +204,17 @@ export async function runGhCliPrContract(): Promise<JsonRecord> {
|
||||
const viewSelected = viewData.json as JsonRecord;
|
||||
assertCondition(viewSelected.body === "PR body" && viewSelected.title === "contract PR", "pr view alias should preserve selected fields", viewData);
|
||||
|
||||
const closeout = await runCli(["gh", "pr", "view", "42", "--repo", "pikasTech/unidesk", "--json", "mergeable,mergeStateStatus,statusCheckRollup,headRefName,baseRefName"], env);
|
||||
assertCondition(closeout.status === 0, "pr view closeout metadata fields should not be rejected", closeout.json ?? { stdout: closeout.stdout });
|
||||
const closeoutData = dataOf(closeout.json ?? {});
|
||||
const closeoutJson = closeoutData.json as JsonRecord;
|
||||
assertCondition(closeoutJson.mergeable === "MERGEABLE", "pr view should expose mergeable", closeoutData);
|
||||
assertCondition(closeoutJson.mergeStateStatus === "CLEAN", "pr view should expose mergeStateStatus", closeoutData);
|
||||
assertCondition(closeoutJson.headRefName === "feature/pr-contract" && closeoutJson.baseRefName === "master", "pr view should expose PR branch names", closeoutData);
|
||||
const rollup = closeoutJson.statusCheckRollup as JsonRecord;
|
||||
assertCondition(rollup.state === "SUCCESS", "pr view should expose statusCheckRollup", closeoutData);
|
||||
assertCondition(mock.requests.some((request) => request.method === "POST" && request.url === "/graphql"), "closeout metadata should use GitHub GraphQL when requested", mock.requests);
|
||||
|
||||
const preflight = await runBun([
|
||||
"scripts/code-queue-pr-preflight-example.ts",
|
||||
"--repo",
|
||||
@@ -206,7 +241,7 @@ export async function runGhCliPrContract(): Promise<JsonRecord> {
|
||||
assertCondition(preflightComment.ok === true && preflightComment.dryRun === true && preflightComment.planned === true, "PR preflight comment must stay dry-run", preflightComment);
|
||||
assertCondition(mock.requests.some((request) => request.method === "GET" && request.url === "/rate_limit"), "PR preflight should probe REST egress", mock.requests);
|
||||
assertCondition(mock.requests.some((request) => request.method === "GET" && request.url === "/repos/pikasTech/unidesk"), "PR preflight should probe repo visibility", mock.requests);
|
||||
assertCondition(mock.requests.every((request) => request.method === "GET"), "initial mock phase should remain read-only", mock.requests);
|
||||
assertCondition(mock.requests.every((request) => request.method === "GET" || request.method === "POST" && request.url === "/graphql"), "initial mock phase should remain read-only except GraphQL metadata reads", mock.requests);
|
||||
} finally {
|
||||
await mock.close();
|
||||
}
|
||||
@@ -309,6 +344,7 @@ export async function runGhCliPrContract(): Promise<JsonRecord> {
|
||||
checks: [
|
||||
"gh help lists pr create/comment",
|
||||
"pr list/read/view work through REST with token and no gh binary dependency",
|
||||
"pr view closeout metadata fields are accepted and hydrated through GraphQL",
|
||||
"pr create dry-run exposes planned operation",
|
||||
"pr comment dry-run preserves markdown text",
|
||||
"pr update replace/append and close/reopen are available",
|
||||
|
||||
Reference in New Issue
Block a user