diff --git a/src/approval-report/__tests__/act-board.test.ts b/src/approval-report/__tests__/act-board.test.ts index 4ca99db..70f8ce7 100644 --- a/src/approval-report/__tests__/act-board.test.ts +++ b/src/approval-report/__tests__/act-board.test.ts @@ -55,7 +55,7 @@ function boardIssue( number: Number.parseInt(rule.ruleId, 16) || 1, title: actBoardIssueTitle(rule), body: renderActBoardIssueBody(rule), - state: rule.status === "Deprecated" ? "closed" : "open", + state: "open", nodeId: `BOARD_${rule.ruleId}`, ...overrides, }; @@ -290,22 +290,19 @@ describe("upsertActBoardIssues", () => { expect(client.updateBoardIssue).not.toHaveBeenCalled(); }); - it("closes deprecated and snapshot-missing rule issues", async () => { + it("keeps deprecated rule issues open and closes snapshot-missing ones", async () => { const deprecated = row("674b10", { status: "Deprecated" }); - const oldDeprecated = boardIssue(deprecated, { - body: "old body", - state: "open", - }); + const oldDeprecated = boardIssue(deprecated, { body: "old body" }); const removed = boardIssue(row("2ee8b8")); const client = fakeClient({ issues: [oldDeprecated, removed] }); const result = await upsertActBoardIssues([deprecated], client); - expect(result.closed).toBe(2); + expect(result.closed).toBe(1); expect(client.updateBoardIssue).toHaveBeenCalledWith( expect.anything(), oldDeprecated.number, - expect.objectContaining({ state: "closed" }), + { body: renderActBoardIssueBody(deprecated) }, ); expect(client.updateBoardIssue).toHaveBeenCalledWith( expect.anything(), @@ -314,6 +311,38 @@ describe("upsertActBoardIssues", () => { ); }); + it("reopens a deprecated rule issue closed by an earlier run", async () => { + const deprecated = row("674b10", { status: "Deprecated" }); + const closedIssue = boardIssue(deprecated, { state: "closed" }); + const client = fakeClient({ issues: [closedIssue] }); + + const result = await upsertActBoardIssues([deprecated], client); + + expect(result.reopened).toBe(1); + expect(result.closed).toBe(0); + expect(client.updateBoardIssue).toHaveBeenCalledWith( + expect.anything(), + closedIssue.number, + { state: "open" }, + ); + }); + + it("creates a deprecated rule issue as open", async () => { + const deprecated = row("674b10", { status: "Deprecated" }); + const client = fakeClient(); + + const result = await upsertActBoardIssues([deprecated], client); + + expect(result.created).toBe(1); + expect(result.closed).toBe(0); + expect(client.createBoardIssue).toHaveBeenCalledWith( + expect.anything(), + actBoardIssueTitle(deprecated), + expect.stringContaining("**Status:** Deprecated"), + ); + expect(client.updateBoardIssue).not.toHaveBeenCalled(); + }); + it("adds new blockers and removes dropped sub-issues", async () => { const blocker = issue(12, "Current blocker", true); const currentRow = row("674b10", { diff --git a/src/approval-report/act-board.ts b/src/approval-report/act-board.ts index 3a2fafa..a1393c3 100644 --- a/src/approval-report/act-board.ts +++ b/src/approval-report/act-board.ts @@ -185,18 +185,11 @@ export async function upsertActBoardIssues( const ruleId = row.ruleId.toLowerCase(); const title = actBoardIssueTitle(row); const body = renderActBoardIssueBody(row); - const desiredState = row.status === "Deprecated" ? "closed" : "open"; let issue = managedIssues.get(ruleId); if (!issue) { issue = await client.createBoardIssue(boardRepository, title, body); result.created += 1; - if (desiredState === "closed") { - issue = await client.updateBoardIssue(boardRepository, issue.number, { - state: "closed", - }); - result.closed += 1; - } managedIssues.set(ruleId, issue); continue; } @@ -208,7 +201,10 @@ export async function upsertActBoardIssues( } = {}; if (issue.title !== title) update.title = title; if (normalizeBody(issue.body) !== normalizeBody(body)) update.body = body; - if (issue.state !== desiredState) update.state = desiredState; + // Every rule in the snapshot keeps an open issue, deprecated ones included. + // Projects v2 moves closed items to Done, which this Project renames + // "Approved, current"; the Deprecated status comes from the Project sync. + if (issue.state === "closed") update.state = "open"; if (Object.keys(update).length === 0) { unwrittenIssueNodeIds.add(issue.nodeId); @@ -219,8 +215,7 @@ export async function upsertActBoardIssues( update, ); managedIssues.set(ruleId, issue); - if (update.state === "closed") result.closed += 1; - else if (update.state === "open") result.reopened += 1; + if (update.state === "open") result.reopened += 1; else result.updated += 1; } }