From eebcc79a7ff6e099e0c7fd2fbfabbf9908ea80ec Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Tue, 8 Sep 2026 10:30:03 +0900 Subject: [PATCH] =?UTF-8?q?fix(scheduler):=20=EC=9E=90=EA=B2=A9=20?= =?UTF-8?q?=EC=A6=9D=EB=AA=85=EA=B3=BC=20Actions=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EA=B3=84=EC=95=BD=20=EB=B3=B5=EA=B5=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Codex Signed-off-by: Seongho Bae --- AGENTS.md | 4 ++++ tests/test_pr_review_merge_scheduler.py | 15 ++++++++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index e955f8b36a..336698bfe7 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -212,3 +212,7 @@ them alone proves succession. variable in CI, so a failure class exists that cannot reproduce locally. Before calling a scheduler change clean, run the affected tests both ways, including `GITHUB_ACTIONS=true python3 -m pytest `. +- Scheduler credential fixtures must provide distinct synthetic selected and workflow + tokens, not only a source label. Keep missing-token and same-token rejection tests; + never weaken production credential proof to restore a green fixture. Actions callable + doubles must accept and assert the real keyword arguments, including `stdin`. diff --git a/tests/test_pr_review_merge_scheduler.py b/tests/test_pr_review_merge_scheduler.py index 0e2aba2330..2a208a807a 100644 --- a/tests/test_pr_review_merge_scheduler.py +++ b/tests/test_pr_review_merge_scheduler.py @@ -34,6 +34,8 @@ def workflow_starting_mutation_credential(monkeypatch): workflow-starting credential exactly like the scheduler workflow does. """ monkeypatch.setenv("SCHEDULER_MUTATION_TOKEN_SOURCE", "PR_REVIEW_MERGE_TOKEN") + monkeypatch.setenv("GH_TOKEN", "selected-mutation-test-token") + monkeypatch.setenv("SCHEDULER_WORKFLOW_TOKEN", "runner-comparison-test-token") @pytest.fixture(autouse=True) @@ -1785,7 +1787,12 @@ def map(self, func, items): ), ) cancelled = [] - monkeypatch.setattr(sched, "run_github_actions", cancelled.append) + def record_cancel(args, *, stdin=None): + assert stdin is None + cancelled.append(args) + return "" + + monkeypatch.setattr(sched, "run_github_actions", record_cancel) monkeypatch.setattr(sched, "require_github_actions_control_actor", lambda x: None) run_ids = sched.cancel_stale_opencode_runs("owner/repo", "workflow", make_pr(), dry_run=False) @@ -1796,7 +1803,8 @@ def map(self, func, items): def test_force_cancel_failure_logs_reason_and_does_not_raise(monkeypatch, capsys): - def fail_cancel(args): + def fail_cancel(args, *, stdin=None): + assert stdin is None raise RuntimeError( "Command failed (1): gh api -X POST " "repos/owner/repo/actions/runs/29263154177/force-cancel; " @@ -1821,7 +1829,8 @@ def fail_cancel(args): def test_force_cancel_multiple_runs_reports_only_failures(monkeypatch): - def maybe_fail(args): + def maybe_fail(args, *, stdin=None): + assert stdin is None if "runs/2/force-cancel" in " ".join(args): raise RuntimeError("GitHub returned HTTP 500") return ""