diff --git a/src/runboat/webhooks.py b/src/runboat/webhooks.py index 67fcb73..ce74a67 100644 --- a/src/runboat/webhooks.py +++ b/src/runboat/webhooks.py @@ -1,7 +1,12 @@ +import logging + from fastapi import APIRouter, BackgroundTasks, Header, Request from .controller import controller from .github import CommitInfo +from .settings import settings + +_logger = logging.getLogger(__name__) router = APIRouter() @@ -16,21 +21,41 @@ async def receive_payload( payload = await request.json() if x_github_event == "pull_request": if payload["action"] in ("opened", "synchronize"): + repo = payload["repository"]["full_name"] + target_branch = payload["pull_request"]["base"]["ref"] + if not settings.is_repo_and_branch_supported(repo, target_branch): + _logger.debug( + "Ignoring %s payload for unsupported repo %s or target branch %s", + x_github_event, + repo, + target_branch, + ) + return background_tasks.add_task( controller.deploy_or_start, CommitInfo( - repo=payload["repository"]["full_name"], - target_branch=payload["pull_request"]["base"]["ref"], + repo=repo, + target_branch=target_branch, pr=payload["pull_request"]["number"], git_commit=payload["pull_request"]["head"]["sha"], ), ) elif x_github_event == "push": + repo = payload["repository"]["full_name"] + target_branch = payload["ref"].split("/")[-1] + if not settings.is_repo_and_branch_supported(repo, target_branch): + _logger.debug( + "Ignoring %s payload for unsupported repo %s or target branch %s", + x_github_event, + repo, + target_branch, + ) + return background_tasks.add_task( controller.deploy_or_start, CommitInfo( - repo=payload["repository"]["full_name"], - target_branch=payload["ref"].split("/")[-1], + repo=repo, + target_branch=target_branch, pr=None, git_commit=payload["after"], ), diff --git a/tests/test_webhook.py b/tests/test_webhook.py index fc9feb6..f5ce19c 100644 --- a/tests/test_webhook.py +++ b/tests/test_webhook.py @@ -34,8 +34,25 @@ def test_webhook_github_push(mocker: MockerFixture) -> None: ) +def test_webhook_github_push_unsupported_repo(mocker: MockerFixture) -> None: + mock = mocker.patch("fastapi.BackgroundTasks.add_task") + response = client.post( + "/webhooks/github", + headers={ + "X-GitHub-Event": "push", + }, + json={ + "repository": {"full_name": "org/not-a-repo"}, # repo not in .env.test + "ref": "refs/heads/15.0", + "after": "abcde", + }, + ) + response.raise_for_status() + mock.assert_not_called() + + @pytest.mark.parametrize("action", ["opened", "synchronize"]) -def test_webhook_github_pr_open_synchronize(action: str, mocker: MockerFixture) -> None: +def test_webhook_github_pr(action: str, mocker: MockerFixture) -> None: mock = mocker.patch("fastapi.BackgroundTasks.add_task") response = client.post( "/webhooks/github", @@ -66,3 +83,31 @@ def test_webhook_github_pr_open_synchronize(action: str, mocker: MockerFixture) git_commit="abcde", ), ) + + +@pytest.mark.parametrize("action", ["opened", "synchronize"]) +def test_webhook_github_pr_unsupported_branch( + action: str, mocker: MockerFixture +) -> None: + mock = mocker.patch("fastapi.BackgroundTasks.add_task") + response = client.post( + "/webhooks/github", + headers={ + "X-GitHub-Event": "pull_request", + }, + json={ + "action": action, + "repository": {"full_name": "oca/mis-builder"}, + "pull_request": { + "base": { + "ref": "14.0", # branch 14.0 not declared in .env.test + }, + "number": 381, + "head": { + "sha": "abcde", + }, + }, + }, + ) + response.raise_for_status() + mock.assert_not_called()