From 1d35e8624f30b2e17223ddd9e3d9adcabbc29d22 Mon Sep 17 00:00:00 2001 From: can1357 Date: Sat, 20 Jun 2026 21:38:00 +0200 Subject: [PATCH] fix(python/robomp): updated pull request event trigger criteria - Added the labeled action to the pull_request event, ensuring that workers process pull requests when labels are updated. --- python/robomp/src/queue.py | 2 +- python/robomp/tests/test_queue_dispatch.py | 94 ++++++++++++++++++++++ 2 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 python/robomp/tests/test_queue_dispatch.py diff --git a/python/robomp/src/queue.py b/python/robomp/src/queue.py index 49db480e3..1174631c5 100644 --- a/python/robomp/src/queue.py +++ b/python/robomp/src/queue.py @@ -391,7 +391,7 @@ class WorkerPool: attempts=row.attempts, slot_uid=slot_uid, ) - elif event == "pull_request" and action in ("opened", "reopened", "ready_for_review"): + elif event == "pull_request" and action in ("opened", "reopened", "ready_for_review", "labeled"): await tasks.review_pr( settings=self.settings, db=self.db, diff --git a/python/robomp/tests/test_queue_dispatch.py b/python/robomp/tests/test_queue_dispatch.py new file mode 100644 index 000000000..9ffa056be --- /dev/null +++ b/python/robomp/tests/test_queue_dispatch.py @@ -0,0 +1,94 @@ +"""Dispatch action -> task mapping in WorkerPool._dispatch. + +Regression guard for the route<->dispatch contract: `github_events.route` +queues a `pull_request.labeled` event as a `review_pr` task in `vouched_label` +mode, so `_dispatch` MUST invoke `tasks.review_pr` for that action. It +previously only handled `opened/reopened/ready_for_review`, so every vouched +PR fell through to the no-op branch and was silently marked `done`. +""" + +from __future__ import annotations + +import pytest + +from robomp import tasks +from robomp.config import Settings +from robomp.db import Database, EventRow +from robomp.queue import WorkerPool +from robomp.slot_pool import SlotPool + + +class _StubGitHub: + """Sentinel; dispatch tests stub out the task body.""" + + +class _StubSandbox: + natives_cache = None + + +class _StubGitTransport: + pass + + +def _make_pool(settings: Settings, db: Database) -> WorkerPool: + return WorkerPool( + settings=settings, + db=db, + github=_StubGitHub(), # type: ignore[arg-type] + sandbox=_StubSandbox(), # type: ignore[arg-type] + git_transport=_StubGitTransport(), # type: ignore[arg-type] + slot_pool=SlotPool(), + ) + + +def _pr_row(action: str, *, delivery: str = "pr1") -> EventRow: + return EventRow( + delivery_id=delivery, + event_type="pull_request", + repo="octo/widget", + issue_key="octo/widget#7", + payload={"action": action, "pull_request": {"number": 7}}, + received_at="2026-01-01T00:00:00Z", + state="running", + attempts=1, + last_error=None, + ) + + +@pytest.mark.parametrize("action", ["opened", "reopened", "ready_for_review", "labeled"]) +@pytest.mark.asyncio +async def test_dispatch_routes_pr_review_actions_to_review_pr( + settings: Settings, db: Database, monkeypatch: pytest.MonkeyPatch, action: str +) -> None: + """Every PR action `route` can queue for review MUST reach `tasks.review_pr`. + + `labeled` is the vouched-label trigger; the others are the `open` trigger. + """ + seen: list[str] = [] + + async def fake_review_pr(*, payload, **_kwargs) -> None: + seen.append(str(payload.get("action"))) + + monkeypatch.setattr(tasks, "review_pr", fake_review_pr) + + await _make_pool(settings, db)._dispatch(_pr_row(action)) # noqa: SLF001 + + assert seen == [action] + + +@pytest.mark.asyncio +async def test_dispatch_pr_synchronize_is_noop( + settings: Settings, db: Database, monkeypatch: pytest.MonkeyPatch +) -> None: + """Actions `route` never queues for review must NOT spawn a review task.""" + called = False + + async def fake_review_pr(**_kwargs) -> None: + nonlocal called + called = True + + monkeypatch.setattr(tasks, "review_pr", fake_review_pr) + + await _make_pool(settings, db)._dispatch(_pr_row("synchronize")) # noqa: SLF001 + + assert called is False