131 lines
5.9 KiB
TypeScript
131 lines
5.9 KiB
TypeScript
import { codexPrPreflightQueryForTest } from "./src/code-queue";
|
|
|
|
type JsonRecord = Record<string, unknown>;
|
|
|
|
function assertCondition(condition: unknown, message: string, detail: unknown = {}): void {
|
|
if (!condition) throw new Error(`${message}: ${JSON.stringify(detail)}`);
|
|
}
|
|
|
|
function asRecord(value: unknown): JsonRecord {
|
|
assertCondition(typeof value === "object" && value !== null && !Array.isArray(value), "expected JSON object", { value });
|
|
return value as JsonRecord;
|
|
}
|
|
|
|
function fixtureRuntimePreflight(tokenPresent: boolean): JsonRecord {
|
|
return {
|
|
ok: tokenPresent,
|
|
checkedAt: "2026-05-20T00:00:00.000Z",
|
|
cwd: "/workspace/unidesk",
|
|
pid: 123,
|
|
ports: {
|
|
codex: { ok: true, commandPath: "/usr/local/bin/codex", version: "codex 0.128.0", errors: [] },
|
|
opencode: { ok: true, commandPath: "/usr/local/bin/opencode", version: "opencode 1.14.48", errors: [] },
|
|
},
|
|
pullRequestDelivery: {
|
|
ok: tokenPresent,
|
|
checkedAt: "2026-05-20T00:00:00.000Z",
|
|
tools: {
|
|
git: { ok: true, path: "/usr/bin/git", version: "git version 2.43.0" },
|
|
gh: { ok: true, path: "/usr/bin/gh", version: "gh version 2.45.0" },
|
|
hub: { ok: false, path: null, version: null },
|
|
jq: { ok: true, path: "/usr/bin/jq", version: "jq-1.7" },
|
|
ssh: { ok: true, path: "/usr/bin/ssh", version: "OpenSSH_9.6" },
|
|
curl: { ok: true, path: "/usr/bin/curl", version: "curl 8.5.0" },
|
|
},
|
|
credentials: {
|
|
ghTokenPresent: tokenPresent,
|
|
githubTokenPresent: false,
|
|
ghHostPresent: false,
|
|
githubApiUrlPresent: false,
|
|
ghRepoPresent: false,
|
|
sshAuthSockPresent: false,
|
|
gitAskpassPresent: false,
|
|
ghHostsConfigPresent: false,
|
|
gitCredentialsPresent: false,
|
|
},
|
|
githubContext: {
|
|
host: "github.com",
|
|
apiBaseUrl: "https://api.github.com",
|
|
repo: "pikasTech/unidesk",
|
|
issueProbeNumber: 20,
|
|
},
|
|
egress: {
|
|
proxy: { selectedProxyHost: "d601-provider-egress-proxy.unidesk.svc.cluster.local", selectedProxyPort: "18789", selectedProxyHostResolvable: true },
|
|
githubDefault: { command: "preflight", args: ["github-default-network"], ok: true, exitCode: 0, signal: null, error: null, stdout: "skipped", stderr: "" },
|
|
apiDefault: { command: "preflight", args: ["github-api-default-network"], ok: true, exitCode: 0, signal: null, error: null, stdout: "skipped", stderr: "" },
|
|
issueApi: null,
|
|
},
|
|
git: {
|
|
insideWorktree: true,
|
|
branch: "master",
|
|
head: "abc1234",
|
|
originMaster: "abc1234",
|
|
remoteOrigin: "git@github.com:pikasTech/unidesk.git",
|
|
home: "/root",
|
|
homeWritable: true,
|
|
knownHostsPresent: true,
|
|
privateKeyPresent: true,
|
|
},
|
|
limitations: tokenPresent ? [] : ["GH_TOKEN/GITHUB_TOKEN is not present; gh cannot create PRs unless another gh credential store is mounted"],
|
|
risks: [],
|
|
},
|
|
};
|
|
}
|
|
|
|
function fixtureResponse(tokenPresent: boolean): JsonRecord {
|
|
return {
|
|
ok: true,
|
|
status: 200,
|
|
body: {
|
|
ok: true,
|
|
runtimePreflight: fixtureRuntimePreflight(tokenPresent),
|
|
},
|
|
};
|
|
}
|
|
|
|
export function runCodeQueuePrPreflightContract(): JsonRecord {
|
|
let observedPath = "";
|
|
const missing = codexPrPreflightQueryForTest(["--remote", "--issue", "35"], (path) => {
|
|
observedPath = path;
|
|
return fixtureResponse(false);
|
|
});
|
|
assertCondition(
|
|
observedPath === "/api/microservices/code-queue/proxy/api/runtime-preflight?remote=1&issue=35",
|
|
"PR preflight should route to the stable code-queue runtime preflight path",
|
|
{ observedPath },
|
|
);
|
|
assertCondition(asRecord(missing).ok === false, "missing token preflight should set top-level ok=false", missing);
|
|
const missingPreflight = asRecord(asRecord(missing).preflight);
|
|
assertCondition(missingPreflight.ok === false, "missing token preflight should fail", missingPreflight);
|
|
assertCondition(missingPreflight.runnerDisposition === "infra-blocked", "missing token must be infra-blocked", missingPreflight);
|
|
const missingTokenCoverage = asRecord(missingPreflight.tokenCoverage);
|
|
assertCondition(missingTokenCoverage.ok === false, "tokenCoverage should fail when no env token is present", missingTokenCoverage);
|
|
assertCondition(Array.isArray(missingTokenCoverage.missing) && missingTokenCoverage.missing.includes("GH_TOKEN") && missingTokenCoverage.missing.includes("GITHUB_TOKEN"), "tokenCoverage should name both accepted env keys", missingTokenCoverage);
|
|
assertCondition(!JSON.stringify(missing).includes("contract-token"), "preflight output must not leak token values", missing);
|
|
|
|
const ready = codexPrPreflightQueryForTest(["--remote", "--push-dry-run", "--push-dry-run-ref", "refs/heads/probe/test"], (path) => {
|
|
assertCondition(path === "/api/microservices/code-queue/proxy/api/runtime-preflight?remote=1&pushDryRun=1&pushDryRunRef=refs%2Fheads%2Fprobe%2Ftest", "push dry-run options should map to query string", { path });
|
|
return fixtureResponse(true);
|
|
});
|
|
const readyPreflight = asRecord(asRecord(ready).preflight);
|
|
assertCondition(asRecord(ready).ok === true, "token-ready preflight should set top-level ok=true", ready);
|
|
assertCondition(readyPreflight.ok === true, "token-ready preflight should pass fixture", readyPreflight);
|
|
assertCondition(readyPreflight.runnerDisposition === "ready", "ready preflight should report ready disposition", readyPreflight);
|
|
const readyTokenCoverage = asRecord(readyPreflight.tokenCoverage);
|
|
assertCondition(readyTokenCoverage.source === "GH_TOKEN", "ready token source should be redacted to key name only", readyTokenCoverage);
|
|
|
|
return {
|
|
ok: true,
|
|
checks: [
|
|
"stable runtime-preflight proxy path",
|
|
"missing GitHub token is infra-blocked",
|
|
"token key names are reported without values",
|
|
"push dry-run options are forwarded",
|
|
],
|
|
};
|
|
}
|
|
|
|
if (import.meta.main) {
|
|
process.stdout.write(`${JSON.stringify(runCodeQueuePrPreflightContract(), null, 2)}\n`);
|
|
}
|