diff --git a/src/github.test.ts b/src/github.test.ts index 5268d45..4dc24a0 100644 --- a/src/github.test.ts +++ b/src/github.test.ts @@ -337,7 +337,7 @@ describe("GitHub writes", () => { "--delete-branch", ]); }); - it("rerunFailedChecks posts to the newest run for the sha", async () => { + it("rerunFailedChecks posts to the newest failed run for the sha", async () => { const calls: string[][] = []; const gh = new GitHub(cfg, fakeExec(calls), false); const sha = "aaaa1111bbbb2222cccc3333dddd4444eeee5555"; @@ -345,7 +345,7 @@ describe("GitHub writes", () => { expect(calls[0]).toEqual([ "gh", "api", - `repos/${cfg.repo}/actions/runs?head_sha=${sha}&per_page=1`, + `repos/${cfg.repo}/actions/runs?head_sha=${sha}&status=failure&per_page=1`, "--jq", ".workflow_runs[0].id // empty", ]); @@ -357,7 +357,7 @@ describe("GitHub writes", () => { `repos/${cfg.repo}/actions/runs/77/rerun-failed-jobs`, ]); }); - it("rerunFailedChecks answers null when the commit has no run, and reruns nothing", async () => { + it("rerunFailedChecks answers null when the commit has no failed run, and reruns nothing", async () => { const calls: string[][] = []; const exec: Exec = async (cmd, args) => { calls.push([cmd, ...args]); diff --git a/src/github.ts b/src/github.ts index ef6650d..5564bf1 100644 --- a/src/github.ts +++ b/src/github.ts @@ -345,15 +345,18 @@ export class GitHub { } /** - * Reruns the failed jobs of the newest workflow run for `sha`, and answers with its run id (or - * null when GitHub has no run for that commit). REST rather than GraphQL on purpose: the + * Reruns the failed jobs of the newest FAILED workflow run for `sha`, and answers with its run id + * (or null when GitHub has no failed run for that commit). Filtered on `status=failure`, because + * the newest run for a sha is often a skipped or green workflow, and rerunning one of those is a + * 403 ("This workflow run cannot be retried") that threw before the ledger line was written, so + * the daemon retried it every tick. REST rather than GraphQL on purpose: the * tick's GraphQL budget is for the board reads, and this only fires on a red PR. */ async rerunFailedChecks(sha: string): Promise { const found = ( await this.gh([ "api", - `repos/${this.cfg.repo}/actions/runs?head_sha=${sha}&per_page=1`, + `repos/${this.cfg.repo}/actions/runs?head_sha=${sha}&status=failure&per_page=1`, "--jq", ".workflow_runs[0].id // empty", ])