An agent meets the mesh's words most often in tool descriptions, and nothing compared them with the glossary: several still said "the host" for the node-engine and the forge's pull request comment was headed "Change plan", a word retired twice over. retired-words is the copy of the words the glossary retires for the tools, and checks/words fails the repository check when any string a module's code can show, or any manifest description, uses one. Those found are reworded here.
146 lines
10 KiB
TypeScript
146 lines
10 KiB
TypeScript
import assert from "node:assert/strict";
|
|
import { test } from "node:test";
|
|
import { createServer } from "node:http";
|
|
|
|
// A pull request's merge check (novox/hq to-be 45 §9): each new head announced once, and the verdict set
|
|
// where the pull request shows it — an error never as a success.
|
|
|
|
test("each open pull request's new head is announced once, and nothing closed or merged", async () => {
|
|
const { headsToAnnounce } = await import("../pulls.ts");
|
|
const pulls = [
|
|
{ number: 1, title: "a", state: "open", merged: false, head_sha: "aaa", html_url: "" },
|
|
{ number: 2, title: "b", state: "open", merged: false, head_sha: "bbb", html_url: "" },
|
|
{ number: 3, title: "c", state: "closed", merged: true, head_sha: "ccc", html_url: "" },
|
|
{ number: 4, title: "d", state: "open", merged: false, html_url: "" },
|
|
];
|
|
const announced = { "novox/mesh-catalog#1": "aaa", "novox/mesh-catalog#2": "old" };
|
|
assert.deepEqual(headsToAnnounce("novox/mesh-catalog", pulls, announced).map((p) => p.number), [2],
|
|
"only a head not announced, of a pull request that is open");
|
|
});
|
|
|
|
test("a verdict is the head commit's status; an error is the forge's error, never a success", async () => {
|
|
const { statusFor, commentFor, CHECK_CONTEXT } = await import("../pulls.ts");
|
|
const base = { owner: "novox", repo: "mesh-catalog", number: 7, commit: "0123456789abcdef", id: "build-1", on: "laptop" };
|
|
assert.equal(statusFor({ ...base, verdict: "pass", summary: "every machine composes" }).state, "success");
|
|
// A warning is a note, never a blocking state: the forge combines `warning` as a failure (issue 293).
|
|
const wide = statusFor({ ...base, verdict: "warning", summary: "a merge rebuilds 14 module(s)" });
|
|
assert.equal(wide.state, "success");
|
|
assert.match(wide.description, /^pass, with a note: a merge rebuilds 14 module/);
|
|
assert.equal(statusFor({ ...base, verdict: "fail", summary: "x" }).state, "failure");
|
|
assert.equal(statusFor({ ...base, verdict: "error", summary: "the check could not run" }).state, "error");
|
|
assert.equal(statusFor({ ...base, verdict: "", summary: "" }).state, "error", "no verdict is no pass");
|
|
const long = statusFor({ ...base, verdict: "fail", summary: "y".repeat(500) });
|
|
assert.ok(long.description.length <= 140 && long.context === CHECK_CONTEXT);
|
|
assert.equal(commentFor({ ...base, verdict: "pass", summary: "fine" }), null, "a pass leaves no comment");
|
|
const said = commentFor({ ...base, verdict: "fail", summary: "lemurs refused", report: "fails:\n - ```x```" }) ?? "";
|
|
assert.match(said, /mesh\/merge-gate`: \*\*FAIL\*\*/);
|
|
assert.match(said, /01234567/);
|
|
assert.match(said, /builds --log build-1/);
|
|
assert.ok(!said.slice(said.indexOf("```") + 3, said.lastIndexOf("```")).includes("```"), "the report cannot close its own block");
|
|
});
|
|
|
|
test("each layer is its own status: the gate with the modules it judged, the repository's own check beside it", async () => {
|
|
const { statusesFor, commentFor, CHECK_CONTEXT, REPO_CHECK_CONTEXT } = await import("../pulls.ts");
|
|
const base = { owner: "novox", repo: "mesh-catalog", number: 7, commit: "0123456789abcdef", id: "build-1" };
|
|
const both = statusesFor({ ...base, verdict: "pass", summary: "every machine composes",
|
|
gate: { verdict: "pass", summary: "every machine composes", modules: ["gitea", "keycloak"], dependents: ["node-tools"] },
|
|
"repo-check": { verdict: "fail", summary: "its merge-check.sh failed: FAIL x" } });
|
|
assert.deepEqual(both.map((s) => [s.context, s.state]), [[CHECK_CONTEXT, "success"], [REPO_CHECK_CONTEXT, "failure"]]);
|
|
assert.match(both[0].description, /gitea, keycloak \+1 dependent/);
|
|
assert.match(commentFor({ ...base, verdict: "pass", summary: "", gate: { verdict: "pass", summary: "" },
|
|
"repo-check": { verdict: "fail", summary: "its merge-check.sh failed" } }) ?? "", /mesh\/repo-check`: \*\*FAIL/);
|
|
|
|
// Nothing of the graph touched, no script: a pass and a warning, and no comment on every push.
|
|
const quiet = { ...base, verdict: "pass", summary: "the change touches no module of the mesh's graph",
|
|
gate: { verdict: "pass", summary: "the change touches no module of the mesh's graph" },
|
|
"repo-check": { verdict: "warning", summary: "the repository declares no merge-check.sh" } };
|
|
assert.deepEqual(statusesFor(quiet, { defined: false, required: false }).map((s) => [s.state, s.description]),
|
|
[["success", "pass: the change touches no module of the mesh's graph"], ["success", "no repository check defined"]]);
|
|
assert.equal(commentFor(quiet, { defined: false, required: false }), null);
|
|
|
|
// A repository outside the mesh, touching nothing: the gate alone, a pass.
|
|
assert.equal(statusesFor({ ...base, verdict: "pass", summary: "x", gate: { verdict: "pass", summary: "x" } }).length, 1);
|
|
|
|
// A controller from before the layers: its verdict is the gate's.
|
|
assert.deepEqual(statusesFor({ ...base, verdict: "warning", summary: "wide" }).map((s) => [s.context, s.state]),
|
|
[[CHECK_CONTEXT, "success"]]);
|
|
});
|
|
|
|
// **A required status is success or it blocks** (novox/hq issue 293): branch protection requires
|
|
// mesh/merge-gate (and mesh/repo-check on the core repositories) with no administrator override, and the
|
|
// forge combines `warning` as a failure. No verdict ever sets `warning` on either; a note is a success that
|
|
// says it; only what a person must decide is a failure, with why.
|
|
test("no verdict sets warning on a required check; only a person's decision fails", async () => {
|
|
const { statusesFor, commentFor, UNDEFINED_REQUIRED, REPO_CHECK_CONTEXT } = await import("../pulls.ts");
|
|
const base = { owner: "novox", repo: "photos", number: 3, commit: "0123456789abcdef", id: "build-2" };
|
|
const noScript = { verdict: "warning", summary: "the repository declares no merge-check.sh" };
|
|
const quiet = { ...base, verdict: "pass", summary: "x", gate: { verdict: "pass", summary: "x" }, "repo-check": noScript };
|
|
for (const verdict of ["pass", "warning", "fail", "error", ""]) {
|
|
for (const facts of [{}, { defined: true }, { defined: false }, { defined: false, required: true }, { defined: false, required: false }]) {
|
|
const c = { ...base, verdict, summary: "s", gate: { verdict, summary: "s" }, "repo-check": { verdict, summary: "s" } };
|
|
for (const s of statusesFor(c, facts)) assert.notEqual(s.state, "warning", `${verdict} ${JSON.stringify(facts)} → ${s.context}`);
|
|
}
|
|
}
|
|
// A repository without a merge-check.sh where repo-check is not required: success, said.
|
|
assert.deepEqual(statusesFor(quiet, { defined: false, required: false })[1],
|
|
{ state: "success", context: REPO_CHECK_CONTEXT, description: "no repository check defined" });
|
|
// Where it is required — or the protection could not be read — a person decides: a failure, with why.
|
|
for (const facts of [{ defined: false, required: true }, { defined: false }]) {
|
|
const s = statusesFor(quiet, facts)[1];
|
|
assert.equal(s.state, "failure");
|
|
assert.ok(s.description.length <= 140 && UNDEFINED_REQUIRED.startsWith(s.description.replace(/…$/, "")));
|
|
assert.match(s.description, /^fail: mesh\/repo-check is required/);
|
|
assert.match(commentFor(quiet, facts) ?? "", /mesh\/repo-check`: \*\*FAIL\*\* — mesh\/repo-check is required/);
|
|
}
|
|
// A script that defines its check and said a warning itself: a note, a success.
|
|
const noted = statusesFor({ ...quiet, "repo-check": { verdict: "warning", summary: "2 tests skipped" } }, { defined: true })[1];
|
|
assert.deepEqual([noted.state, noted.description], ["success", "pass, with a note: 2 tests skipped"]);
|
|
// The gate's notes — a wide rebuild, a problem already so on the base — are successes that say so.
|
|
const already = statusesFor({ ...base, verdict: "warning", summary: "s",
|
|
gate: { verdict: "warning", summary: "the module check's problems were all so on main already" } })[0];
|
|
assert.deepEqual([already.state, already.description],
|
|
["success", "pass, with a note: the module check's problems were all so on main already"]);
|
|
assert.match(commentFor({ ...base, verdict: "warning", summary: "wide", gate: { verdict: "warning", summary: "wide" } }) ?? "",
|
|
/PASS, WITH A NOTE/);
|
|
});
|
|
|
|
test("a commit status is set on the commit, under the merge check's context", async () => {
|
|
const { GiteaClient } = await import("../client.ts");
|
|
let seen: { path: string; body: any } | null = null;
|
|
const server = createServer((req, res) => {
|
|
let raw = "";
|
|
req.on("data", (c) => (raw += c));
|
|
req.on("end", () => {
|
|
seen = { path: `${req.method} ${req.url}`, body: JSON.parse(raw) };
|
|
res.statusCode = 201;
|
|
res.end("{}");
|
|
});
|
|
});
|
|
await new Promise<void>((r) => server.listen(0, r));
|
|
const port = (server.address() as any).port;
|
|
const client = new GiteaClient(`http://127.0.0.1:${port}`, "t");
|
|
await client.setCommitStatus("novox", "mesh-catalog", "abc123", { state: "failure", context: "mesh/merge-gate", description: "x" });
|
|
server.close();
|
|
assert.equal(seen!.path, "POST /api/v1/repos/novox/mesh-catalog/statuses/abc123");
|
|
assert.equal(seen!.body.state, "failure");
|
|
assert.equal(seen!.body.context, "mesh/merge-gate");
|
|
});
|
|
|
|
test("a change plan is the gate's result: said on the status and, when it builds something, as a comment", async () => {
|
|
const { statusFor, commentFor } = await import("../pulls.ts");
|
|
const plan = {
|
|
repository: "novox/mesh-catalog", base: "main", head: "0123456789abcdef", moved: ["gitea"],
|
|
tiers: [["gitea"]], machines: [{ machine: "anchor", receives: ["gitea"] }], steps: [],
|
|
summary: "builds gitea → anchor; no bus step",
|
|
};
|
|
const c = { owner: "novox", repo: "mesh-catalog", number: 7, commit: "0123456789abcdef", id: "b", verdict: "pass",
|
|
summary: "every machine composes", gate: { verdict: "pass", summary: "every machine composes", modules: ["gitea"] }, plan };
|
|
assert.equal(statusFor(c).description, "pass: builds gitea → anchor; no bus step; every machine composes");
|
|
const said = commentFor(c) ?? "";
|
|
assert.match(said, /Delivery plan\*\* — builds gitea → anchor/);
|
|
assert.match(said, /- anchor: receives gitea/);
|
|
// A plan that builds nothing, passing: the statuses say it, no comment.
|
|
const nothing = { ...c, plan: { ...plan, moved: [], tiers: [], machines: [], summary: "builds nothing" } };
|
|
assert.equal(commentFor(nothing), null);
|
|
});
|