import { expect, mock, test } from "bun:test";
mock.module("cloudflare:workers", () => ({
env: {},
waitUntil: () => undefined,
WorkflowEntrypoint: class {},
DurableObject: class {},
WorkerEntrypoint: class {},
}));
const { buildArchive } = await import("./archive");
const { parseActionManifest } = await import("./manifest");
const { compileWorkflow } = await import("../compile");
const { buildJobScript } = await import("../script");
const { parseWorkflow } = await import("../spec");
const { buildPack, makeBlob, makeCommit, makeTree } = await import("../../git/objects");
const { parsePack } = await import("../../git/pack");
async function runJob(tamper: boolean) {
const yml = "inputs:\n version:\n default: stable\nruns:\n using: node20\n main: index.js\n post: post.js\n";
const main = `const fs=require('fs');console.log('main version='+process.env.INPUT_VERSION+' action='+process.env.GITHUB_ACTION_REPOSITORY);fs.appendFileSync(process.env.GITHUB_OUTPUT,'executable=/usr/bin/vim\\n');fs.appendFileSync(process.env.GITHUB_STATE,'saved=yes\\n');console.log('::add-mask::topsecret');`;
const post = `console.log('post state='+process.env.STATE_saved)`;
const blobs = [await makeBlob(yml), await makeBlob(main), await makeBlob(post)];
const root = await makeTree([
{ mode: "100644", name: "action.yml", sha: blobs[0].sha },
{ mode: "100644", name: "index.js", sha: blobs[1].sha },
{ mode: "100644", name: "post.js", sha: blobs[2].sha },
]);
const sig = { name: "a", email: "a@x", timestamp: 1, timezone: "+0000" };
const commit = await makeCommit({ tree: root.sha, parents: [], author: sig, committer: sig, message: "x" });
const parsed = await parsePack(await buildPack([...blobs, root, commit]), {
maxObjects: 100,
maxObjectBytes: 1 << 20,
maxTotalBytes: 1 << 22,
});
const { tgz } = await buildArchive(parsed, commit.sha);
const sum = tamper ? "0".repeat(64) : new Bun.CryptoHasher("sha256").update(tgz).digest("hex");
const key = `o/act@${commit.sha}`;
const server = Bun.serve({
port: 0,
fetch: (req) =>
new URL(req.url).searchParams.get("key") === key ? new Response(tgz) : new Response("no", { status: 404 }),