From 87527817a1b2b41000ba01b363b3dfd7bc8b7fb0 Mon Sep 17 00:00:00 2001 From: MauroFab Date: Mon, 13 Jul 2026 17:32:57 -0300 Subject: [PATCH] ci: bench workflows queue instead of cancelling each other MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All CPU bench workflows run on the single self-hosted `bench` runner, which already serializes them: jobs queue for the one runner. The workflows do not need `concurrency` to enforce ordering, and using it to cancel actively hurts. Three of them (bench-verify, bench-abba, profile-recursion) trigger on *every* `issue_comment` and keyed their concurrency group on the PR number alone, with `cancel-in-progress: true`. So any new comment on a PR — including one meant for a *different* command — re-triggered every one of these workflows. The new run entered the same per-PR group as the in-flight bench and cancelled it, even though the new run's job was immediately skipped by its `if:` command guard. Concretely: a `/profile_recursion` comment on a PR that had a `/bench-verify` benchmark running re-fired bench-verify.yml, which re-entered `bench-verify-` and cancelled the running verifier mid-measurement. Fix, in two parts: 1. `cancel-in-progress: false` on all five bench workflows (benchmark-pr and bench-vs-nightly included). Nothing should ever cancel a running bench; the runner is the serialization point. 2. Command-gated concurrency groups on the three comment-triggered workflows. The group is the real per-PR group only when the comment actually starts with that workflow's command; any other comment falls to a unique per-run throwaway group, so it can no longer sit in — or evict — the real queue. benchmark-pr's group is already unique per comment/push run (head_ref is empty for those events, so it falls to run_id), so only the cancel flag changed there; bench-vs-nightly likewise keeps its ref-keyed group. Intentional behavior change: re-issuing a command (e.g. a second `/bench-verify` on the same PR) now queues behind the running one instead of superseding it. --- .github/workflows/bench-abba.yml | 7 +++---- .github/workflows/bench-verify.yml | 10 +++++++--- .github/workflows/bench-vs-nightly.yml | 3 ++- .github/workflows/benchmark-pr.yml | 3 ++- .github/workflows/profile-recursion.yml | 5 +++-- 5 files changed, 17 insertions(+), 11 deletions(-) diff --git a/.github/workflows/bench-abba.yml b/.github/workflows/bench-abba.yml index b5f203698..8e8863c30 100644 --- a/.github/workflows/bench-abba.yml +++ b/.github/workflows/bench-abba.yml @@ -8,11 +8,10 @@ on: issue_comment: types: [created] -# One ABBA run per PR; a re-trigger cancels the stale one. (The single self-hosted -# bench runner serializes across PRs on its own.) concurrency: - group: bench-abba-${{ github.event.issue.number }} - cancel-in-progress: true + # See bench-verify.yml. The single self-hosted bench runner serializes across PRs. + group: ${{ startsWith(github.event.comment.body, '/bench-abba') && format('bench-abba-{0}', github.event.issue.number) || format('bench-abba-ignore-{0}', github.run_id) }} + cancel-in-progress: false permissions: contents: read diff --git a/.github/workflows/bench-verify.yml b/.github/workflows/bench-verify.yml index e35c5d4fc..e33808b06 100644 --- a/.github/workflows/bench-verify.yml +++ b/.github/workflows/bench-verify.yml @@ -5,10 +5,14 @@ on: issue_comment: types: [created] -# One verifier run per PR; a re-trigger cancels the stale one. concurrency: - group: bench-verify-${{ github.event.issue.number }} - cancel-in-progress: true + # Serialization is provided by the single self-hosted bench runner (jobs queue + # for it). Never cancel a running bench: real /bench-verify comments share the + # per-PR group and queue; any other comment (this workflow fires on every + # issue_comment) gets a unique throwaway group so it can't sit in — or evict — + # the real queue. + group: ${{ startsWith(github.event.comment.body, '/bench-verify') && format('bench-verify-{0}', github.event.issue.number) || format('bench-verify-ignore-{0}', github.run_id) }} + cancel-in-progress: false permissions: contents: read diff --git a/.github/workflows/bench-vs-nightly.yml b/.github/workflows/bench-vs-nightly.yml index 04d07a5e8..4315d8ab6 100644 --- a/.github/workflows/bench-vs-nightly.yml +++ b/.github/workflows/bench-vs-nightly.yml @@ -10,8 +10,9 @@ permissions: contents: read concurrency: + # Never cancel an in-flight nightly bench; the single bench runner serializes. group: bench-vs-nightly-${{ github.ref }} - cancel-in-progress: true + cancel-in-progress: false jobs: bench-vs: diff --git a/.github/workflows/benchmark-pr.yml b/.github/workflows/benchmark-pr.yml index 50ee28d71..fd74c7b3f 100644 --- a/.github/workflows/benchmark-pr.yml +++ b/.github/workflows/benchmark-pr.yml @@ -27,8 +27,9 @@ permissions: actions: read concurrency: + # Runner serializes; never cancel a running bench (group is already unique per run for comment/push events). group: benchmark-${{ github.head_ref || github.run_id }} - cancel-in-progress: true + cancel-in-progress: false env: # Headline program: the ethrex guest ELF proven against a 20-transfer block diff --git a/.github/workflows/profile-recursion.yml b/.github/workflows/profile-recursion.yml index 680741f15..5fc9817ba 100644 --- a/.github/workflows/profile-recursion.yml +++ b/.github/workflows/profile-recursion.yml @@ -15,8 +15,9 @@ permissions: pull-requests: write concurrency: - group: profile-recursion-${{ github.event.issue.number || github.run_id }} - cancel-in-progress: true + # See bench-verify.yml. workflow_dispatch (no comment) falls to the unique run_id group. + group: ${{ startsWith(github.event.comment.body, '/profile_recursion') && format('profile-recursion-{0}', github.event.issue.number) || format('profile-recursion-{0}', github.run_id) }} + cancel-in-progress: false jobs: # One job per configuration; they run in parallel and each uploads a Markdown