Page the announcer through every open pull request updated since its last look
mesh/merge-gate head 961e57f7e403 merged into trunk 22071dabfc7b — pass: builds gitea → novox; no bus step; every machine composes with the change as it di…
mesh/repo-check head 961e57f7e403 merged into trunk 22071dabfc7b — pass: its merge-check.sh passed, each part in its toolchain: merge-check.sh (go), merge-…
mesh/delivery delivered

A pass read only the 20 most recently updated open pull requests of a
repository, so a new head beyond them went unannounced and its merge check
never started (novox/hq issue 579). Pages stop at the floor; a sweep reads all.
This commit is contained in:
2026-10-12 20:52:27 +02:00
parent 22071dabfc
commit 961e57f7e4
3 changed files with 121 additions and 3 deletions
+26 -2
View File
@@ -342,8 +342,8 @@ export class GiteaClient {
}
/** **Every open pull request of a repository**, page by page (novox/hq ADR 0323 §4): what a trunk's move puts out of
* date, however many are open — not the twenty most recently updated a pass announces from. Bounded at 20 pages
* of 50; a repository with more is said, and the rest are left to the merge tool's own comparison. */
* date, however many are open, whatever their update time (a pass announces from listOpenPullsSince). Bounded at
* 20 pages of 50; a repository with more is said, and the rest are left to the merge tool's own comparison. */
async listOpenPulls(owner: string, repo: string): Promise<GiteaPull[]> {
const out: GiteaPull[] = [];
for (let page = 1; page <= 20; page++) {
@@ -355,6 +355,30 @@ export class GiteaClient {
return out;
}
/** **The open pull requests of a repository updated since a moment**, newest first, page by page (novox/hq issue
* 579): what a pass announces new heads from. The forge sorts `recentupdate` by update time, newest first, so the
* paging stops at the first page that reaches back past `since`; with no moment — a sweep or the first pass —
* every page is read. Bounded like listOpenPulls at 20 pages of 50. A pull request seen twice, pushed up a page
* while the pages were read, is answered once. */
async listOpenPullsSince(owner: string, repo: string, since: string): Promise<GiteaPull[]> {
const out: GiteaPull[] = [];
const seen = new Set<number>();
const floor = since ? Date.parse(since) : NaN;
for (let page = 1; page <= 20; page++) {
const batch = await this.listPullRequests(owner, repo, { state: "open", sort: "recentupdate", limit: "50", page: String(page) });
for (const p of batch) {
if (seen.has(p.number)) continue;
seen.add(p.number);
out.push(p);
}
if (batch.length < 50) return out;
const oldest = batch[batch.length - 1]?.updated_at;
if (!Number.isNaN(floor) && oldest && Date.parse(oldest) < floor) return out;
}
console.error(`[gitea] ${owner}/${repo} has more than 1000 open pull requests updated since ${since || "ever"}; only the newest 1000 are read`);
return out;
}
/** The commit a branch is at now: a trunk's head (novox/hq ADR 0323). */
async branchHead(owner: string, repo: string, branch: string): Promise<string> {
const b = await this.request<any>(`${repoPath(owner, repo)}/branches/${pathSegments("branch", branch)}`);