From 67f2640df6de4806113d3ce47fec69394b4745f3 Mon Sep 17 00:00:00 2001 From: Noam Cohen Date: Tue, 22 Sep 2026 11:12:41 +0200 Subject: [PATCH 1/2] List only the current attempt's jobs in the SEC regression summary The summary job listed the jobs of every attempt of its run. After a few re-runs that listing spans several pages, and GitHub's API answers some of those pages with a persistent 502, so every re-run of the summary failed (main run #335, four attempts). Listing the current attempt returns every job of the run in a listing that paginates cleanly. Jobs carried over from earlier attempts keep their own run_attempt, which summarize_sec_regress.py already uses to pick the latest attempt of each job and its result artifact. --- .github/workflows/regress-sec.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/regress-sec.yml b/.github/workflows/regress-sec.yml index 0d256e1d..768f7248 100644 --- a/.github/workflows/regress-sec.yml +++ b/.github/workflows/regress-sec.yml @@ -831,10 +831,14 @@ jobs: script: | const fs = require('fs'); const path = require('path'); - const jobs = await github.paginate(github.rest.actions.listJobsForWorkflowRun, { + // Listing every attempt of a re-run run (filter: 'all') fails with a + // persistent 502 from the API once the run has several attempts, so + // only the current attempt is listed. Jobs carried over from earlier + // attempts keep their own run_attempt, which the summary honours. + const jobs = await github.paginate(github.rest.actions.listJobsForWorkflowRunAttempt, { ...context.repo, run_id: context.runId, - filter: 'all', + attempt_number: Number(process.env.GITHUB_RUN_ATTEMPT), per_page: 100, }); fs.writeFileSync(path.join(process.env.RUNNER_TEMP, 'sec-jobs.json'), JSON.stringify(jobs)); From 9026210a50c5390d531627fe9cbd1da605885611 Mon Sep 17 00:00:00 2001 From: Noam Cohen Date: Tue, 22 Sep 2026 11:36:36 +0200 Subject: [PATCH 2/2] List each attempt separately in the SEC regression summary Listing only the current attempt would look up every job under that attempt number, but after a re-run of failed jobs the unchanged jobs ran, and stored their results, under an earlier attempt. The step now lists attempts 1 through the current one. A job appears from the attempt it ran in onward, so its first appearance gives that attempt, and the summary keeps each job's latest attempt and reads the matching result artifact. Jobs re-run in different attempts are therefore each taken from their own last run. --- .github/workflows/regress-sec.yml | 32 ++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/.github/workflows/regress-sec.yml b/.github/workflows/regress-sec.yml index 768f7248..83fa2c72 100644 --- a/.github/workflows/regress-sec.yml +++ b/.github/workflows/regress-sec.yml @@ -831,17 +831,27 @@ jobs: script: | const fs = require('fs'); const path = require('path'); - // Listing every attempt of a re-run run (filter: 'all') fails with a - // persistent 502 from the API once the run has several attempts, so - // only the current attempt is listed. Jobs carried over from earlier - // attempts keep their own run_attempt, which the summary honours. - const jobs = await github.paginate(github.rest.actions.listJobsForWorkflowRunAttempt, { - ...context.repo, - run_id: context.runId, - attempt_number: Number(process.env.GITHUB_RUN_ATTEMPT), - per_page: 100, - }); - fs.writeFileSync(path.join(process.env.RUNNER_TEMP, 'sec-jobs.json'), JSON.stringify(jobs)); + // Listing every attempt at once (filter: 'all') fails with a persistent + // 502 from the API once a run has several attempts, so the attempts + // are listed one by one. A job appears from the attempt it ran in + // onward, so its first appearance is its attempt; the summary then + // keeps the latest attempt of each job and its result artifact. + const attempts = Number(process.env.GITHUB_RUN_ATTEMPT); + const jobsById = new Map(); + for (let attempt = 1; attempt <= attempts; attempt++) { + const jobs = await github.paginate(github.rest.actions.listJobsForWorkflowRunAttempt, { + ...context.repo, + run_id: context.runId, + attempt_number: attempt, + per_page: 100, + }); + for (const job of jobs) { + if (!jobsById.has(job.id)) { + jobsById.set(job.id, { ...job, run_attempt: attempt }); + } + } + } + fs.writeFileSync(path.join(process.env.RUNNER_TEMP, 'sec-jobs.json'), JSON.stringify([...jobsById.values()])); - name: Download regression results id: results