From 4127453bc67175b22b2db62b73b0750e3f57c294 Mon Sep 17 00:00:00 2001 From: Roomote Date: Mon, 31 Aug 2026 03:01:28 +0000 Subject: [PATCH 1/2] fix: link review gate to workflow details --- .github/workflows/label-pr-review-state.yml | 6 +++--- .../__tests__/pr-review-state-workflow.test.ts | 10 +++++++++- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/.github/workflows/label-pr-review-state.yml b/.github/workflows/label-pr-review-state.yml index 48d836420e..564371513e 100644 --- a/.github/workflows/label-pr-review-state.yml +++ b/.github/workflows/label-pr-review-state.yml @@ -76,6 +76,7 @@ jobs: const codeRabbitActiveLabel = 'coderabbit-review-active'; const reviewGateName = 'Zoo Code / PR review gate'; const reconciliationCheckName = 'Zoo Code / reconcile PR review state'; + const workflowRunUrl = `${context.serverUrl}/${owner}/${repo}/actions/runs/${context.runId}`; // When triggered by a single PR event, only reconcile that PR. // The hourly schedule and workflow_dispatch reconcile all open PRs. @@ -316,8 +317,7 @@ jobs: } if (!lookupSucceeded && passed) return; if (latestGateStatus?.state === state && - latestGateStatus.description === description && - latestGateStatus.target_url === pr.html_url) { + latestGateStatus.description === description) { return; } const mustInvalidateSuccess = !passed && @@ -331,7 +331,7 @@ jobs: state, context: reviewGateName, description, - target_url: pr.html_url, + target_url: workflowRunUrl, }); } catch (error) { if (required || mustInvalidateSuccess) throw error; diff --git a/src/services/__tests__/pr-review-state-workflow.test.ts b/src/services/__tests__/pr-review-state-workflow.test.ts index 5cc0241db8..22e944bb3f 100644 --- a/src/services/__tests__/pr-review-state-workflow.test.ts +++ b/src/services/__tests__/pr-review-state-workflow.test.ts @@ -15,6 +15,7 @@ const workflowScript = workflow.jobs.reconcile.steps[0].with.script as string const SHA = "a".repeat(40) const OLD_SHA = "b".repeat(40) const REVIEWED_AT = Date.parse("2026-08-29T15:02:00Z") +const WORKFLOW_RUN_URL = "https://github.com/Zoo-Code-Org/Zoo-Code/actions/runs/123456" type ReviewState = "APPROVED" | "CHANGES_REQUESTED" | "COMMENTED" | "DISMISSED" @@ -329,6 +330,8 @@ async function runWorkflow(options: HarnessOptions = {}) { const context = { eventName, repo: { owner: "Zoo-Code-Org", repo: "Zoo-Code" }, + runId: 123456, + serverUrl: "https://github.com", payload, } const core = { @@ -1099,7 +1102,12 @@ describe("PR review-state workflow", () => { const result = await runWorkflow() expect(latestGateStatus(result)).toEqual( - expect.objectContaining({ context: "Zoo Code / PR review gate", sha: SHA, state: "pending" }), + expect.objectContaining({ + context: "Zoo Code / PR review gate", + sha: SHA, + state: "pending", + target_url: WORKFLOW_RUN_URL, + }), ) }) From cdedb0b91f60c6af7fd1e57029448e6d5dfe1c62 Mon Sep 17 00:00:00 2001 From: Roomote Date: Mon, 31 Aug 2026 03:13:53 +0000 Subject: [PATCH 2/2] test: cover changed review gate links --- .../pr-review-state-workflow.test.ts | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/services/__tests__/pr-review-state-workflow.test.ts b/src/services/__tests__/pr-review-state-workflow.test.ts index 22e944bb3f..f38e46c54d 100644 --- a/src/services/__tests__/pr-review-state-workflow.test.ts +++ b/src/services/__tests__/pr-review-state-workflow.test.ts @@ -1127,6 +1127,27 @@ describe("PR review-state workflow", () => { expect(result.addLabels).toHaveBeenCalledWith(expect.objectContaining({ labels: ["awaiting-coderabbit"] })) }) + it("publishes a changed review gate status with the workflow run URL", async () => { + const result = await runWorkflow({ + gateStatuses: [ + { + context: "Zoo Code / PR review gate", + state: "pending", + description: "Wait for the required CI checks to finish.", + targetUrl: "https://github.com/Zoo-Code-Org/Zoo-Code/pull/1437", + }, + ], + }) + + expect(latestGateStatus(result)).toEqual( + expect.objectContaining({ + state: "pending", + description: "Required CI passed. Wait for CodeRabbit to approve the latest commit.", + target_url: WORKFLOW_RUN_URL, + }), + ) + }) + it("continues metadata reconciliation when gate publication fails", async () => { const result = await runWorkflow({ createCommitStatusErrorStatus: 500 })