From 137b1a122c50622e14506d6b2c5133dda4043469 Mon Sep 17 00:00:00 2001 From: khaliqgant Date: Tue, 27 Oct 2026 00:47:00 -0700 Subject: [PATCH 1/2] ci(targeted-verification): let "Re-run failed jobs" find the shard selection The selection artifact was named with run_attempt, but "Re-run failed jobs" does not re-run the select job, so re-attempted shards looked for an artifact from the new attempt that was never uploaded and failed with "Artifact not found". Key the artifact by run_id only (earlier attempts' artifacts remain downloadable within the same run) and upload with overwrite: true so "Re-run all jobs" can replace it. Co-Authored-By: Claude Opus 5.5 (1M context) --- .github/workflows/targeted-feature-verification.yml | 10 ++++++++-- .../fixtures/targeted-feature-verification.test.ts | 13 +++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/.github/workflows/targeted-feature-verification.yml b/.github/workflows/targeted-feature-verification.yml index 8264f4fbfd..74608eabde 100644 --- a/.github/workflows/targeted-feature-verification.yml +++ b/.github/workflows/targeted-feature-verification.yml @@ -84,14 +84,20 @@ jobs: --max-command-seconds 720 echo "matrix=$(jq -c '.matrix' .workflow-artifacts/targeted-pr/shards/matrix.json)" >> "$GITHUB_OUTPUT" + # Keyed by run_id only (no run_attempt): "Re-run failed jobs" does not + # re-run this job, so a re-attempted shard must find the selection the + # original attempt uploaded. Artifacts from earlier attempts stay visible + # to later attempts of the same run. overwrite lets "Re-run all jobs" + # replace it; the selection is a pure function of the same base/head SHAs. - name: Upload immutable selection uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 with: - name: targeted-feature-selection-${{ github.run_id }}-${{ github.run_attempt }} + name: targeted-feature-selection-${{ github.run_id }} path: .workflow-artifacts/targeted-pr include-hidden-files: true if-no-files-found: error retention-days: 14 + overwrite: true targeted: if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository @@ -153,7 +159,7 @@ jobs: - name: Download immutable selection uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 with: - name: targeted-feature-selection-${{ github.run_id }}-${{ github.run_attempt }} + name: targeted-feature-selection-${{ github.run_id }} path: .workflow-artifacts/targeted-pr - name: Generate and check Flows v2 spec diff --git a/tests/fixtures/targeted-feature-verification.test.ts b/tests/fixtures/targeted-feature-verification.test.ts index ceea3ce12e..fc0baf7201 100644 --- a/tests/fixtures/targeted-feature-verification.test.ts +++ b/tests/fixtures/targeted-feature-verification.test.ts @@ -508,6 +508,19 @@ describe('targeted Flows v2 PR verification', () => { expect(workflow).toContain('matrix: ${{ fromJSON(needs.select.outputs.matrix) }}'); }); + it('keys the shard selection artifact by run so "Re-run failed jobs" can download it', async () => { + const workflow = await readFile('.github/workflows/targeted-feature-verification.yml', 'utf8'); + const selectionNames = workflow.match(/name: targeted-feature-selection-.*$/gm) ?? []; + // One upload (select job) and one download (each shard). + expect(selectionNames).toEqual([ + 'name: targeted-feature-selection-${{ github.run_id }}', + 'name: targeted-feature-selection-${{ github.run_id }}', + ]); + expect(workflow).toMatch( + /name: targeted-feature-selection-\$\{\{ github\.run_id \}\}\n(?:\s+.+\n)*?\s+overwrite: true/ + ); + }); + it('expands the broker binary template in a full-smoke spec', async () => { const directory = await mkdtemp(path.join(os.tmpdir(), 'relay-targeted-pr-broker-')); temporaryDirectories.push(directory); From 9fcdbdcb225f90fe620e272337187350b23a1f50 Mon Sep 17 00:00:00 2001 From: khaliqgant Date: Tue, 27 Oct 2026 01:02:18 -0700 Subject: [PATCH 2/2] test(targeted-verification): assert selection artifact via parsed steps Parse the workflow and check the upload/download steps directly so the overwrite assertion cannot match a different step. Co-Authored-By: Claude Opus 5.5 (1M context) --- .../targeted-feature-verification.test.ts | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/tests/fixtures/targeted-feature-verification.test.ts b/tests/fixtures/targeted-feature-verification.test.ts index fc0baf7201..b7cfff03aa 100644 --- a/tests/fixtures/targeted-feature-verification.test.ts +++ b/tests/fixtures/targeted-feature-verification.test.ts @@ -509,16 +509,17 @@ describe('targeted Flows v2 PR verification', () => { }); it('keys the shard selection artifact by run so "Re-run failed jobs" can download it', async () => { - const workflow = await readFile('.github/workflows/targeted-feature-verification.yml', 'utf8'); - const selectionNames = workflow.match(/name: targeted-feature-selection-.*$/gm) ?? []; - // One upload (select job) and one download (each shard). - expect(selectionNames).toEqual([ - 'name: targeted-feature-selection-${{ github.run_id }}', - 'name: targeted-feature-selection-${{ github.run_id }}', - ]); - expect(workflow).toMatch( - /name: targeted-feature-selection-\$\{\{ github\.run_id \}\}\n(?:\s+.+\n)*?\s+overwrite: true/ - ); + const workflow = parse(await readFile('.github/workflows/targeted-feature-verification.yml', 'utf8')); + const step = (job: string, name: string) => + workflow.jobs[job].steps.find((candidate: { name?: string }) => candidate.name === name); + const upload = step('select', 'Upload immutable selection'); + const download = step('targeted', 'Download immutable selection'); + + // No run_attempt: the select job is not re-run by "Re-run failed jobs". + expect(upload.with.name).toBe('targeted-feature-selection-${{ github.run_id }}'); + expect(download.with.name).toBe(upload.with.name); + // "Re-run all jobs" re-uploads the same name. + expect(upload.with.overwrite).toBe(true); }); it('expands the broker binary template in a full-smoke spec', async () => {