77 lines
2.0 KiB
JavaScript
77 lines
2.0 KiB
JavaScript
import { execFileSync } from "node:child_process";
|
|
import { appendFileSync } from "node:fs";
|
|
|
|
const repository = process.env.CI_REPOSITORY;
|
|
const branch = process.env.CI_DEFAULT_BRANCH;
|
|
const head = process.env.HEAD_SHA;
|
|
const shaPattern = /^[0-9a-f]{40}$/i;
|
|
|
|
function ancestor(base) {
|
|
try {
|
|
execFileSync("git", ["merge-base", "--is-ancestor", base, head], {
|
|
stdio: "ignore",
|
|
});
|
|
return true;
|
|
} catch {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
function write(base, reason) {
|
|
const output = { base, reason };
|
|
if (process.env.GITHUB_OUTPUT) {
|
|
appendFileSync(
|
|
process.env.GITHUB_OUTPUT,
|
|
`base=${base}\nreason=${reason.replace(/[\r\n]/g, " ")}\n`,
|
|
);
|
|
}
|
|
console.log(JSON.stringify(output));
|
|
}
|
|
|
|
if (!repository || !branch || !head || !shaPattern.test(head)) {
|
|
write("", "Repository, default branch, or checked-out head is invalid");
|
|
} else {
|
|
try {
|
|
const response = execFileSync(
|
|
"gh",
|
|
[
|
|
"api",
|
|
"--method",
|
|
"GET",
|
|
`repos/${repository}/actions/workflows/ci.yml/runs`,
|
|
"-f",
|
|
`branch=${branch}`,
|
|
"-f",
|
|
"event=push",
|
|
"-f",
|
|
"status=success",
|
|
"-F",
|
|
"per_page=100",
|
|
],
|
|
{ encoding: "utf8", timeout: 15_000, maxBuffer: 4 * 1024 * 1024 },
|
|
);
|
|
const runs = JSON.parse(response).workflow_runs;
|
|
if (!Array.isArray(runs))
|
|
throw new Error("GitHub returned no workflow run list");
|
|
const base = runs.find(
|
|
(run) =>
|
|
run?.event === "push" &&
|
|
run?.conclusion === "success" &&
|
|
run?.head_branch === branch &&
|
|
run?.head_repository?.full_name === repository &&
|
|
typeof run?.head_sha === "string" &&
|
|
shaPattern.test(run.head_sha) &&
|
|
run.head_sha.toLowerCase() !== head.toLowerCase() &&
|
|
ancestor(run.head_sha),
|
|
)?.head_sha;
|
|
if (base) write(base, "");
|
|
else
|
|
write(
|
|
"",
|
|
"No trusted successful CI push baseline is an ancestor of this head",
|
|
);
|
|
} catch {
|
|
write("", "Could not read a successful CI push baseline from GitHub");
|
|
}
|
|
}
|