docs: add code queue PR preflight template
This commit is contained in:
@@ -7,16 +7,16 @@ import { tmpdir } from "node:os";
|
||||
|
||||
type JsonRecord = Record<string, unknown>;
|
||||
|
||||
function assertCondition(condition: unknown, message: string, detail: JsonRecord = {}): void {
|
||||
function assertCondition(condition: unknown, message: string, detail: unknown = {}): void {
|
||||
if (!condition) throw new Error(`${message}: ${JSON.stringify(detail)}`);
|
||||
}
|
||||
|
||||
function runCli(args: string[], env: Record<string, string> = {}): Promise<{ status: number | null; stdout: string; stderr: string; json: JsonRecord | null }> {
|
||||
function runBun(args: string[], env: Record<string, string> = {}): Promise<{ status: number | null; stdout: string; stderr: string; json: JsonRecord | null }> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const child = spawn("bun", ["scripts/cli.ts", ...args], {
|
||||
cwd: process.cwd(),
|
||||
env: { ...process.env, ...env },
|
||||
});
|
||||
const child = spawn("bun", args, {
|
||||
cwd: process.cwd(),
|
||||
env: { ...process.env, ...env },
|
||||
});
|
||||
const stdoutChunks: Buffer[] = [];
|
||||
const stderrChunks: Buffer[] = [];
|
||||
child.stdout.on("data", (chunk) => stdoutChunks.push(Buffer.from(chunk)));
|
||||
@@ -40,6 +40,10 @@ function runCli(args: string[], env: Record<string, string> = {}): Promise<{ sta
|
||||
});
|
||||
}
|
||||
|
||||
function runCli(args: string[], env: Record<string, string> = {}): Promise<{ status: number | null; stdout: string; stderr: string; json: JsonRecord | null }> {
|
||||
return runBun(["scripts/cli.ts", ...args], env);
|
||||
}
|
||||
|
||||
interface MockRequest {
|
||||
method: string;
|
||||
url: string;
|
||||
@@ -79,10 +83,18 @@ async function startMockGitHub(): Promise<{ baseUrl: string; requests: MockReque
|
||||
const server = createServer(async (req, res) => {
|
||||
const body = await collectBody(req);
|
||||
requests.push({ method: req.method ?? "", url: req.url ?? "", body });
|
||||
if (req.method === "GET" && req.url === "/rate_limit") {
|
||||
sendJson(res, 200, { resources: { core: { limit: 5000, remaining: 4999 } } });
|
||||
return;
|
||||
}
|
||||
if (req.method === "GET" && req.url === "/repos/pikasTech/unidesk") {
|
||||
sendJson(res, 200, { id: 1, full_name: "pikasTech/unidesk", private: true, default_branch: "master", permissions: { pull: true, push: true } });
|
||||
return;
|
||||
}
|
||||
if (req.method === "GET" && req.url === "/repos/pikasTech/unidesk/issues?per_page=1&state=all") {
|
||||
sendJson(res, 200, []);
|
||||
return;
|
||||
}
|
||||
if (req.method === "GET" && req.url === "/repos/pikasTech/unidesk/pulls?state=all&per_page=4") {
|
||||
sendJson(res, 200, [pullRequest]);
|
||||
return;
|
||||
@@ -154,6 +166,34 @@ export async function runGhCliPrContract(): Promise<JsonRecord> {
|
||||
assertCondition(pullRequest.number === 42 && pullRequest.url === "https://github.com/pikasTech/unidesk/pull/42", "pr view should expose PR details", viewData);
|
||||
const selected = viewData.json as JsonRecord;
|
||||
assertCondition(selected.body === "PR body" && selected.title === "contract PR", "pr view --json should select fields", viewData);
|
||||
|
||||
const preflight = await runBun([
|
||||
"scripts/code-queue-pr-preflight-example.ts",
|
||||
"--repo",
|
||||
"pikasTech/unidesk",
|
||||
"--base",
|
||||
"master",
|
||||
"--head",
|
||||
"feature/pr-contract",
|
||||
"--comment-pr",
|
||||
"42",
|
||||
], env);
|
||||
assertCondition(preflight.status === 0, "PR preflight example should succeed against mock GitHub", preflight.json ?? { stdout: preflight.stdout });
|
||||
assertCondition(preflight.json?.ok === true, "PR preflight example should report ok=true", preflight.json ?? {});
|
||||
assertCondition(!preflight.stdout.includes("contract-token"), "PR preflight example must not print token values", { stdout: preflight.stdout });
|
||||
assertCondition(typeof preflight.json?.checks === "object" && preflight.json.checks !== null && !Array.isArray(preflight.json.checks), "PR preflight should expose checks", preflight.json ?? {});
|
||||
const preflightChecks = preflight.json?.checks as JsonRecord;
|
||||
const envToken = preflightChecks.envToken as JsonRecord;
|
||||
assertCondition(envToken.present === true && envToken.source === "GH_TOKEN", "PR preflight should require env token source", envToken);
|
||||
const authStatus = preflightChecks.githubAuthStatus as JsonRecord;
|
||||
assertCondition(authStatus.ok === true, "PR preflight should prove GitHub REST egress and repo visibility", authStatus);
|
||||
const preflightCreate = preflightChecks.prCreateDryRun as JsonRecord;
|
||||
const preflightComment = preflightChecks.prCommentDryRun as JsonRecord;
|
||||
assertCondition(preflightCreate.ok === true && preflightCreate.dryRun === true && preflightCreate.planned === true, "PR preflight create must stay dry-run", preflightCreate);
|
||||
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);
|
||||
} finally {
|
||||
await mock.close();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user