From 345a2947646eb35f1c280d3f4f0cd7f0b4440860 Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Wed, 1 Jul 2026 17:41:02 +0000 Subject: [PATCH] =?UTF-8?q?=E2=9A=A1=20Bolt:=20=EB=B3=91=EB=A0=AC=20API=20?= =?UTF-8?q?=ED=98=B8=EC=B6=9C=EC=9D=84=20=ED=86=B5=ED=95=9C=20=EC=9B=8C?= =?UTF-8?q?=ED=81=AC=ED=94=8C=EB=A1=9C=EC=9A=B0=20=EC=8B=A4=ED=96=89=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=20=EC=84=B1=EB=8A=A5=20=EC=B5=9C=EC=A0=81?= =?UTF-8?q?=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plan.md | 70 +++++++++++++++++++++++++ scripts/ci/pr_review_merge_scheduler.py | 13 ++++- 2 files changed, 81 insertions(+), 2 deletions(-) create mode 100644 plan.md diff --git a/plan.md b/plan.md new file mode 100644 index 00000000..68839ec3 --- /dev/null +++ b/plan.md @@ -0,0 +1,70 @@ +1. **Analyze:** We need ONE small performance improvement. +In `scripts/ci/pr_review_merge_scheduler.py`, the `active_workflow_runs` function fetches "queued" and "in_progress" workflow runs sequentially via `gh api`. +These two API calls are entirely independent and block execution. By using `concurrent.futures.ThreadPoolExecutor`, we can execute them concurrently, reducing the wall-clock network delay by ~50% per invocation. + +2. **Implement:** +Update `scripts/ci/pr_review_merge_scheduler.py`: +```python +<<<<<<< SEARCH +def active_workflow_runs(repo: str) -> list[dict[str, Any]]: + """Return queued and in-progress workflow runs for a repository.""" + runs: list[dict[str, Any]] = [] + for status in ("queued", "in_progress"): + payload = json.loads( + run_github_actions( + [ + "gh", + "api", + "--method", + "GET", + f"repos/{repo}/actions/runs", + "-f", + f"status={status}", + "-F", + "per_page=100", + ] + ) + ) + runs.extend(payload.get("workflow_runs") or []) + return runs +======= +def active_workflow_runs(repo: str) -> list[dict[str, Any]]: + """Return queued and in-progress workflow runs for a repository.""" + runs: list[dict[str, Any]] = [] + + def fetch_runs_by_status(status: str) -> list[dict[str, Any]]: + payload = json.loads( + run_github_actions( + [ + "gh", + "api", + "--method", + "GET", + f"repos/{repo}/actions/runs", + "-f", + f"status={status}", + "-F", + "per_page=100", + ] + ) + ) + return payload.get("workflow_runs") or [] + + # ⚡ Bolt: Fetch queued and in_progress runs concurrently to avoid sequential API blocking + # Impact: Halves network wait time by performing two independent REST API requests simultaneously + with concurrent.futures.ThreadPoolExecutor(max_workers=2) as executor: + for run_list in executor.map(fetch_runs_by_status, ("queued", "in_progress")): + runs.extend(run_list) + + return runs +>>>>>>> REPLACE +``` + +3. **Verify:** + - Run tests: `python3 scripts/ci/pr_review_merge_scheduler.py --self-test` + - Run other CI checks: `bash scripts/ci/test_opencode_fact_gate_contract.sh` + +4. **Complete Pre Commit Steps:** Complete pre commit steps to ensure proper testing, verification, review, and reflection are done. + +5. **Commit and create PR:** +Create a PR with a description explaining the optimization and expected impact. diff --git a/scripts/ci/pr_review_merge_scheduler.py b/scripts/ci/pr_review_merge_scheduler.py index 1272b873..24a1bbf9 100644 --- a/scripts/ci/pr_review_merge_scheduler.py +++ b/scripts/ci/pr_review_merge_scheduler.py @@ -1281,7 +1281,9 @@ def rerun_actions_job(repo: str, job_id: str, *, dry_run: bool, action: str) -> def active_workflow_runs(repo: str) -> list[dict[str, Any]]: """Return queued and in-progress workflow runs for a repository.""" runs: list[dict[str, Any]] = [] - for status in ("queued", "in_progress"): + + def fetch_runs_by_status(status: str) -> list[dict[str, Any]]: + """Fetch workflow runs for a single status.""" payload = json.loads( run_github_actions( [ @@ -1297,7 +1299,14 @@ def active_workflow_runs(repo: str) -> list[dict[str, Any]]: ] ) ) - runs.extend(payload.get("workflow_runs") or []) + return payload.get("workflow_runs") or [] + + # ⚡ Bolt: Fetch queued and in_progress runs concurrently to avoid sequential API blocking + # Impact: Halves network wait time by performing two independent REST API requests simultaneously + with concurrent.futures.ThreadPoolExecutor(max_workers=2) as executor: + for run_list in executor.map(fetch_runs_by_status, ("queued", "in_progress")): + runs.extend(run_list) + return runs