Once main requires mesh/check, a hand that set it could pass a merge past the checker, the gap issue 293 closed for the two statuses before it. gitea_commit_status now refuses mesh/check in every state, and the new gitea_check_status writes it alone; the bus grants that tool only to a module whose manifest invokes it, the forge bridge (the lead's choice A).
99 lines
7.0 KiB
TypeScript
99 lines
7.0 KiB
TypeScript
import assert from "node:assert/strict";
|
|
import { test } from "node:test";
|
|
|
|
// What the forge's holder does for a delivery (novox/hq ADR 0239): a note appended once, in the forge's own
|
|
// repository as its own user; one view per pull request; only the mesh's statuses.
|
|
|
|
test("a note line is appended once, as the forge's user, in its own repository", async () => {
|
|
const { appendNote, noteArgs } = await import("../delivery.ts");
|
|
const notes: Record<string, string[]> = {};
|
|
const calls: string[][] = [];
|
|
const runner = async (file: string, args: string[]) => {
|
|
calls.push([file, ...args]);
|
|
const commit = args[args.length - 1];
|
|
if (args.includes("show")) {
|
|
const lines = notes[commit];
|
|
return lines ? { stdout: lines.join("\n") + "\n", code: 0 } : { stdout: "", code: 1 };
|
|
}
|
|
const line = args[args.indexOf("-m") + 1];
|
|
(notes[commit] ??= []).push(line);
|
|
return { stdout: "", code: 0 };
|
|
};
|
|
const sha = "0123456789abcdef0123456789abcdef01234567";
|
|
assert.deepEqual(await appendNote(runner, "gitea", "Novox", "Mesh-Catalog", sha, "mesh-plan", "a -> b\n(merged)"),
|
|
{ added: true, lines: 1 });
|
|
assert.deepEqual(await appendNote(runner, "gitea", "Novox", "Mesh-Catalog", sha, "mesh-plan", "a -> b (merged)"),
|
|
{ added: false, lines: 1 }, "the same line twice adds nothing");
|
|
assert.deepEqual(await appendNote(runner, "gitea", "Novox", "Mesh-Catalog", sha, "mesh-plan", "b -> c"),
|
|
{ added: true, lines: 2 });
|
|
const append = calls.find((c) => c.includes("append"))!;
|
|
assert.deepEqual(append.slice(0, 7), ["docker", "exec", "-u", "git", "gitea", "git", "--git-dir"]);
|
|
assert.equal(append[7], "/data/git/repositories/novox/mesh-catalog.git");
|
|
assert.ok(append.includes("--ref=mesh-plan"));
|
|
assert.throws(() => noteArgs("gitea", "novox", "x; rm -rf /", sha, "mesh-plan"), /not a repository/);
|
|
assert.throws(() => noteArgs("gitea", "novox", "x", "HEAD", "mesh-plan"), /not a commit/);
|
|
assert.throws(() => noteArgs("gitea", "novox", "x", sha, "../commits"), /not a notes ref/);
|
|
});
|
|
|
|
test("a note that cannot be written is said, never read as written", async () => {
|
|
const { appendNote } = await import("../delivery.ts");
|
|
const runner = async (_file: string, args: string[]) => ({ stdout: "", code: args.includes("append") ? 128 : 1 });
|
|
await assert.rejects(appendNote(runner, "gitea", "novox", "x", "abcdef1234567", "mesh-plan", "l"), /could not be appended/);
|
|
});
|
|
|
|
test("one view per pull request, found by its marker; only the mesh's statuses", async () => {
|
|
const { viewBody, viewComment, deliveryStatus, VIEW_MARKER } = await import("../delivery.ts");
|
|
assert.ok(viewBody("**Delivery**").startsWith(VIEW_MARKER));
|
|
assert.equal(viewBody(`${VIEW_MARKER}\nx`), `${VIEW_MARKER}\nx`, "a marked body is kept as it is");
|
|
const comments = [{ id: 1, body: "a review" }, { id: 2, body: `${VIEW_MARKER}\nold` }, { id: 3, body: `${VIEW_MARKER}\nlater` }];
|
|
assert.equal(viewComment(comments)?.id, 2);
|
|
assert.equal(viewComment([{ id: 1, body: "x" }]), undefined);
|
|
const s = deliveryStatus("mesh/delivery", "pending", "y".repeat(300), "https://forge.invalid/novox/x/pulls/1");
|
|
assert.ok(s.description.length <= 140 && s.target_url);
|
|
assert.throws(() => deliveryStatus("ci/other", "success", "x"), /mesh's own/);
|
|
assert.throws(() => deliveryStatus("mesh/delivery", "green", "x"), /not a status/);
|
|
// The merge check's statuses are its verdict's alone: required by a branch, they are never set by hand.
|
|
assert.throws(() => deliveryStatus("mesh/merge-gate", "success", "x"), /merge check's status/);
|
|
assert.throws(() => deliveryStatus("mesh/repo-check", "warning", "x"), /merge check's status/);
|
|
assert.throws(() => deliveryStatus("mesh/merge-gate", "failure", "x"), /merge check's status/);
|
|
// Pending is no verdict: a recheck says it so the old verdict does not let the head merge meanwhile.
|
|
assert.equal(deliveryStatus("mesh/merge-gate", "pending", "checking again: main moved on").state, "pending");
|
|
assert.equal(deliveryStatus("mesh/repo-check", "pending", "checking again: main moved on").context, "mesh/repo-check");
|
|
assert.equal(deliveryStatus("mesh/delivery", "success", "x", "javascript:alert(1)").target_url, undefined);
|
|
});
|
|
|
|
// Issue 1301-S4 (ADR 0447 §1; the lead's choice A): main requires mesh/check, so no hand may set it. The status tool
|
|
// every caller may use refuses it in every state; it is written only by gitea_check_status, which the forge bridge
|
|
// alone lists in its manifest's `invokes`, so only its account may call it.
|
|
test("mesh/check is refused by the status tool and written by the check's own tool alone", async () => {
|
|
const { commitStatusTool, checkStatusTool, deliveryStatus, CHECK_STATUS } = await import("../delivery.ts");
|
|
assert.equal(CHECK_STATUS, "mesh/check");
|
|
const sha = "0123456789abcdef0123456789abcdef01234567";
|
|
const sent: string[] = [];
|
|
const setCommitStatus = async (o: string, r: string, s: string, st: any) =>
|
|
void sent.push(`${o}/${r}@${s.slice(0, 8)} ${st.context} ${st.state} ${st.description}${st.target_url ? " " + st.target_url : ""}`);
|
|
const gates = { rechecked: async () => { throw new Error("not the gate writer's"); } };
|
|
for (const state of ["pending", "success", "failure", "error", "warning"]) {
|
|
assert.throws(() => deliveryStatus("mesh/check", state, "x"), /mesh\/check is the checker's status/);
|
|
await assert.rejects(commitStatusTool({ setCommitStatus, gates } as any).run({ owner: "novox", repo: "mesh-sdk", sha,
|
|
context: "mesh/check", state, description: "by hand" }), /gitea_check_status/);
|
|
}
|
|
assert.deepEqual(sent, [], "nothing was sent for a hand-set mesh/check");
|
|
|
|
const tool = checkStatusTool({ setCommitStatus });
|
|
assert.equal(tool.name, "gitea_check_status");
|
|
for (const k of ["owner", "repo", "sha", "state", "description", "target_url", "context"]) assert.ok(k in tool.input, k);
|
|
// The bridge's arguments as it sends them for gitea_commit_status: the context may be given, and is mesh/check.
|
|
await tool.run({ owner: "novox", repo: "mesh-sdk", sha, context: "mesh/check", state: "success", description: "pass",
|
|
target_url: "https://forge.invalid/novox/mesh-sdk/pulls/1" });
|
|
await tool.run({ owner: "novox", repo: "mesh-sdk", sha, state: "pending", description: "y".repeat(300) });
|
|
assert.equal(sent[0], "novox/mesh-sdk@01234567 mesh/check success pass https://forge.invalid/novox/mesh-sdk/pulls/1");
|
|
assert.ok(sent[1].startsWith("novox/mesh-sdk@01234567 mesh/check pending yyyy"), sent[1]);
|
|
assert.ok(sent[1].length < 200, "the description is cut as every status's is");
|
|
await assert.rejects(tool.run({ owner: "novox", repo: "mesh-sdk", sha, context: "mesh/delivery", state: "success" }), /mesh\/check alone/);
|
|
await assert.rejects(tool.run({ owner: "novox", repo: "mesh-sdk", sha: sha.slice(0, 12), state: "success" }), /whole sha/);
|
|
await assert.rejects(tool.run({ owner: "novox", repo: "mesh-sdk", sha, state: "green" }), /not a status/);
|
|
await assert.rejects(tool.run({ owner: "../x", repo: "mesh-sdk", sha, state: "success" }));
|
|
assert.equal(sent.length, 2, "nothing more was sent");
|
|
});
|