Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .github/workflows/pr-review-merge-scheduler.yml
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,13 @@ jobs:
github.event.client_payload.org_sweep != true
)
runs-on: ubuntu-24.04
# Bound scan-pr-queue to a wall-clock ceiling well short of GitHub's
# 360-minute platform default. This is a single-repository queue scan
# (paginated GraphQL reads plus at most one review dispatch and one
# branch update per run) -- much lighter than org-queue-sweep's full
# organization walk below, so it gets a shorter bound than that job's
# timeout-minutes: 60.
timeout-minutes: 30

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 Info: Queue delay remains unbounded

timeout-minutes starts after runner assignment, so it cannot drain existing queue delays. It still prevents executing scans from occupying runners beyond 30 minutes.

Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 Info: Interrupted runs remain reconcilable

A timeout can stop between remote mutations, but no local transaction survives. Later runs reload GitHub state, while head guards protect branch updates and merges.

Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

permissions:
actions: write
checks: read
Expand Down
21 changes: 21 additions & 0 deletions tests/test_required_workflow_queue_contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import json
import os
import re
import shlex
import shutil
import subprocess
Expand Down Expand Up @@ -977,6 +978,26 @@ def test_review_events_can_dispatch_after_threads_are_resolved() -> None:
)[1].splitlines()[0]


def test_scan_pr_queue_has_a_bounded_runtime() -> None:
"""scan-pr-queue must not fall back to GitHub's 360-minute platform default.

Without a job-level timeout-minutes, a stuck run (rate-limited GitHub API,
a hung gh invocation) can occupy a shared runner for up to six hours,
contributing to org-wide Actions capacity saturation. The bound must be
shorter than org-queue-sweep's timeout-minutes: 60, since scan-pr-queue
only scans this one repository's queue while org-queue-sweep walks every
target repository in the organization.
"""
workflow = workflow_text("pr-review-merge-scheduler.yml")
scan_job = workflow.split(" scan-pr-queue:", 1)[1].split(" org-queue-sweep:", 1)[0]

match = re.search(r"^ timeout-minutes: (\d+)$", scan_job, flags=re.MULTILINE)
assert match is not None, "scan-pr-queue must declare a job-level timeout-minutes"
scan_timeout = int(match.group(1))
assert 1 <= scan_timeout <= 45
assert scan_timeout < 60


def test_org_queue_sweep_covers_target_repositories_on_a_heartbeat() -> None:
"""Guard the org-wide approved-PR fallback sweep contract.

Expand Down
Loading