From ff70480b53ce7ff18f2ebaf037af884f4b2b2b39 Mon Sep 17 00:00:00 2001 From: Sanjay Santhanam <51058514+Sanjays2402@users.noreply.github.com> Date: Wed, 15 Jul 2026 02:58:30 -0700 Subject: [PATCH] fix(server): use sync mode for webhook jobs Webhook jobs used an unsupported incremental mode, so the executor skipped documentation regeneration while still advancing the sync baseline. Enqueue GitHub and GitLab pushes as sync jobs and cover both routes with regression tests. --- .../src/repowise/server/routers/webhooks.py | 4 +- tests/unit/server/test_webhooks.py | 65 +++++++++++++++++++ 2 files changed, 67 insertions(+), 2 deletions(-) diff --git a/packages/server/src/repowise/server/routers/webhooks.py b/packages/server/src/repowise/server/routers/webhooks.py index cadaede74..77d86af6e 100644 --- a/packages/server/src/repowise/server/routers/webhooks.py +++ b/packages/server/src/repowise/server/routers/webhooks.py @@ -121,7 +121,7 @@ async def github_webhook( repository_id=repo.id, status="pending", config={ - "mode": "incremental", + "mode": "sync", "trigger": "webhook", "before": payload.get("before", ""), "after": payload.get("after", ""), @@ -179,7 +179,7 @@ async def gitlab_webhook( repository_id=repo.id, status="pending", config={ - "mode": "incremental", + "mode": "sync", "trigger": "webhook", "before": payload.get("before", ""), "after": payload.get("after", ""), diff --git a/tests/unit/server/test_webhooks.py b/tests/unit/server/test_webhooks.py index 07d073a4c..b94727601 100644 --- a/tests/unit/server/test_webhooks.py +++ b/tests/unit/server/test_webhooks.py @@ -10,6 +10,9 @@ import pytest from httpx import AsyncClient +from sqlalchemy import select + +from repowise.core.persistence.models import GenerationJob, Repository @pytest.mark.asyncio @@ -34,6 +37,68 @@ async def test_github_webhook_no_secret(client: AsyncClient) -> None: assert data["status"] == "accepted" +@pytest.mark.parametrize( + ("endpoint", "headers", "repository_payload"), + [ + ( + "/api/webhooks/github", + { + "X-GitHub-Event": "push", + "X-GitHub-Delivery": "test-delivery-sync", + }, + {"repository": {"clone_url": "https://example.com/test-repo"}}, + ), + ( + "/api/webhooks/gitlab", + {"X-Gitlab-Event": "Push Hook"}, + {"project": {"web_url": "https://example.com/test-repo"}}, + ), + ], +) +@pytest.mark.asyncio +async def test_push_webhook_enqueues_sync_job( + client: AsyncClient, + session_factory, + endpoint: str, + headers: dict[str, str], + repository_payload: dict[str, object], +) -> None: + """Push webhooks use the executor's sync mode so docs are regenerated.""" + async with session_factory() as session: + session.add( + Repository( + name="test-repo", + url="https://example.com/test-repo", + local_path="/tmp/test-repo", + default_branch="main", + ) + ) + await session.commit() + + payload = { + "ref": "refs/heads/main", + "before": "before-sha", + "after": "after-sha", + **repository_payload, + } + with patch("repowise.server.routers.webhooks._launch_webhook_job"): + response = await client.post( + endpoint, + content=json.dumps(payload), + headers={**headers, "Content-Type": "application/json"}, + ) + + assert response.status_code == 200 + async with session_factory() as session: + job = (await session.execute(select(GenerationJob))).scalar_one() + config = json.loads(job.config_json) + + assert config["mode"] == "sync" + assert config["trigger"] == "webhook" + assert config["before"] == "before-sha" + assert config["after"] == "after-sha" + + @pytest.mark.asyncio async def test_github_webhook_valid_signature(client: AsyncClient) -> None: """With a secret configured, a valid signature passes."""