diff --git a/modules/gitea/index.ts b/modules/gitea/index.ts index b0cfac0c..f5aeb79 100644 --- a/modules/gitea/index.ts +++ b/modules/gitea/index.ts @@ -222,6 +222,7 @@ async function pollPulls(client: GiteaClient): Promise { html_url: pull.html_url, paths: files.paths, paths_truncated: files.truncated, + removed: files.removed, ...(moduleDirs ? { module_dirs: moduleDirs, module_dirs_said: true } : {}), ...(mergeCheck !== null ? { merge_check: mergeCheck, merge_check_said: true } : {}), }); diff --git a/modules/gitea/pulls.ts b/modules/gitea/pulls.ts index 8eac731..9990d84 100644 --- a/modules/gitea/pulls.ts +++ b/modules/gitea/pulls.ts @@ -21,7 +21,10 @@ export const REPO_CHECK_CONTEXT = "mesh/repo-check"; export interface Layer { verdict: string; summary: string; + /** The modules a merge of the change would move, as the controller's planner reckons it… */ modules?: string[]; + /** …and those it would build after them because they stand on them. */ + dependents?: string[]; } /** What the controller says as `checked` (mesh-controller internal/link, Checked). */ @@ -55,10 +58,10 @@ function stateOf(verdict: string): CommitStatus["state"] { return verdict === "pass" ? "success" : verdict === "warning" ? "warning" : verdict === "fail" ? "failure" : "error"; } -function described(verdict: string, summary: string, modules?: string[]): string { +function described(verdict: string, summary: string, modules?: string[], dependents?: string[]): string { // The forge keeps a short description; the rest is the comment's. let d = `${verdict || "error"}: ${summary}`; - if (modules?.length) d += ` [${modules.join(", ")}]`; + if (modules?.length) d += ` [${modules.join(", ")}${dependents?.length ? ` +${dependents.length} dependent(s)` : ""}]`; d = d.replace(/\s+/g, " ").trim(); return d.length > 140 ? d.slice(0, 139) + "…" : d; } @@ -66,7 +69,10 @@ function described(verdict: string, summary: string, modules?: string[]): string /** The forge's status for the gate. */ export function statusFor(c: Checked): CommitStatus { const gate = c.gate ?? { verdict: c.verdict, summary: c.summary }; - return { state: stateOf(gate.verdict), context: CHECK_CONTEXT, description: described(gate.verdict, gate.summary, gate.modules) }; + return { + state: stateOf(gate.verdict), context: CHECK_CONTEXT, + description: described(gate.verdict, gate.summary, gate.modules, gate.dependents), + }; } /** Every status a verdict sets: the gate's, and the repository's own check's when it was said. */ @@ -87,7 +93,8 @@ export function commentFor(c: Checked): string | null { if (gate.verdict === "pass" && !repoWrong) return null; const lines = [`**Merge check** at \`${c.commit.slice(0, 8)}\``, ""]; lines.push(`- \`${CHECK_CONTEXT}\`: **${(gate.verdict || "error").toUpperCase()}** — ${gate.summary}` + - (gate.modules?.length ? ` (modules: ${gate.modules.join(", ")})` : "")); + (gate.modules?.length ? ` (modules: ${gate.modules.join(", ")}` + + (gate.dependents?.length ? `; built after them: ${gate.dependents.join(", ")}` : "") + ")" : "")); if (repo) lines.push(`- \`${REPO_CHECK_CONTEXT}\`: **${(repo.verdict || "error").toUpperCase()}** — ${repo.summary}`); const ran = c.on ? `\n\nRun by the build seat on ${c.on} as \`${c.id}\` (\`builds --log ${c.id}\`).` : ""; const report = c.report ? `\n\n\`\`\`\n${c.report.replace(/```/g, "'''")}\n\`\`\`` : ""; diff --git a/modules/gitea/test/pulls.test.ts b/modules/gitea/test/pulls.test.ts index 0e54c19..29342a4 100644 --- a/modules/gitea/test/pulls.test.ts +++ b/modules/gitea/test/pulls.test.ts @@ -40,10 +40,10 @@ test("each layer is its own status: the gate with the modules it judged, the rep 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"] }, + 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/); + 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/);