From cf763073d3048ad1f3daed901d28b92b0bbef649 Mon Sep 17 00:00:00 2001 From: dhruv8sh Date: Tue, 20 Oct 2026 23:42:10 +0530 Subject: [PATCH 1/2] Queue pull request CI runs per author and workflow One author opening or pushing many pull requests could fill the runner queue and delay everyone else. Each PR-triggered workflow now uses a concurrency group keyed on the workflow and the actor, so an author has one run in progress per workflow while the rest wait in order (queue: max) rather than being cancelled. Pushes to main, scheduled runs and manual dispatches fall back to the run ID and are never held back. Signed-off-by: dhruv8sh --- .github/workflows/codeql.yml | 9 +++++++++ .github/workflows/format.yml | 9 +++++++++ .github/workflows/integration-tests.yml | 9 +++++++++ .github/workflows/pbs-example.yml | 9 +++++++++ .github/workflows/test.yml | 9 +++++++++ 5 files changed, 45 insertions(+) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 4b963e0153..0a03f49e82 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -19,6 +19,15 @@ on: schedule: - cron: "42 6 * * 0" +# Each author runs one pull request at a time per workflow, so one person +# pushing many PRs cannot fill the runner queue ahead of everyone else. Their +# other runs wait in order instead of being cancelled. Other events get their +# own group from the run ID and are never held back. +concurrency: + group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.actor || github.run_id }} + cancel-in-progress: false + queue: max + jobs: analyze: name: Analyze (${{ matrix.language }}) diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml index f458572eb7..be6543b5d0 100644 --- a/.github/workflows/format.yml +++ b/.github/workflows/format.yml @@ -8,6 +8,15 @@ on: permissions: contents: read +# Each author runs one pull request at a time per workflow, so one person +# pushing many PRs cannot fill the runner queue ahead of everyone else. Their +# other runs wait in order instead of being cancelled. Other events get their +# own group from the run ID and are never held back. +concurrency: + group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.actor || github.run_id }} + cancel-in-progress: false + queue: max + jobs: check-claude-md-symlink: name: CLAUDE.md symlink guard diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 157a3582d3..d5cf97b726 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -10,6 +10,15 @@ on: types: [opened, synchronize, reopened] workflow_dispatch: +# Each author runs one pull request at a time per workflow, so one person +# pushing many PRs cannot fill the runner queue ahead of everyone else. Their +# other runs wait in order instead of being cancelled. Other events get their +# own group from the run ID and are never held back. +concurrency: + group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.actor || github.run_id }} + cancel-in-progress: false + queue: max + env: ORIGIN_PORT: 8888 ARTIFACTS_DIR: /tmp/integration-test-artifacts diff --git a/.github/workflows/pbs-example.yml b/.github/workflows/pbs-example.yml index dced0c7b63..ca3245d0c0 100644 --- a/.github/workflows/pbs-example.yml +++ b/.github/workflows/pbs-example.yml @@ -17,6 +17,15 @@ on: permissions: contents: read +# Each author runs one pull request at a time per workflow, so one person +# pushing many PRs cannot fill the runner queue ahead of everyone else. Their +# other runs wait in order instead of being cancelled. Other events get their +# own group from the run ID and are never held back. +concurrency: + group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.actor || github.run_id }} + cancel-in-progress: false + queue: max + jobs: local-checks: name: PBS Terraform and Compose checks diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b27173dd66..777578bb36 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -8,6 +8,15 @@ on: branches: [main] pull_request: +# Each author runs one pull request at a time per workflow, so one person +# pushing many PRs cannot fill the runner queue ahead of everyone else. Their +# other runs wait in order instead of being cancelled. Other events get their +# own group from the run ID and are never held back. +concurrency: + group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.actor || github.run_id }} + cancel-in-progress: false + queue: max + jobs: test-rust: name: cargo test From 68e005b052c96754a5e5fc8f8a94000c56999e58 Mon Sep 17 00:00:00 2001 From: dhruv8sh Date: Wed, 21 Oct 2026 00:47:36 +0530 Subject: [PATCH 2/2] Key the CI queue on the PR author and add job timeouts Group pull request runs by the PR author instead of the triggering actor, so a maintainer pushing to or updating contributors' branches does not pile those runs into the maintainer's queue. Bot-authored PRs fall back to the run ID so a Dependabot batch is not serialized. Give every job in the queued workflows a timeout of roughly three times its longest recent run, so a hung job cannot hold an author's queue for GitHub's six-hour default. Signed-off-by: dhruv8sh --- .github/workflows/codeql.yml | 12 +++++++----- .github/workflows/format.yml | 16 +++++++++++----- .github/workflows/integration-tests.yml | 11 ++++++----- .github/workflows/pbs-example.yml | 11 ++++++----- .github/workflows/test.yml | 17 ++++++++++++----- 5 files changed, 42 insertions(+), 25 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 0a03f49e82..09f03e0e0a 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -19,12 +19,13 @@ on: schedule: - cron: "42 6 * * 0" -# Each author runs one pull request at a time per workflow, so one person -# pushing many PRs cannot fill the runner queue ahead of everyone else. Their -# other runs wait in order instead of being cancelled. Other events get their -# own group from the run ID and are never held back. +# Each pull request author runs one PR at a time per workflow, so one person +# opening many PRs cannot fill the runner queue ahead of everyone else. Their +# other runs wait in order instead of being cancelled, and every job has a +# timeout so a hung run cannot hold that queue for hours. Bot-authored PRs and +# other events get their own group from the run ID and are never held back. concurrency: - group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.actor || github.run_id }} + group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.event.pull_request.user.type != 'Bot' && github.event.pull_request.user.login || github.run_id }} cancel-in-progress: false queue: max @@ -37,6 +38,7 @@ jobs: # - https://gh.io/using-larger-runners (GitHub.com only) # Consider using larger runners or machines with greater resources for possible analysis time improvements. runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }} + timeout-minutes: 45 permissions: # required for all workflows security-events: write diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml index be6543b5d0..7de102c2de 100644 --- a/.github/workflows/format.yml +++ b/.github/workflows/format.yml @@ -8,12 +8,13 @@ on: permissions: contents: read -# Each author runs one pull request at a time per workflow, so one person -# pushing many PRs cannot fill the runner queue ahead of everyone else. Their -# other runs wait in order instead of being cancelled. Other events get their -# own group from the run ID and are never held back. +# Each pull request author runs one PR at a time per workflow, so one person +# opening many PRs cannot fill the runner queue ahead of everyone else. Their +# other runs wait in order instead of being cancelled, and every job has a +# timeout so a hung run cannot hold that queue for hours. Bot-authored PRs and +# other events get their own group from the run ID and are never held back. concurrency: - group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.actor || github.run_id }} + group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.event.pull_request.user.type != 'Bot' && github.event.pull_request.user.login || github.run_id }} cancel-in-progress: false queue: max @@ -21,6 +22,7 @@ jobs: check-claude-md-symlink: name: CLAUDE.md symlink guard runs-on: ubuntu-latest + timeout-minutes: 5 steps: - uses: actions/checkout@v4 @@ -51,6 +53,7 @@ jobs: format-rust: name: cargo fmt runs-on: ubuntu-latest + timeout-minutes: 25 steps: - uses: actions/checkout@v4 @@ -112,6 +115,7 @@ jobs: format-typescript: runs-on: ubuntu-latest + timeout-minutes: 10 defaults: run: working-directory: crates/trusted-server-js/lib @@ -143,6 +147,7 @@ jobs: format-docs: runs-on: ubuntu-latest + timeout-minutes: 10 defaults: run: working-directory: docs @@ -184,6 +189,7 @@ jobs: docs-proposal-scripts: name: docs-proposal scripts runs-on: ubuntu-latest + timeout-minutes: 10 steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index d5cf97b726..2346f5a525 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -10,12 +10,13 @@ on: types: [opened, synchronize, reopened] workflow_dispatch: -# Each author runs one pull request at a time per workflow, so one person -# pushing many PRs cannot fill the runner queue ahead of everyone else. Their -# other runs wait in order instead of being cancelled. Other events get their -# own group from the run ID and are never held back. +# Each pull request author runs one PR at a time per workflow, so one person +# opening many PRs cannot fill the runner queue ahead of everyone else. Their +# other runs wait in order instead of being cancelled, and every job has a +# timeout so a hung run cannot hold that queue for hours. Bot-authored PRs and +# other events get their own group from the run ID and are never held back. concurrency: - group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.actor || github.run_id }} + group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.event.pull_request.user.type != 'Bot' && github.event.pull_request.user.login || github.run_id }} cancel-in-progress: false queue: max diff --git a/.github/workflows/pbs-example.yml b/.github/workflows/pbs-example.yml index ca3245d0c0..2c1fb07303 100644 --- a/.github/workflows/pbs-example.yml +++ b/.github/workflows/pbs-example.yml @@ -17,12 +17,13 @@ on: permissions: contents: read -# Each author runs one pull request at a time per workflow, so one person -# pushing many PRs cannot fill the runner queue ahead of everyone else. Their -# other runs wait in order instead of being cancelled. Other events get their -# own group from the run ID and are never held back. +# Each pull request author runs one PR at a time per workflow, so one person +# opening many PRs cannot fill the runner queue ahead of everyone else. Their +# other runs wait in order instead of being cancelled, and every job has a +# timeout so a hung run cannot hold that queue for hours. Bot-authored PRs and +# other events get their own group from the run ID and are never held back. concurrency: - group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.actor || github.run_id }} + group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.event.pull_request.user.type != 'Bot' && github.event.pull_request.user.login || github.run_id }} cancel-in-progress: false queue: max diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 777578bb36..0514afee2f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -8,12 +8,13 @@ on: branches: [main] pull_request: -# Each author runs one pull request at a time per workflow, so one person -# pushing many PRs cannot fill the runner queue ahead of everyone else. Their -# other runs wait in order instead of being cancelled. Other events get their -# own group from the run ID and are never held back. +# Each pull request author runs one PR at a time per workflow, so one person +# opening many PRs cannot fill the runner queue ahead of everyone else. Their +# other runs wait in order instead of being cancelled, and every job has a +# timeout so a hung run cannot hold that queue for hours. Bot-authored PRs and +# other events get their own group from the run ID and are never held back. concurrency: - group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.actor || github.run_id }} + group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.event.pull_request.user.type != 'Bot' && github.event.pull_request.user.login || github.run_id }} cancel-in-progress: false queue: max @@ -77,6 +78,7 @@ jobs: test-axum: name: cargo test (axum native) runs-on: ubuntu-latest + timeout-minutes: 30 steps: - uses: actions/checkout@v4 @@ -125,6 +127,7 @@ jobs: test-cloudflare: name: cargo check (cloudflare native + wasm32-unknown-unknown) runs-on: ubuntu-latest + timeout-minutes: 15 steps: - uses: actions/checkout@v4 @@ -146,6 +149,7 @@ jobs: test-spin: name: cargo check/build/test (spin native + wasm32-wasip1) runs-on: ubuntu-latest + timeout-minutes: 20 steps: - uses: actions/checkout@v4 @@ -179,6 +183,7 @@ jobs: test-parity: name: cargo test (cross-adapter parity) runs-on: ubuntu-latest + timeout-minutes: 15 steps: - uses: actions/checkout@v4 @@ -204,6 +209,7 @@ jobs: matrix: os: [ubuntu-latest, macos-latest] runs-on: ${{ matrix.os }} + timeout-minutes: 45 steps: - uses: actions/checkout@v4 @@ -268,6 +274,7 @@ jobs: test-typescript: name: vitest runs-on: ubuntu-latest + timeout-minutes: 10 defaults: run: working-directory: crates/trusted-server-js/lib