Say where a pending merge check is: queued since when, then building on which machine (hq issue 446)
mesh/merge-gate pass: builds gitea, mesh-delivery → novox; no bus step; every machine composes with the change as it did without (4 of 4 compose)
mesh/repo-check pass: its merge-check.sh passed, each part in its toolchain: merge-check.sh (go), merge-check-typescript.sh (typescript)
mesh/delivery superseded: a newer head of the same pull request
mesh/merge-gate pass: builds gitea, mesh-delivery → novox; no bus step; every machine composes with the change as it did without (4 of 4 compose)
mesh/repo-check pass: its merge-check.sh passed, each part in its toolchain: merge-check.sh (go), merge-check-typescript.sh (typescript)
mesh/delivery superseded: a newer head of the same pull request
The forge's holder set mesh/merge-gate pending as "the mesh is mapping this head onto its module graph" and nothing changed it until the verdict, so a ten-minute controller check read as a stalled forge (issue 423). The holder now says the head waits in the build queue since the local time it was announced; mesh-delivery follows the build seat's started event and says the machine building it and since when, never over a verdict the forge holds.
This commit is contained in:
@@ -27,8 +27,8 @@
|
||||
|
||||
import { emit, on } from "@novox/mesh-sdk/events";
|
||||
import { GiteaClient, movedSince } from "./client.js";
|
||||
import { CHECK_CONTEXT, REPO_CHECK_CONTEXT, commentFor, headsToAnnounce, statusesFor, type Announced, type Checked,
|
||||
type RepoCheckFacts, reposToLook } from "./pulls.js";
|
||||
import { CHECK_CONTEXT, REPO_CHECK_CONTEXT, commentFor, headsToAnnounce, pendingWords, statusesFor, type Announced,
|
||||
type Checked, type RepoCheckFacts, reposToLook } from "./pulls.js";
|
||||
|
||||
// Without a way to a token — configured, or mintable with the admin account (token.ts) — there is
|
||||
// nothing to watch; log and stay quiet rather than crash the runtime. With one, the first poll mints
|
||||
@@ -274,10 +274,11 @@ async function pollPulls(client: GiteaClient): Promise<void> {
|
||||
});
|
||||
// Said, so an operator knows the mesh was asked to check it.
|
||||
console.log(`[gitea] announced ${key} at ${String(pull.head_sha).slice(0, 8)} to be checked before it merges`);
|
||||
// Pending until the verdict comes, so the pull request says a check is running rather than nothing.
|
||||
// Pending until the verdict comes, so the pull request says a check is running rather than nothing — and
|
||||
// where it is: in the build queue from now, until mesh-delivery says a build machine took it (issue 446).
|
||||
await client
|
||||
.setCommitStatus(repo.owner, repo.name, String(pull.head_sha), {
|
||||
state: "pending", context: CHECK_CONTEXT, description: "the mesh is mapping this head onto its module graph",
|
||||
state: "pending", context: CHECK_CONTEXT, description: pendingWords(new Date()),
|
||||
})
|
||||
.catch((err) => console.error(`[gitea] ${key}: could not say a check is pending — ${err instanceof Error ? err.message : err}`));
|
||||
}
|
||||
|
||||
@@ -18,6 +18,18 @@ export const CHECK_CONTEXT = "mesh/merge-gate";
|
||||
/** The status context of the repository's own merge-check.sh, the check's second layer (novox/hq ADR 0237). */
|
||||
export const REPO_CHECK_CONTEXT = "mesh/repo-check";
|
||||
|
||||
/**
|
||||
* The pending words a head's merge check is announced with (novox/hq issue 446): where the check is, and since when,
|
||||
* in the time the operator reads. They stood as "the mesh is mapping this head onto its module graph" for the whole
|
||||
* check — the few seconds the controller maps the head and then the queue wait and the build — and readers took the
|
||||
* forge for lagging (issue 423). The controller maps and queues the check in seconds, so from the announcement it waits
|
||||
* in the build queue; mesh-delivery says "building on <machine> since …" when a build machine takes it.
|
||||
*/
|
||||
export function pendingWords(announced: Date): string {
|
||||
const two = (n: number) => String(n).padStart(2, "0");
|
||||
return `waiting in the build queue since ${two(announced.getHours())}:${two(announced.getMinutes())}`;
|
||||
}
|
||||
|
||||
/** One layer of a check, judged. */
|
||||
export interface Layer {
|
||||
verdict: string;
|
||||
|
||||
@@ -146,3 +146,11 @@ test("a change plan is the gate's result: said on the status and, when it builds
|
||||
const nothing = { ...c, plan: { ...plan, moved: [], tiers: [], machines: [], summary: "builds nothing" } };
|
||||
assert.equal(commentFor(nothing), null);
|
||||
});
|
||||
|
||||
// **A pending check says where it is** (novox/hq issue 446): announced, it waits in the build queue, since the time the
|
||||
// operator reads — not "mapping this head onto its module graph" for the ten minutes of a controller check.
|
||||
test("a head announced is pending in the build queue, since the local time it was announced", async () => {
|
||||
const { pendingWords } = await import("../pulls.ts");
|
||||
assert.equal(pendingWords(new Date(2026, 9, 11, 3, 8, 50)), "waiting in the build queue since 03:08");
|
||||
assert.equal(pendingWords(new Date(2026, 9, 11, 14, 0, 0)), "waiting in the build queue since 14:00");
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user