From 38250e28bca0a21c8ce3799b2b9b67973b9f59c1 Mon Sep 17 00:00:00 2001 From: ghost <49853598+JSONbored@users.noreply.github.com> Date: Wed, 8 Jul 2026 03:23:25 -0700 Subject: [PATCH] fix(review): keep fallback marker until workflow completion --- src/queue/processors.ts | 1 + test/unit/actions-fallback-webhook.test.ts | 31 ++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/src/queue/processors.ts b/src/queue/processors.ts index 1fc9397f7b..6874a1f87a 100644 --- a/src/queue/processors.ts +++ b/src/queue/processors.ts @@ -4601,6 +4601,7 @@ async function maybeCaptureOnActionsFallbackWorkflowRun( } ).workflow_run; if (run?.name !== FALLBACK_WORKFLOW_NAME || run?.event !== "workflow_dispatch") return false; + if (payload.action !== "completed") return false; const correlation = parseFallbackRunCorrelation(run.display_title); if (correlation) { diff --git a/test/unit/actions-fallback-webhook.test.ts b/test/unit/actions-fallback-webhook.test.ts index 5bf58c1ba2..738a3c40af 100644 --- a/test/unit/actions-fallback-webhook.test.ts +++ b/test/unit/actions-fallback-webhook.test.ts @@ -484,6 +484,37 @@ describe("workflow_run webhook -> actions_fallback storage (#4112)", () => { expect(artifactsListCalled).toBe(false); }); + it("does not clear the dispatch marker for a non-terminal workflow_run activity", async () => { + const env = createTestEnv({ GITHUB_APP_PRIVATE_KEY: await generatePrivateKeyPem(), GITTENSORY_REVIEW_REPOS: "owner/fallback-repo", REVIEW_AUDIT: memoryReviewAudit() }); + await seedRepoAndPr(env, "cafebabecafebabecafebabecafebabecafebabe"); + await markFallbackDispatched(env, "cafebabecafebabecafebabecafebabecafebabe"); + let artifactsListCalled = false; + vi.stubGlobal( + "fetch", + baseFetchStub({ + "/actions/runs/": () => { + artifactsListCalled = true; + return Response.json({ artifacts: [] }); + }, + }), + ); + + await processJob(env, { + type: "github-webhook", + deliveryId: "requested-run-keeps-marker", + eventName: "workflow_run", + payload: { + action: "requested", + repository: { name: "fallback-repo", full_name: "owner/fallback-repo", owner: { login: "owner" } }, + installation: { id: 9101 }, + workflow_run: { id: 589, name: "Gittensory Visual Capture Fallback", event: "workflow_dispatch", conclusion: null, display_title: "gittensory-visual-fallback pr=55 sha=cafebabecafebabecafebabecafebabecafebabe" }, + }, + } as never); + + expect(artifactsListCalled).toBe(false); + await expect(isFallbackDispatchInFlight(env, "cafebabecafebabecafebabecafebabecafebabe")).resolves.toBe(true); + }); + it("clears the dispatch marker on a FAILED run too (#4112 review fix -- a failed run shouldn't block a retry for the rest of the max-age window)", async () => { const env = createTestEnv({ GITHUB_APP_PRIVATE_KEY: await generatePrivateKeyPem(), GITTENSORY_REVIEW_REPOS: "owner/fallback-repo", REVIEW_AUDIT: memoryReviewAudit() }); await seedRepoAndPr(env, "cafebabecafebabecafebabecafebabecafebabe");