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

A shipped tell finds its change by asking for the event, not scanning 200 #219

Merged opened this

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

Merged

scout/forge:scout/107-a-shipped-tell-finds-its-change-by-askin → main 1 commit fork

  • Merged. scout/107-a-shipped-tell-finds-its-change-by-askin was merged into main as 2665514.

Review

Sign in to review this change.
3 files changed +49 −5
src/core/events.ts +6
@@ -78,6 +78,8 @@ export class EventBus {
7878
7979 export interface ListEventsOptions {
8080 repoId?: string;
81 /** Restrict to events of this kind. */
82 kind?: string;
8183 /** Return events with id greater than this (exclusive). */
8284 afterId?: string;
8385 /** @default 100 */
@@ -148,6 +150,10 @@ export function listEvents(
148150 params.push(options.repoId);
149151 clauses.push(`repo_id = ?${params.length}`);
150152 }
153 if (options.kind !== undefined) {
154 params.push(options.kind);
155 clauses.push(`kind = ?${params.length}`);
156 }
151157 if (options.afterId !== undefined) {
152158 params.push(options.afterId);
153159 clauses.push(`id > ?${params.length}`);
src/web/studio/tell.ts +6 −5
@@ -52,11 +52,12 @@ import {
5252 * shows. Undefined for an issue closed by hand, or still open. */
5353 function shippedBy(db: Database, repo: Repo, issue: Issue): Pull | undefined {
5454 if (issue.state !== "closed") return undefined;
55 const closed = listEvents(db, { repoId: repo.id, limit: 200 }).find(
56 (e) =>
57 e.kind === "issue.closed" &&
58 Number(e.payload.number) === issue.number &&
59 e.payload.by === "merge",
55 const closed = listEvents(db, {
56 repoId: repo.id,
57 kind: "issue.closed",
58 limit: 200,
59 }).find(
60 (e) => Number(e.payload.number) === issue.number && e.payload.by === "merge",
6061 );
6162 if (closed === undefined) return undefined;
6263 const number = Number(closed.payload.pull);
test/studio.test.ts +37
@@ -362,6 +362,43 @@ describe("the studio", () => {
362362 expect(getUserByName(app.db, "scout")).toBeDefined();
363363 });
364364
365 test("a tell shipped long ago still reads shipped once it is buried under 250 later events", async () => {
366 const told = openIssue(app, alice, repo, {
367 title: "Buried tell",
368 body: "",
369 });
370 if (!told.ok) throw new Error(String(told.error));
371 const branch = await commitToBranch(app, alice, repo, {
372 branch: "feature/buried",
373 base: "main",
374 message: "Buried",
375 files: [{ path: "BURIED.md", content: "buried\n" }],
376 });
377 if (!branch.ok) throw new Error(JSON.stringify(branch.error));
378 const opened = await openPull(app, alice, repo, {
379 title: "Buried",
380 body: `Closes #${told.value.number}`,
381 baseBranch: "main",
382 headBranch: "feature/buried",
383 });
384 if (!opened.ok) throw new Error(String(opened.error));
385 const merged = await mergePull(app, alice, repo, opened.value, "squash");
386 if (!merged.ok) throw new Error(String(merged.error));
387 expect(getIssue(app.db, repo.id, told.value.number)?.state).toBe("closed");
388
389 // 250 events of other kinds, appended after the merge, so a scan of the
390 // most recent 200 events of any kind would never reach the one that
391 // actually closed this issue.
392 for (let i = 0; i < 250; i++)
393 app.bus.append({ kind: "push", repoId: repo.id, payload: { n: i } });
394
395 const page = await (
396 await get(`/alice/notes/issues/${told.value.number}`)
397 ).text();
398 expect(page).toContain('data-word="shipped"');
399 expect(page).not.toContain('data-state="closed"');
400 });
401
365402 test("a pull on an app renders as a studio page — the preview, the look and the decision, no diff; ?mode=dev still renders the diff", async () => {
366403 const scout = getUserByName(app.db, "scout")!;
367404 const branch = await commitToBranch(app, alice, repo, {

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs