Repository navigation
Conversation
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 <dhruv8sh@proton.me>
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 <dhruv8sh@proton.me>
prk-Jr
left a comment
There was a problem hiding this comment.
Summary
Reviewed all five changed workflows at 3d448f910c2c0445b979441452b29d401074d42d, including job dependencies, matrices, shared setup, triggers, permissions and concurrency policies. No blocking defects found; the implementation matches issue #1425. Author rather than actor grouping correctly handles maintainer updates, and all 18 job definitions have explicit timeouts.
Non-blocking observations
-
🤔 Workflow limits do not guarantee runner fairness — The concurrency block in
.github/workflows/test.yml:16–19admits one workflow run per author, but that run can launch eight jobs. Format and CodeQL can launch another eight simultaneously, alongside integration jobs. This substantially reduces burst multiplication, but still permits significant runner occupancy by one author. Measure contention after rollout before adding further serialization. -
📝 Clarify queue capacity and ordering — The repeated comments in the five workflows say queued runs are preserved and run in order. GitHub permits 100 pending runs per group, then cancels additional arrivals. FIFO follows when runs begin waiting on the concurrency group, rather than workflow dispatch order. Consider documenting those qualifications in the shared wording and PR description. See GitHub concurrency documentation. Apply manually: this clarification spans five workflow files.
-
🏕 Retain the policy verification script — The PR describes useful expression checks with
act, but the verification script is not included in the change. Keeping it in the repository would help catch drift across the five duplicated policies. Cover author versus actor, bots, non-PR events, group separation and timeout presence. Apply manually: retaining the script introduces a new file.
Suggested follow-up
Retain this author-level cap, then separately consider cancelling superseded runs within the same PR. That would reduce obsolete work while preserving the cap across different PRs. Any privileged cancellation workflow should manipulate Actions metadata without checking out or executing contributor code. Stale-run queueing is explicitly acknowledged in this PR and is not a blocker.
Validation
Local YAML/policy assertions passed for all five identical concurrency policies and all 18 job definitions; git diff --check passed. Local actionlint reported its outdated schema for queue and shell warnings on unchanged lines. Current GitHub documentation confirms queue: max is supported. Rust/JS suites were not rerun locally for this workflow-only change, and the reported live multi-PR experiment was not independently reproduced.
CI Status
- browser integration tests: PASS
- integration tests (Fastly EC lifecycle): PASS
- integration tests: PASS
- CodeQL: PASS
- cargo test (ts CLI, native) (macos-latest): PASS
- Analyze (actions): PASS
- cargo check (cloudflare native + wasm32-unknown-unknown): PASS
- Analyze (javascript-typescript): PASS
- cargo test (axum native): PASS
- docs-proposal scripts: PASS
- format-docs: PASS (required)
- Analyze (rust): PASS
- prepare integration artifacts: PASS
- format-typescript: PASS (required)
- cargo test: PASS (required)
- CLAUDE.md symlink guard: PASS
- cargo fmt: PASS (required)
- cargo check/build/test (spin native + wasm32-wasip1): PASS
- vitest: PASS
- cargo test (cross-adapter parity): PASS
- cargo test (ts CLI, native) (ubuntu-latest): PASS
- PBS Terraform and Compose checks: PASS
- Analyze (javascript-typescript): PASS
- Analyze (python): PASS
ChristianPavilonis
left a comment
There was a problem hiding this comment.
Approved. Queuing PR CI runs per author and workflow, with bounded job timeouts and independent groups for bots and non-PR runs, is a focused improvement to shared runner fairness.
aram356
left a comment
There was a problem hiding this comment.
Summary
This adds a per-PR-author concurrency group with queue: max to the five PR-triggered workflows, and a timeout-minutes on every job. The timeouts hold up against the last 400 runs of each workflow and against the cold runs after the Rust 1.98.1 upgrade. Two things block: without superseded-run cancellation, the per-author queue delays required checks by hours and can hit the 100-pending cap, and nothing keeps the new invariants in place as open PRs land.
1 of the inline comments below carries a one-click GitHub
suggestion— use Commit suggestion to apply it as a commit on the PR branch. The remaining comments describe the fix in prose because the change touches multiple files or lines outside the diff and can't be auto-applied.
Blocking
🔧 wrench
- Per-author queue without superseded-run cancellation — see inline at
.github/workflows/test.yml:17 - Enforce the shared block and job timeouts — see inline at
.github/workflows/format.yml:58
Non-blocking
🤔 thinking
- Bot exemption covers the runs nobody waits on — see inline at
.github/workflows/test.yml:14
📝 note
- Windows axum leg from the module stack — see inline at
.github/workflows/test.yml:81
CI Status
- integration tests: PASS
- browser integration tests: PASS
- integration tests (Fastly EC lifecycle): PASS
- CodeQL: PASS
- cargo test (ts CLI, native) (macos-latest): PASS
- Analyze (python): PASS
- docs-proposal scripts: PASS
- Analyze (javascript-typescript): PASS (both runs)
- Analyze (rust): PASS
- vitest: PASS
- cargo fmt: PASS (required)
- cargo test (axum native): PASS
- CLAUDE.md symlink guard: PASS
- format-typescript: PASS (required)
- prepare integration artifacts: PASS
- cargo test (ts CLI, native) (ubuntu-latest): PASS
- format-docs: PASS (required)
- cargo check/build/test (spin native + wasm32-wasip1): PASS
- cargo test (cross-adapter parity): PASS
- PBS Terraform and Compose checks: PASS
- cargo check (cloudflare native + wasm32-unknown-unknown): PASS
- cargo test: PASS (required)
- Analyze (actions): PASS
A workflow-level group per pull request now cancels a run when a newer push arrives, so stale runs no longer hold an author's queue or count toward GitHub's 100-pending cap. The per-author queue moves to each job's own concurrency block with queue: max, keyed on the matrix for matrix jobs so their legs do not queue behind each other. Bot-authored PRs and non-PR events still key on the run ID. The shared comment now states the FIFO ordering and the 100-pending limit. Signed-off-by: dhruv8sh <dhruv8sh@proton.me>
The required cargo fmt job now fails when a PR-triggered workflow lacks the per-PR cancellation block from test.yml, or when a job lacks timeout-minutes or a per-author queue keyed on pull_request.user.login with queue: max. Matrix jobs must also include the matrix in their group. Jobs that call a reusable workflow are skipped. The step uses the runner image's yq. Signed-off-by: dhruv8sh <dhruv8sh@proton.me>
Summary
github.event.pull_request.user.login), so an author has at most one run in progress per workflow and their extra runs wait aspendingwithout holding a runner. Keying on the author rather thangithub.actormeans a maintainer pushing to or clicking "Update branch" on contributors' PRs does not pile those runs into the maintainer's queue.queue: maxkeeps every waiting run and starts them in order. The default single-pending queue would silently cancel an author's older waiting run whenever they open another PR. Every job now setstimeout-minutes, so a hung job cannot hold an author's queue for GitHub's 6-hour default.main, scheduled runs, manual dispatches and bot-authored PRs (for example Dependabot) fall back togithub.run_id, so they get their own group and are never held behind anyone's queue.Changes
.github/workflows/test.ymlqueue: max; addtimeout-minutesto the six jobs that lacked one.github/workflows/format.ymltimeout-minutesto all five jobs.github/workflows/codeql.ymltimeout-minutestoanalyze.github/workflows/integration-tests.yml.github/workflows/pbs-example.ymldeploy-docs.ymlanddocs-proposal.ymlare untouched: they only run onmainand already define their own concurrency.New timeouts are about 3x the longest of each job's last five
mainruns, with a 10-minute floor (5 for the symlink guard):test-axumtest-cloudflaretest-spintest-paritytest-cli(macOS leg)test-typescriptcheck-claude-md-symlinkformat-rustformat-typescriptformat-docsdocs-proposal-scriptsanalyze(rust leg)Known trade-offs: several pushes to the same PR now run one after another rather than in parallel, and a re-run joins the back of the author's queue. Cancelling a PR's superseded runs needs a separate privileged workflow, since a workflow can only have one concurrency group; that is left for a follow-up.
Closes
Closes #1425
Spec
Spec: Not a feature (CI change)
Test plan
cargo test-fastly && cargo test-axum(andcargo test-cloudflare)cargo clippy-fastly && cargo clippy-axum(andcargo clippy-cloudflare)cargo fmt --all -- --checkcd crates/trusted-server-js/lib && npx vitest runcd crates/trusted-server-js/lib && npm run formatcd docs && npm run formatcargo build --package trusted-server-adapter-fastly --release --target wasm32-wasip1fastly compute serveconcurrencyblock withqueue: maxin a throwaway private repo. One author opened three PRs back to back, then pushed tomainwhile they were queued. The PR runs ran one at a time, in creation order, none cancelled (pr-2 started 4s after pr-1 finished, pr-3 4s after pr-2). Themainpush started 4s after it was created while two PR runs were still pending.act: evaluated each workflow's actualgroup:expression. Two PRs by one author map to one group, different authors to separate groups, a maintainer pushing to another author's PR to that author's group, and Dependabot PRs,push,scheduleandworkflow_dispatchto run-ID groups. The same script asserts every job setstimeout-minutes. Against the previous revision it fails on the maintainer, Dependabot and timeout checks, as expected.queueas an unknown key; their schemas predate it. GitHub accepts it, anddocs-proposal.ymlalready usesqueue: maxonmain.Checklist
unwrap()in production code — useexpect("should ...")(no Rust changes)tracingmacros (notprintln!) (no Rust changes)actchecks above)