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

The parked-twice hand-over skips an issue that is done on main #2525

Merged opened this

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

Merged

scout/forge:scout/2514-the-parked-twice-hand-over-skips-an-issu → main 1 commit fork 1 thread · 1 unresolved

  • Merged. scout/2514-the-parked-twice-hand-over-skips-an-issu was merged into main as a09af57.

Review

Sign in to review this change.
2 files changed +37 −3
src/crew/parks.ts +7 −3
@@ -22,7 +22,7 @@
2222 import type { Database } from "bun:sqlite";
2323 import { getIssueById, standsForPerson } from "../core/issues.ts";
2424 import type { Repo } from "../core/repos.ts";
25 import { BY_CREW, DONE_LIKE, PARK_LIKE } from "../core/done_on_main.ts";
25 import { alreadyDone, BY_CREW, DONE_LIKE, PARK_LIKE } from "../core/done_on_main.ts";
2626 import { directorsAmong, proposedWork } from "./direct.ts";
2727
2828 /** Parks since the last word at which the clock no longer dispatches an issue. */
@@ -188,7 +188,7 @@ export interface ParkedTwice {
188188 * nothing open. So an issue leaves the list when it is closed (split, or
189189 * replaced by a fresh one), when it is put behind something open (its
190190 * parts, or the Later gate), or when someone who directs the crew says what
191 * to try. One read for every repository, and two more for each that has
191 * to try, or when commits on main already name it (`alreadyDone`). One read for every repository, and two more for each that has

This line is much longer than the rest of the comment. Rewrap it, and move the alreadyDone mention onto its own line.

192192 * any.
193193 */
194194 export function parkedTwice(
@@ -280,9 +280,13 @@ export function parkedTwice(
280280 : issue;
281281 });
282282 if (struck.length === 0) continue;
283 // Finished work is the asker's to close, not the planner's to split.
284 const done = alreadyDone(db, struck.map((issue) => issue.issueId));
285 const open = struck.filter((issue) => !done.has(issue.issueId));
286 if (open.length === 0) continue;
283287 // An open pull that would close it is someone's answer already.
284288 const proposed = proposedWork(db, repo);
285 out.push(...struck.filter((issue) => !proposed.has(issue.number)));
289 out.push(...open.filter((issue) => !proposed.has(issue.number)));
286290 }
287291 return out;
288292 }
test/crew-parks.test.ts +30
@@ -1560,4 +1560,34 @@ describe("an issue found already done is the asker's to close, not a park", () =
15601560 expect(alreadyDone(e.app.db, [work.id]).has(work.id)).toBe(false);
15611561 expect(alreadyDoneOids("no changes pushed: already done: " + oid)).toEqual([]);
15621562 });
1563
1564 test("an issue parked twice whose newest crew note is the done note is not handed to the planner", () => {
1565 const park = (on: Issue) => {
1566 for (let n = 0; n < 2; n++)
1567 addComment(e.app, e.mason, e.fresh(), on, "Parked by the crew: " + nothingNew);
1568 };
1569 const nothingNew = "the run ended without a pull: nothing to propose";
1570 const finished = e.issue("Parked, then found done");
1571 const open = e.issue("Parked, still open");
1572 park(finished);
1573 park(open);
1574 const numbers = () => parkedTwice(e.app.db, [e.fresh()]).map((i) => i.number);
1575 expect(numbers()).toEqual([finished.number, open.number]);
1576 addComment(
1577 e.app,
1578 e.mason,
1579 e.fresh(),
1580 finished,
1581 "Done on main already, waiting for you to close it: " + oid,
1582 );
1583 // Written in the same instant as the park: the clock cannot order them.
1584 e.app.db.run(
1585 `UPDATE comment SET created_at = (SELECT MAX(p.created_at) FROM comment p
1586 WHERE p.issue_id = ?1 AND p.body LIKE 'Parked by the crew%')
1587 WHERE issue_id = ?1 AND body LIKE 'Done on main already%'`,
1588 [finished.id],
1589 );
1590 expect(alreadyDone(e.app.db, [finished.id]).get(finished.id)).toEqual([oid]);
1591 expect(numbers()).toEqual([open.number]);
1592 });
15631593 });

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs