From 9833b47b3357b411b7af02f25dcd99a85aa5dec9 Mon Sep 17 00:00:00 2001 From: hyperpolymath <6759885+hyperpolymath@users.noreply.github.com> Date: Mon, 18 May 2026 08:15:42 +0100 Subject: [PATCH] fix(ci): add concurrency dedup + tighten over-broad triggers (Refs #77) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cause-B mitigation for the CI jam: every push fanned out 20+ workflows with zero concurrency control, so stacked pushes piled identical jobs into a queue that the saturated personal-account runner pool never drained. - Add `concurrency: { group: - }` to every workflow that lacked one (hypatia-scan.yml already had the canonical block). cancel-in-progress: true for push/PR CI gates (rust-ci, codeql, governance, mvp-smoke, live-provers, dogfood-gate, cargo-audit, secret-scanner, security-scan, formal-verification, agda-meta-checker, idris2-abi-ci, chapel-ci, cflite_pr); cancel-in-progress: false for mirror/sync/publish/scorecard so an in-flight mirror, image publish or security scan is never aborted mid-run. - Narrow two over-broad triggers (no gate disabled, all still fire): - governance.yml: pull_request was unscoped (fired on PRs to every branch) -> branches: [main, master], matching the other gates. - container-ci.yml: push was any-branch (path-filtered only) -> branches: [main, master], so feature-branch pushes touching those paths no longer also fan out a container build. Security/governance gates are unchanged in scope — this only removes redundant concurrent duplicates and obviously over-broad fan-out. The residual cause (GitHub-hosted Actions concurrency/spending cap on the personal account) is org-admin/billing-gated and tracked on #77. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/agda-meta-checker.yml | 6 ++++++ .github/workflows/boj-build.yml | 7 +++++++ .github/workflows/cargo-audit.yml | 6 ++++++ .github/workflows/cflite_pr.yml | 6 ++++++ .github/workflows/chapel-ci.yml | 6 ++++++ .github/workflows/codeql.yml | 6 ++++++ .github/workflows/container-ci.yml | 11 +++++++++++ .github/workflows/dogfood-gate.yml | 6 ++++++ .github/workflows/formal-verification.yml | 6 ++++++ .github/workflows/ghcr-publish.yml | 6 ++++++ .github/workflows/governance.yml | 9 +++++++++ .github/workflows/idris2-abi-ci.yml | 6 ++++++ .github/workflows/instant-sync.yml | 6 ++++++ .github/workflows/live-provers.yml | 6 ++++++ .github/workflows/mirror.yml | 7 +++++++ .github/workflows/mvp-smoke.yml | 6 ++++++ .github/workflows/rust-ci.yml | 6 ++++++ .github/workflows/scorecard-enforcer.yml | 6 ++++++ .github/workflows/scorecard.yml | 6 ++++++ .github/workflows/secret-scanner.yml | 6 ++++++ .github/workflows/security-scan.yml | 6 ++++++ 21 files changed, 136 insertions(+) diff --git a/.github/workflows/agda-meta-checker.yml b/.github/workflows/agda-meta-checker.yml index 67a2e981..34c43fc0 100644 --- a/.github/workflows/agda-meta-checker.yml +++ b/.github/workflows/agda-meta-checker.yml @@ -15,6 +15,12 @@ on: - 'meta-checker/**' workflow_dispatch: +# Cause-B mitigation (#77): cancel superseded runs so stacked pushes +# to the same ref don't pile up identical jobs in the queue. +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + permissions: contents: read diff --git a/.github/workflows/boj-build.yml b/.github/workflows/boj-build.yml index 410dc3cf..2af22d6e 100644 --- a/.github/workflows/boj-build.yml +++ b/.github/workflows/boj-build.yml @@ -4,6 +4,13 @@ on: push: branches: [main, master] workflow_dispatch: + +# Cause-B mitigation (#77): de-duplicate stacked BoJ build triggers. +# cancel-in-progress is false so an in-flight dispatch always completes. +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: false + jobs: trigger-boj: runs-on: ubuntu-latest diff --git a/.github/workflows/cargo-audit.yml b/.github/workflows/cargo-audit.yml index 19424271..2272b067 100644 --- a/.github/workflows/cargo-audit.yml +++ b/.github/workflows/cargo-audit.yml @@ -14,6 +14,12 @@ on: # Run weekly on Monday at 06:00 UTC to catch new advisories. - cron: '0 6 * * 1' +# Cause-B mitigation (#77): cancel superseded runs so stacked pushes +# to the same ref don't pile up identical jobs in the queue. +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + permissions: contents: read diff --git a/.github/workflows/cflite_pr.yml b/.github/workflows/cflite_pr.yml index d5216a6c..fc44ba1c 100644 --- a/.github/workflows/cflite_pr.yml +++ b/.github/workflows/cflite_pr.yml @@ -4,6 +4,12 @@ on: pull_request: branches: [main] +# Cause-B mitigation (#77): cancel superseded fuzzing runs so rapid +# PR pushes don't pile up identical jobs in the queue. +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + permissions: contents: read diff --git a/.github/workflows/chapel-ci.yml b/.github/workflows/chapel-ci.yml index 9d81f4f9..74082d06 100644 --- a/.github/workflows/chapel-ci.yml +++ b/.github/workflows/chapel-ci.yml @@ -19,6 +19,12 @@ on: - 'Cargo.toml' - '.github/workflows/chapel-ci.yml' +# Cause-B mitigation (#77): cancel superseded runs so stacked pushes +# to the same ref don't pile up identical jobs in the queue. +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + permissions: read-all jobs: diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 9e41a5c2..1bc5d916 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -9,6 +9,12 @@ on: schedule: - cron: '0 6 * * 1' +# Cause-B mitigation (#77): cancel superseded runs so stacked pushes +# to the same ref don't pile up identical jobs in the queue. +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + permissions: contents: read diff --git a/.github/workflows/container-ci.yml b/.github/workflows/container-ci.yml index 778bf92e..18c8e917 100644 --- a/.github/workflows/container-ci.yml +++ b/.github/workflows/container-ci.yml @@ -13,6 +13,10 @@ name: Container Build Verification on: push: + # Cause-B mitigation (#77): was any-branch (path-filtered only); + # scoped to integration branches so feature-branch pushes that + # touch these paths don't also fan out a container build. + branches: [main, master] paths: - 'Containerfile' - '.containerization/**' @@ -34,6 +38,13 @@ on: # so the container build does not race the live-prover tests. - cron: '0 6 * * 0' +# Cause-B mitigation (#77): de-duplicate superseded builds on the same +# ref. cancel-in-progress is false so an in-flight image build/publish +# is never interrupted mid-push. +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: false + permissions: contents: read diff --git a/.github/workflows/dogfood-gate.yml b/.github/workflows/dogfood-gate.yml index 501ee675..cbd17c29 100644 --- a/.github/workflows/dogfood-gate.yml +++ b/.github/workflows/dogfood-gate.yml @@ -12,6 +12,12 @@ on: push: branches: [main, master] +# Cause-B mitigation (#77): cancel superseded runs so stacked pushes +# to the same ref don't pile up identical jobs in the queue. +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + permissions: contents: read diff --git a/.github/workflows/formal-verification.yml b/.github/workflows/formal-verification.yml index f7a5c6e0..50c0e13c 100644 --- a/.github/workflows/formal-verification.yml +++ b/.github/workflows/formal-verification.yml @@ -29,6 +29,12 @@ on: paths: - 'crates/echidna-core-spark/**' +# Cause-B mitigation (#77): cancel superseded runs so stacked pushes +# to the same ref don't pile up identical jobs in the queue. +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + permissions: contents: read diff --git a/.github/workflows/ghcr-publish.yml b/.github/workflows/ghcr-publish.yml index 0301fc0c..aa670754 100644 --- a/.github/workflows/ghcr-publish.yml +++ b/.github/workflows/ghcr-publish.yml @@ -9,6 +9,12 @@ on: types: [published] workflow_dispatch: +# Cause-B mitigation (#77): de-duplicate stacked publish runs. +# cancel-in-progress is false — never abort an image publish in flight. +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: false + env: REGISTRY: ghcr.io IMAGE_NAME: ${{ github.repository }} diff --git a/.github/workflows/governance.yml b/.github/workflows/governance.yml index 76bd1a0e..f40c2770 100644 --- a/.github/workflows/governance.yml +++ b/.github/workflows/governance.yml @@ -16,8 +16,17 @@ on: push: branches: [main, master] pull_request: + # Cause-B mitigation (#77): was unscoped (fired on PRs to every + # branch); narrowed to integration branches like the other gates. + branches: [main, master] workflow_dispatch: +# Cause-B mitigation (#77): cancel superseded runs so stacked pushes +# to the same ref don't pile up identical jobs in the queue. +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + permissions: contents: read diff --git a/.github/workflows/idris2-abi-ci.yml b/.github/workflows/idris2-abi-ci.yml index 2367c0c2..75dfaf0d 100644 --- a/.github/workflows/idris2-abi-ci.yml +++ b/.github/workflows/idris2-abi-ci.yml @@ -11,6 +11,12 @@ on: - 'src/abi/**' - '.github/workflows/idris2-abi-ci.yml' +# Cause-B mitigation (#77): cancel superseded runs so stacked pushes +# to the same ref don't pile up identical jobs in the queue. +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + permissions: read-all jobs: diff --git a/.github/workflows/instant-sync.yml b/.github/workflows/instant-sync.yml index e900c7e7..8acfc98c 100644 --- a/.github/workflows/instant-sync.yml +++ b/.github/workflows/instant-sync.yml @@ -8,6 +8,12 @@ on: release: types: [published] +# Cause-B mitigation (#77): de-duplicate stacked sync runs. +# cancel-in-progress is false so an in-flight sync always completes. +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: false + permissions: contents: read diff --git a/.github/workflows/live-provers.yml b/.github/workflows/live-provers.yml index f75cb4a9..58489001 100644 --- a/.github/workflows/live-provers.yml +++ b/.github/workflows/live-provers.yml @@ -33,6 +33,12 @@ on: required: false default: '1' +# Cause-B mitigation (#77): cancel superseded runs so stacked pushes +# to the same ref don't pile up identical jobs in the queue. +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + permissions: contents: read diff --git a/.github/workflows/mirror.yml b/.github/workflows/mirror.yml index 408093be..8ea1f420 100644 --- a/.github/workflows/mirror.yml +++ b/.github/workflows/mirror.yml @@ -7,6 +7,13 @@ on: branches: [main] workflow_dispatch: +# Cause-B mitigation (#77): de-duplicate stacked mirror runs. +# cancel-in-progress is false so an in-flight mirror push always +# completes (a half-cancelled mirror could leave the remote stale). +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: false + permissions: contents: read diff --git a/.github/workflows/mvp-smoke.yml b/.github/workflows/mvp-smoke.yml index d027be7b..b111d7d3 100644 --- a/.github/workflows/mvp-smoke.yml +++ b/.github/workflows/mvp-smoke.yml @@ -7,6 +7,12 @@ on: pull_request: branches: [main] +# Cause-B mitigation (#77): cancel superseded runs so stacked pushes +# to the same ref don't pile up identical jobs in the queue. +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + permissions: contents: read diff --git a/.github/workflows/rust-ci.yml b/.github/workflows/rust-ci.yml index ecf8b0ad..d8e65689 100644 --- a/.github/workflows/rust-ci.yml +++ b/.github/workflows/rust-ci.yml @@ -7,6 +7,12 @@ on: pull_request: branches: [main] +# Cause-B mitigation (#77): cancel superseded runs so stacked pushes +# to the same ref don't pile up identical jobs in the queue. +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + permissions: contents: read diff --git a/.github/workflows/scorecard-enforcer.yml b/.github/workflows/scorecard-enforcer.yml index 26322c95..f7c7176c 100644 --- a/.github/workflows/scorecard-enforcer.yml +++ b/.github/workflows/scorecard-enforcer.yml @@ -9,6 +9,12 @@ on: - cron: '0 6 * * 1' # Weekly on Monday workflow_dispatch: +# Cause-B mitigation (#77): de-duplicate stacked enforcer runs. +# cancel-in-progress is false — never abort a governance gate in flight. +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: false + permissions: contents: read diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 1e453663..f00884ef 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -6,6 +6,12 @@ on: schedule: - cron: '0 4 * * *' +# Cause-B mitigation (#77): de-duplicate stacked scorecard runs. +# cancel-in-progress is false — never abort a security scan in flight. +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: false + permissions: contents: read diff --git a/.github/workflows/secret-scanner.yml b/.github/workflows/secret-scanner.yml index 352ab8dc..dfff18e7 100644 --- a/.github/workflows/secret-scanner.yml +++ b/.github/workflows/secret-scanner.yml @@ -7,6 +7,12 @@ on: push: branches: [main] +# Cause-B mitigation (#77): cancel superseded runs so stacked pushes +# to the same ref don't pile up identical jobs in the queue. +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + permissions: contents: read diff --git a/.github/workflows/security-scan.yml b/.github/workflows/security-scan.yml index a7b5fc88..e29eb30c 100644 --- a/.github/workflows/security-scan.yml +++ b/.github/workflows/security-scan.yml @@ -9,6 +9,12 @@ on: - cron: '0 0 * * 0' # Weekly on Sunday at midnight workflow_dispatch: +# Cause-B mitigation (#77): cancel superseded runs so stacked pushes +# to the same ref don't pile up identical jobs in the queue. +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + permissions: contents: read