From 31f8aa57d529f6c77ec1a8b4856c6b38298fff9e Mon Sep 17 00:00:00 2001 From: Olivier Cots Date: Sat, 25 Jul 2026 12:34:41 +0200 Subject: [PATCH] ci: stop label-gated workflows from re-triggering on every subsequent label GitHub fires a separate pull_request 'labeled' event per label added, and re-evaluates each job's `if` condition against the PR's *current* full label set, not just the label that triggered this specific event. So adding several run-gating labels to a PR one after another re-runs every already-matching job on each subsequent label add, not just the newly-matched one. Fixed by checking github.event.label.name for 'labeled' events specifically, falling back to the existing full-label-set check for every other trigger type. Applied to: .github/workflows/CI.yml ('run ci'), .github/workflows/Documentation.yml ('run documentation'), and .github/workflows/Breakage.yml ('run breakage'). Co-Authored-By: Claude Sonnet 5 --- .github/workflows/Breakage.yml | 9 ++++++++- .github/workflows/CI.yml | 10 +++++++++- .github/workflows/Documentation.yml | 10 +++++++++- 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/.github/workflows/Breakage.yml b/.github/workflows/Breakage.yml index b6f65fda..7853e16e 100644 --- a/.github/workflows/Breakage.yml +++ b/.github/workflows/Breakage.yml @@ -9,7 +9,14 @@ on: jobs: call: - if: contains(github.event.pull_request.labels.*.name, 'run breakage') + # A 'labeled' event fires once per label added, and re-evaluates against the PR's + # *current* full label set — so adding several labels in a row would otherwise + # re-run this job on every subsequent label add. Only react to 'labeled' when it's + # this specific label; for other trigger types (synchronize/reopened), fall back to + # checking the current label set as before. + if: > + (github.event.action == 'labeled' && github.event.label.name == 'run breakage') || + (github.event.action != 'labeled' && contains(github.event.pull_request.labels.*.name, 'run breakage')) strategy: fail-fast: false matrix: diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 0d8fb2af..9e4dda0b 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -10,7 +10,15 @@ on: jobs: call: - if: github.event_name != 'pull_request' || contains(github.event.pull_request.labels.*.name, 'run ci') + # A 'labeled' event fires once per label added, and re-evaluates against the PR's + # *current* full label set — so adding several labels in a row would otherwise + # re-run this job on every subsequent label add. Only react to 'labeled' when it's + # this specific label; for other trigger types (synchronize/reopened), fall back to + # checking the current label set as before. + if: > + github.event_name != 'pull_request' || + (github.event.action == 'labeled' && github.event.label.name == 'run ci') || + (github.event.action != 'labeled' && contains(github.event.pull_request.labels.*.name, 'run ci')) uses: control-toolbox/CTActions/.github/workflows/ci.yml@main with: runs_on: '["ubuntu-latest","macos-latest"]' diff --git a/.github/workflows/Documentation.yml b/.github/workflows/Documentation.yml index 9c99dad2..b309e06b 100644 --- a/.github/workflows/Documentation.yml +++ b/.github/workflows/Documentation.yml @@ -11,7 +11,15 @@ on: jobs: call: - if: github.event_name != 'pull_request' || contains(github.event.pull_request.labels.*.name, 'run documentation') + # A 'labeled' event fires once per label added, and re-evaluates against the PR's + # *current* full label set — so adding several labels in a row would otherwise + # re-run this job on every subsequent label add. Only react to 'labeled' when it's + # this specific label; for other trigger types (synchronize/reopened), fall back to + # checking the current label set as before. + if: > + github.event_name != 'pull_request' || + (github.event.action == 'labeled' && github.event.label.name == 'run documentation') || + (github.event.action != 'labeled' && contains(github.event.pull_request.labels.*.name, 'run documentation')) uses: control-toolbox/CTActions/.github/workflows/documentation.yml@main with: use_ct_registry: true