From 4f0bb036800c170f2b52973ef920a8a4b3c1047e Mon Sep 17 00:00:00 2001 From: vlakoff <544424+vlakoff@users.noreply.github.com> Date: Thu, 30 Apr 2026 04:02:35 +0200 Subject: [PATCH] Isolate merge_group concurrency to prevent race conditions Implement a prefix-based concurrency group to ensure GitHub Merge Queue events are not prematurely cancelled by simultaneous push events. - Use 'mq-' prefix in concurrency keys for merge_group events to create isolated groups distinct from standard push events. - Maintain PR number in keys to allow synchronize events to cancel stale runs, preserving CI efficiency. - Simplify job filters to skip redundant push runs on internal merge queue branches. --- .github/workflows/docker.yml | 10 +++++++--- .github/workflows/oxipng.yml | 16 +++++++++------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 981fc7f8..b00b05eb 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -18,14 +18,18 @@ on: default: true concurrency: - group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.event.merge_group.head_ref || github.ref }} + group: >- + ${{ github.workflow }}- + ${{ github.event.pull_request.number || + (github.event_name == 'merge_group' && format('mq-{0}', github.event.merge_group.head_ref)) || + github.ref }} cancel-in-progress: true jobs: build: uses: docker/github-builder/.github/workflows/build.yml@v1 - # Exclude 'push' events from the Merge Queue to avoid a race condition where - # the 'push' event might cancel the 'merge_group' event via the concurrency group. + # Exclude 'push' events on Merge Queue branches, as they are already + # handled by the 'merge_group' event. if: (!(github.event_name == 'push' && startsWith(github.ref, 'refs/heads/gh-readonly-queue/'))) permissions: contents: read diff --git a/.github/workflows/oxipng.yml b/.github/workflows/oxipng.yml index e8dc31df..991fb062 100644 --- a/.github/workflows/oxipng.yml +++ b/.github/workflows/oxipng.yml @@ -9,7 +9,11 @@ on: workflow_dispatch: concurrency: - group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.event.merge_group.head_ref || github.ref }} + group: >- + ${{ github.workflow }}- + ${{ github.event.pull_request.number || + (github.event_name == 'merge_group' && format('mq-{0}', github.event.merge_group.head_ref)) || + github.ref }} cancel-in-progress: true jobs: @@ -20,9 +24,8 @@ jobs: timeout-minutes: 60 # Prevent tags and in-repo PRs from triggering this workflow more than once for a commit. - # We also exclude 'push' events from the Merge Queue (gh-readonly-queue/) because they - # trigger alongside the 'merge_group' event. Without this, a race condition in the - # concurrency group could cause the 'push' event to cancel the 'merge_group' event. + # We also exclude 'push' events on Merge Queue branches, as they are already + # handled by the 'merge_group' event. if: >- github.ref_type != 'tag' && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork) && @@ -161,9 +164,8 @@ jobs: timeout-minutes: 30 # Prevent tags and in-repo PRs from triggering this workflow more than once for a commit. - # We also exclude 'push' events from the Merge Queue (gh-readonly-queue/) because they - # trigger alongside the 'merge_group' event. Without this, a race condition in the - # concurrency group could cause the 'push' event to cancel the 'merge_group' event. + # We also exclude 'push' events on Merge Queue branches, as they are already + # handled by the 'merge_group' event. if: >- github.ref_type != 'tag' && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork) &&