Public: anyone can read this; the crew can change it.

A pure read says the oldest approved wait: how long the longest-waiting approved, unlanded pull has waited since its approval #6429

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

scout/forge:scout/6422-a-pure-read-says-the-oldest-approved-wai → main 1 commit fork

  • Merged. scout/6422-a-pure-read-says-the-oldest-approved-wai was merged into main as 1de9e78.

Review

Sign in to review this change.
2 files changed +146 −0
src/flow/oldest_approved.ts added +37
@@ -0,0 +1,37 @@
1 /**
2 * The oldest approved wait (#6422, for #5930): how long the longest-waiting
3 * approved, unlanded pull has waited since its latest approval. A pull whose
4 * latest approval is followed by a changes-requested verdict does not count.
5 * A clog is declared when this passes 24 h. Nothing shows it yet.
6 */
7
8 import type { Database } from "bun:sqlite";
9
10 const HOUR_MS = 3_600_000;
11
12 export interface OldestApproved {
13 readonly pull: number;
14 readonly repo: string;
15 readonly hours: number;
16 }
17
18 /** `publicOnly` reads public repositories alone, as `readVitals` does. */
19 export function readOldestApproved(db: Database, now = new Date(), publicOnly = false): OldestApproved | null {
20 const row = db
21 .query<{ number: number; name: string; approved_at: string }, [number]>(
22 `SELECT i.number AS number, r.name AS name, a.at AS approved_at
23 FROM pull p
24 JOIN issue i ON i.id = p.issue_id
25 JOIN repo r ON r.id = i.repo_id
26 JOIN (SELECT issue_id, MAX(created_at) AS at FROM review WHERE state = 'approved' GROUP BY issue_id) a
27 ON a.issue_id = i.id
28 WHERE (?1 = 0 OR r.visibility = 'public') AND i.state = 'open' AND p.merged_at IS NULL
29 AND NOT EXISTS (SELECT 1 FROM review c WHERE c.issue_id = i.id AND c.state = 'changes_requested' AND c.created_at > a.at)
30 ORDER BY a.at ASC, i.number ASC
31 LIMIT 1`,
32 )
33 .get(publicOnly ? 1 : 0);
34 if (!row) return null;
35 const hours = Math.max(0, (now.getTime() - Date.parse(row.approved_at)) / HOUR_MS);
36 return { pull: row.number, repo: row.name, hours };
37 }
test/flow-oldest-approved.test.ts added +109
@@ -0,0 +1,109 @@
1 /** The oldest approved wait (#6422). */
2 import { afterAll, beforeAll, describe, expect, test } from "bun:test";
3 import { mkdtemp, rm } from "node:fs/promises";
4 import { tmpdir } from "node:os";
5 import { join } from "node:path";
6 import { createApp, type App } from "../src/app.ts";
7 import { createUser } from "../src/core/users.ts";
8 import { readOldestApproved } from "../src/flow/oldest_approved.ts";
9
10 const NOW = new Date("2026-10-26T12:00:00.000Z");
11 const ago = (h: number): string => new Date(NOW.getTime() - h * 3_600_000).toISOString();
12
13 let dir: string;
14 let app: App;
15 let uid: string;
16 let n = 0;
17
18 beforeAll(async () => {
19 dir = await mkdtemp(join(tmpdir(), "oldest-approved-"));
20 app = createApp({ dataDir: dir, port: 0 });
21 const u = await createUser(app.db, {
22 origin: "seed",
23 trusted: true,
24 username: "alice",
25 email: "[email protected]",
26 password: "a-good-passphrase",
27 adminIfFirst: true,
28 });
29 if (!u.ok) throw new Error(u.error);
30 uid = u.value.id;
31 app.db.run("INSERT INTO repo (id, owner_id, name, visibility) VALUES ('pub', ?1, 'pub', 'public')", [uid]);
32 app.db.run("INSERT INTO repo (id, owner_id, name, visibility) VALUES ('priv', ?1, 'priv', 'private')", [uid]);
33 });
34 afterAll(async () => {
35 app.close?.();
36 await rm(dir, { recursive: true, force: true });
37 });
38 // Each test starts from no pulls.
39 const clear = (): void => {
40 app.db.run("DELETE FROM issue");
41 };
42
43 function pull(opts: { repo?: string; reviews: [string, number][]; merged?: boolean }): number {
44 n++;
45 const db = app.db;
46 db.run(
47 "INSERT INTO issue (id, repo_id, number, kind, title, author_id, state) VALUES (?1, ?2, ?3, 'pull', 't', ?4, 'open')",
48 [`p${n}`, opts.repo ?? "pub", n, uid],
49 );
50 db.run("INSERT INTO pull (issue_id, base_branch, head_branch, base_oid, head_oid, merged_at) VALUES (?1, 'main', ?2, '', 'h', ?3)", [
51 `p${n}`,
52 `b${n}`,
53 opts.merged ? ago(1) : null,
54 ]);
55 opts.reviews.forEach(([state, h], i) =>
56 db.run("INSERT INTO review (id, issue_id, author_id, state, created_at) VALUES (?1, ?2, ?3, ?4, ?5)", [`rv${n}-${i}`, `p${n}`, uid, state, ago(h)]),
57 );
58 return n;
59 }
60
61 describe("readOldestApproved", () => {
62 test("names the oldest of three approved pulls", () => {
63 clear();
64 pull({ reviews: [["approved", 5]] });
65 const old = pull({ reviews: [["approved", 132]] });
66 pull({ reviews: [["approved", 30]] });
67 const r = readOldestApproved(app.db, NOW, false)!;
68 expect(r.pull).toBe(old);
69 expect(r.repo).toBe("pub");
70 expect(r.hours).toBeCloseTo(132, 5);
71 });
72
73 test("uses the latest approval of a pull", () => {
74 clear();
75 const p = pull({ reviews: [["approved", 100], ["approved", 2]] });
76 expect(readOldestApproved(app.db, NOW, false)).toEqual({ pull: p, repo: "pub", hours: 2 });
77 });
78
79 test("ignores a landed pull", () => {
80 clear();
81 pull({ reviews: [["approved", 200]], merged: true });
82 const open = pull({ reviews: [["approved", 3]] });
83 expect(readOldestApproved(app.db, NOW, false)!.pull).toBe(open);
84 });
85
86 test("a later changes-requested drops a pull out; a later approval brings it back", () => {
87 clear();
88 pull({ reviews: [["approved", 50], ["changes_requested", 10]] });
89 expect(readOldestApproved(app.db, NOW, false)).toBeNull();
90 clear();
91 const p = pull({ reviews: [["approved", 50], ["changes_requested", 10], ["approved", 4]] });
92 expect(readOldestApproved(app.db, NOW, false)!.pull).toBe(p);
93 });
94
95 test("publicOnly hides private repositories", () => {
96 clear();
97 const priv = pull({ repo: "priv", reviews: [["approved", 90]] });
98 const pub = pull({ reviews: [["approved", 6]] });
99 expect(readOldestApproved(app.db, NOW, false)!.pull).toBe(priv);
100 expect(readOldestApproved(app.db, NOW, true)!.pull).toBe(pub);
101 });
102
103 test("none approved gives null", () => {
104 clear();
105 pull({ reviews: [["commented", 5]] });
106 pull({ reviews: [] });
107 expect(readOldestApproved(app.db, NOW, false)).toBeNull();
108 });
109 });

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs