From 493dbcd285fa51e5f904c57c7aba3836f5fdab30 Mon Sep 17 00:00:00 2001 From: carlobeltrame Date: Tue, 17 Jun 2025 14:55:14 +0200 Subject: [PATCH 1/5] Filter by creation date Fixes Codex-/return-dispatch#264 --- dist/index.mjs | 6 ++++-- src/api.spec.ts | 12 ++++++------ src/api.ts | 4 ++++ src/return-dispatch.ts | 2 +- 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/dist/index.mjs b/dist/index.mjs index 429f5942..716acd30 100644 --- a/dist/index.mjs +++ b/dist/index.mjs @@ -24129,13 +24129,15 @@ async function fetchWorkflowRunUrl(runId) { throw error5; } } -async function fetchWorkflowRunIds(workflowId, branch) { +async function fetchWorkflowRunIds(workflowId, branch, startTime) { try { const useBranchFilter = !branch.isTag && branch.branchName !== void 0 && branch.branchName !== ""; + const afterStartTime = ">" + new Date(startTime).toISOString(); const response = await octokit.rest.actions.listWorkflowRuns({ owner: config.owner, repo: config.repo, workflow_id: workflowId, + created: afterStartTime, ...useBranchFilter ? { branch: branch.branchName, per_page: 10 @@ -24330,7 +24332,7 @@ async function getRunIdAndUrl({ while (elapsedTime < workflowTimeoutMs) { attemptNo++; const fetchWorkflowRunIds2 = await retryOrTimeout( - () => fetchWorkflowRunIds(workflowId, branch), + () => fetchWorkflowRunIds(workflowId, branch, startTime), retryTimeout ); if (!fetchWorkflowRunIds2.success) { diff --git a/src/api.spec.ts b/src/api.spec.ts index 6723b322..04d8c1e7 100644 --- a/src/api.spec.ts +++ b/src/api.spec.ts @@ -358,7 +358,7 @@ describe("API", () => { ); // Behaviour - await expect(fetchWorkflowRunIds(0, branch)).resolves.toStrictEqual( + await expect(fetchWorkflowRunIds(0, branch, Date.now())).resolves.toStrictEqual( mockData.workflow_runs.map((run) => run.id), ); @@ -389,7 +389,7 @@ describe("API", () => { ); // Behaviour - await expect(fetchWorkflowRunIds(0, branch)).rejects.toThrow( + await expect(fetchWorkflowRunIds(0, branch, Date.now())).rejects.toThrow( `Failed to fetch Workflow runs, expected 200 but received ${errorStatus}`, ); @@ -417,7 +417,7 @@ describe("API", () => { ); // Behaviour - await expect(fetchWorkflowRunIds(0, branch)).resolves.toStrictEqual([]); + await expect(fetchWorkflowRunIds(0, branch, Date.now())).resolves.toStrictEqual([]); // Logging assertOnlyCalled(coreDebugLogMock); @@ -453,7 +453,7 @@ describe("API", () => { ); // Behaviour - await expect(fetchWorkflowRunIds(0, branch)).resolves.not.toThrow(); + await expect(fetchWorkflowRunIds(0, branch, Date.now())).resolves.not.toThrow(); expect(parsedRef).toStrictEqual("master"); // Logging @@ -490,7 +490,7 @@ describe("API", () => { ); // Behaviour - await expect(fetchWorkflowRunIds(0, branch)).resolves.not.toThrow(); + await expect(fetchWorkflowRunIds(0, branch, Date.now())).resolves.not.toThrow(); expect(parsedRef).toBeUndefined(); // Logging @@ -527,7 +527,7 @@ describe("API", () => { ); // Behaviour - await expect(fetchWorkflowRunIds(0, branch)).resolves.not.toThrow(); + await expect(fetchWorkflowRunIds(0, branch, Date.now())).resolves.not.toThrow(); expect(parsedRef).toBeUndefined(); // Logging diff --git a/src/api.ts b/src/api.ts index 2c0a07e2..d456b3b6 100644 --- a/src/api.ts +++ b/src/api.ts @@ -158,6 +158,7 @@ export async function fetchWorkflowRunUrl(runId: number): Promise { export async function fetchWorkflowRunIds( workflowId: number, branch: BranchNameResult, + startTime: number, ): Promise { try { const useBranchFilter = @@ -165,11 +166,14 @@ export async function fetchWorkflowRunIds( branch.branchName !== undefined && branch.branchName !== ""; + const afterStartTime = '>' + (new Date(startTime)).toISOString(); + // https://docs.github.com/en/rest/actions/workflow-runs#list-workflow-runs-for-a-repository const response = await octokit.rest.actions.listWorkflowRuns({ owner: config.owner, repo: config.repo, workflow_id: workflowId, + created: afterStartTime, ...(useBranchFilter ? { branch: branch.branchName, diff --git a/src/return-dispatch.ts b/src/return-dispatch.ts index a7d17836..d2d76b2e 100644 --- a/src/return-dispatch.ts +++ b/src/return-dispatch.ts @@ -151,7 +151,7 @@ export async function getRunIdAndUrl({ // Get all runs for a given workflow ID const fetchWorkflowRunIds = await api.retryOrTimeout( - () => api.fetchWorkflowRunIds(workflowId, branch), + () => api.fetchWorkflowRunIds(workflowId, branch, startTime), retryTimeout, ); if (!fetchWorkflowRunIds.success) { From 6b7c495fef426698ba08a4fca87fff2507dfa4d8 Mon Sep 17 00:00:00 2001 From: carlobeltrame Date: Tue, 17 Jun 2025 15:09:54 +0200 Subject: [PATCH 2/5] Filter by event type workflow_dispatch --- dist/index.mjs | 1 + src/api.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/dist/index.mjs b/dist/index.mjs index 716acd30..8cb13e87 100644 --- a/dist/index.mjs +++ b/dist/index.mjs @@ -24138,6 +24138,7 @@ async function fetchWorkflowRunIds(workflowId, branch, startTime) { repo: config.repo, workflow_id: workflowId, created: afterStartTime, + event: "workflow_dispatch", ...useBranchFilter ? { branch: branch.branchName, per_page: 10 diff --git a/src/api.ts b/src/api.ts index d456b3b6..171a1cb3 100644 --- a/src/api.ts +++ b/src/api.ts @@ -174,6 +174,7 @@ export async function fetchWorkflowRunIds( repo: config.repo, workflow_id: workflowId, created: afterStartTime, + event: 'workflow_dispatch', ...(useBranchFilter ? { branch: branch.branchName, From 66afbedcc43ae8a1d1d9aa191cbc4eb4ee5c1e15 Mon Sep 17 00:00:00 2001 From: Alex Miller Date: Wed, 18 Jun 2025 10:12:33 +1200 Subject: [PATCH 3/5] chore: format --- src/api.spec.ts | 22 +++++++++++++++------- src/api.ts | 4 ++-- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/api.spec.ts b/src/api.spec.ts index 04d8c1e7..04cace11 100644 --- a/src/api.spec.ts +++ b/src/api.spec.ts @@ -358,9 +358,9 @@ describe("API", () => { ); // Behaviour - await expect(fetchWorkflowRunIds(0, branch, Date.now())).resolves.toStrictEqual( - mockData.workflow_runs.map((run) => run.id), - ); + await expect( + fetchWorkflowRunIds(0, branch, Date.now()), + ).resolves.toStrictEqual(mockData.workflow_runs.map((run) => run.id)); // Logging assertOnlyCalled(coreDebugLogMock); @@ -417,7 +417,9 @@ describe("API", () => { ); // Behaviour - await expect(fetchWorkflowRunIds(0, branch, Date.now())).resolves.toStrictEqual([]); + await expect( + fetchWorkflowRunIds(0, branch, Date.now()), + ).resolves.toStrictEqual([]); // Logging assertOnlyCalled(coreDebugLogMock); @@ -453,7 +455,9 @@ describe("API", () => { ); // Behaviour - await expect(fetchWorkflowRunIds(0, branch, Date.now())).resolves.not.toThrow(); + await expect( + fetchWorkflowRunIds(0, branch, Date.now()), + ).resolves.not.toThrow(); expect(parsedRef).toStrictEqual("master"); // Logging @@ -490,7 +494,9 @@ describe("API", () => { ); // Behaviour - await expect(fetchWorkflowRunIds(0, branch, Date.now())).resolves.not.toThrow(); + await expect( + fetchWorkflowRunIds(0, branch, Date.now()), + ).resolves.not.toThrow(); expect(parsedRef).toBeUndefined(); // Logging @@ -527,7 +533,9 @@ describe("API", () => { ); // Behaviour - await expect(fetchWorkflowRunIds(0, branch, Date.now())).resolves.not.toThrow(); + await expect( + fetchWorkflowRunIds(0, branch, Date.now()), + ).resolves.not.toThrow(); expect(parsedRef).toBeUndefined(); // Logging diff --git a/src/api.ts b/src/api.ts index 171a1cb3..8286491f 100644 --- a/src/api.ts +++ b/src/api.ts @@ -166,7 +166,7 @@ export async function fetchWorkflowRunIds( branch.branchName !== undefined && branch.branchName !== ""; - const afterStartTime = '>' + (new Date(startTime)).toISOString(); + const afterStartTime = ">" + new Date(startTime).toISOString(); // https://docs.github.com/en/rest/actions/workflow-runs#list-workflow-runs-for-a-repository const response = await octokit.rest.actions.listWorkflowRuns({ @@ -174,7 +174,7 @@ export async function fetchWorkflowRunIds( repo: config.repo, workflow_id: workflowId, created: afterStartTime, - event: 'workflow_dispatch', + event: "workflow_dispatch", ...(useBranchFilter ? { branch: branch.branchName, From 496dd662f32e406aa39007fd344da6b3c4ff6300 Mon Sep 17 00:00:00 2001 From: Alex Miller Date: Wed, 18 Jun 2025 10:20:01 +1200 Subject: [PATCH 4/5] feat: use created from including start time (>=) --- src/api.spec.ts | 20 ++++++++++++++------ src/api.ts | 5 +++-- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/api.spec.ts b/src/api.spec.ts index 04cace11..135c3b67 100644 --- a/src/api.spec.ts +++ b/src/api.spec.ts @@ -326,6 +326,7 @@ describe("API", () => { }); describe("fetchWorkflowRunIds", () => { + const startTimeISO = "2025-06-17T22:24:23.238Z"; const workflowIdCfg: ActionConfig = { token: "secret", ref: "/refs/heads/feature_branch", @@ -359,7 +360,7 @@ describe("API", () => { // Behaviour await expect( - fetchWorkflowRunIds(0, branch, Date.now()), + fetchWorkflowRunIds(0, branch, startTimeISO), ).resolves.toStrictEqual(mockData.workflow_runs.map((run) => run.id)); // Logging @@ -371,6 +372,7 @@ describe("API", () => { Repository: owner/repository Branch Filter: true (feature_branch) Workflow ID: 0 + Created: >=2025-06-17T22:24:23.238Z Runs Fetched: [0, 1, 2]" `, ); @@ -389,7 +391,9 @@ describe("API", () => { ); // Behaviour - await expect(fetchWorkflowRunIds(0, branch, Date.now())).rejects.toThrow( + await expect( + fetchWorkflowRunIds(0, branch, startTimeISO), + ).rejects.toThrow( `Failed to fetch Workflow runs, expected 200 but received ${errorStatus}`, ); @@ -418,7 +422,7 @@ describe("API", () => { // Behaviour await expect( - fetchWorkflowRunIds(0, branch, Date.now()), + fetchWorkflowRunIds(0, branch, startTimeISO), ).resolves.toStrictEqual([]); // Logging @@ -430,6 +434,7 @@ describe("API", () => { Repository: owner/repository Branch Filter: true (feature_branch) Workflow ID: 0 + Created: >=2025-06-17T22:24:23.238Z Runs Fetched: []" `, ); @@ -456,7 +461,7 @@ describe("API", () => { // Behaviour await expect( - fetchWorkflowRunIds(0, branch, Date.now()), + fetchWorkflowRunIds(0, branch, startTimeISO), ).resolves.not.toThrow(); expect(parsedRef).toStrictEqual("master"); @@ -469,6 +474,7 @@ describe("API", () => { Repository: owner/repository Branch Filter: true (master) Workflow ID: 0 + Created: >=2025-06-17T22:24:23.238Z Runs Fetched: []" `, ); @@ -495,7 +501,7 @@ describe("API", () => { // Behaviour await expect( - fetchWorkflowRunIds(0, branch, Date.now()), + fetchWorkflowRunIds(0, branch, startTimeISO), ).resolves.not.toThrow(); expect(parsedRef).toBeUndefined(); @@ -508,6 +514,7 @@ describe("API", () => { Repository: owner/repository Branch Filter: false (/refs/tags/1.5.0) Workflow ID: 0 + Created: >=2025-06-17T22:24:23.238Z Runs Fetched: []" `, ); @@ -534,7 +541,7 @@ describe("API", () => { // Behaviour await expect( - fetchWorkflowRunIds(0, branch, Date.now()), + fetchWorkflowRunIds(0, branch, startTimeISO), ).resolves.not.toThrow(); expect(parsedRef).toBeUndefined(); @@ -547,6 +554,7 @@ describe("API", () => { Repository: owner/repository Branch Filter: false (/refs/cake) Workflow ID: 0 + Created: >=2025-06-17T22:24:23.238Z Runs Fetched: []" `, ); diff --git a/src/api.ts b/src/api.ts index 8286491f..799f32b1 100644 --- a/src/api.ts +++ b/src/api.ts @@ -166,14 +166,14 @@ export async function fetchWorkflowRunIds( branch.branchName !== undefined && branch.branchName !== ""; - const afterStartTime = ">" + new Date(startTime).toISOString(); + const createdFrom = ">=" + new Date(startTime).toISOString(); // https://docs.github.com/en/rest/actions/workflow-runs#list-workflow-runs-for-a-repository const response = await octokit.rest.actions.listWorkflowRuns({ owner: config.owner, repo: config.repo, workflow_id: workflowId, - created: afterStartTime, + created: createdFrom, event: "workflow_dispatch", ...(useBranchFilter ? { @@ -204,6 +204,7 @@ export async function fetchWorkflowRunIds( ` Repository: ${config.owner}/${config.repo}\n` + ` Branch Filter: ${branchMsg}\n` + ` Workflow ID: ${workflowId}\n` + + ` Created: ${createdFrom}\n` + ` Runs Fetched: [${runIds.join(", ")}]`, ); From 96e779d095a8c4aa415fccc43af5758160e6ea7c Mon Sep 17 00:00:00 2001 From: Alex Miller Date: Wed, 18 Jun 2025 10:31:05 +1200 Subject: [PATCH 5/5] feat: avoid reconstructing the Date instance --- dist/index.mjs | 10 ++++++---- src/api.ts | 4 ++-- src/return-dispatch.ts | 3 ++- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/dist/index.mjs b/dist/index.mjs index 8cb13e87..260b76af 100644 --- a/dist/index.mjs +++ b/dist/index.mjs @@ -24129,15 +24129,15 @@ async function fetchWorkflowRunUrl(runId) { throw error5; } } -async function fetchWorkflowRunIds(workflowId, branch, startTime) { +async function fetchWorkflowRunIds(workflowId, branch, startTimeISO) { try { const useBranchFilter = !branch.isTag && branch.branchName !== void 0 && branch.branchName !== ""; - const afterStartTime = ">" + new Date(startTime).toISOString(); + const createdFrom = `>=${startTimeISO}`; const response = await octokit.rest.actions.listWorkflowRuns({ owner: config.owner, repo: config.repo, workflow_id: workflowId, - created: afterStartTime, + created: createdFrom, event: "workflow_dispatch", ...useBranchFilter ? { branch: branch.branchName, @@ -24160,6 +24160,7 @@ async function fetchWorkflowRunIds(workflowId, branch, startTime) { Repository: ${config.owner}/${config.repo} Branch Filter: ${branchMsg} Workflow ID: ${workflowId} + Created: ${createdFrom} Runs Fetched: [${runIds.join(", ")}]` ); return runIds; @@ -24324,6 +24325,7 @@ async function getRunIdAndUrl({ workflowTimeoutMs, workflowJobStepsRetryMs }) { + const startTimeISO = new Date(startTime).toISOString(); const retryTimeout = Math.max( WORKFLOW_FETCH_TIMEOUT_MS, workflowTimeoutMs @@ -24333,7 +24335,7 @@ async function getRunIdAndUrl({ while (elapsedTime < workflowTimeoutMs) { attemptNo++; const fetchWorkflowRunIds2 = await retryOrTimeout( - () => fetchWorkflowRunIds(workflowId, branch, startTime), + () => fetchWorkflowRunIds(workflowId, branch, startTimeISO), retryTimeout ); if (!fetchWorkflowRunIds2.success) { diff --git a/src/api.ts b/src/api.ts index 799f32b1..e88d5767 100644 --- a/src/api.ts +++ b/src/api.ts @@ -158,7 +158,7 @@ export async function fetchWorkflowRunUrl(runId: number): Promise { export async function fetchWorkflowRunIds( workflowId: number, branch: BranchNameResult, - startTime: number, + startTimeISO: string, ): Promise { try { const useBranchFilter = @@ -166,7 +166,7 @@ export async function fetchWorkflowRunIds( branch.branchName !== undefined && branch.branchName !== ""; - const createdFrom = ">=" + new Date(startTime).toISOString(); + const createdFrom = `>=${startTimeISO}`; // https://docs.github.com/en/rest/actions/workflow-runs#list-workflow-runs-for-a-repository const response = await octokit.rest.actions.listWorkflowRuns({ diff --git a/src/return-dispatch.ts b/src/return-dispatch.ts index d2d76b2e..c5819587 100644 --- a/src/return-dispatch.ts +++ b/src/return-dispatch.ts @@ -139,6 +139,7 @@ export async function getRunIdAndUrl({ workflowTimeoutMs, workflowJobStepsRetryMs, }: GetRunIdAndUrlOpts): Promise> { + const startTimeISO = new Date(startTime).toISOString(); const retryTimeout = Math.max( constants.WORKFLOW_FETCH_TIMEOUT_MS, workflowTimeoutMs, @@ -151,7 +152,7 @@ export async function getRunIdAndUrl({ // Get all runs for a given workflow ID const fetchWorkflowRunIds = await api.retryOrTimeout( - () => api.fetchWorkflowRunIds(workflowId, branch, startTime), + () => api.fetchWorkflowRunIds(workflowId, branch, startTimeISO), retryTimeout, ); if (!fetchWorkflowRunIds.success) {