diff --git a/app/webhooks/github.py b/app/webhooks/github.py index 145085d9..965920d1 100644 --- a/app/webhooks/github.py +++ b/app/webhooks/github.py @@ -19,7 +19,7 @@ ISSUE_NUMBER_BOUNDARY = r"(?![A-Za-z0-9_-])" MAX_SQLITE_INTEGER = 2**63 - 1 LINKED_ISSUE_RE = re.compile( - r"\b(?:close[sd]?|fix(?:e[sd])?|resolve[sd]?|refs?|references?|bounty)\s+" + r"\b(?:close[sd]?|fix(?:e[sd])?|resolve[sd]?|refs?|references?|bounty)\s*:?\s+" rf"(?:(?P[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+)#(?P\d+){ISSUE_NUMBER_BOUNDARY}" rf"|#(?P\d+){ISSUE_NUMBER_BOUNDARY})", re.IGNORECASE, diff --git a/tests/test_webhooks.py b/tests/test_webhooks.py index 030d3ca6..e9f175cb 100644 --- a/tests/test_webhooks.py +++ b/tests/test_webhooks.py @@ -155,6 +155,48 @@ def test_accepted_pr_label_pays_pr_author_for_linked_bounty_issue(sqlite_url: st assert get_balance(session, "github:maintainer") == 0 +def test_accepted_pr_label_accepts_colon_after_link_keyword(sqlite_url: str) -> None: + create_schema(sqlite_url) + body = json.dumps( + { + "action": "labeled", + "label": {"name": "mrwk:accepted"}, + "pull_request": { + "number": 9, + "html_url": "https://github.com/ramimbo/mergework/pull/9", + "body": "Refs: #406", + "user": {"login": "contributor"}, + }, + "repository": {"full_name": "ramimbo/mergework"}, + "sender": {"login": "maintainer"}, + }, + separators=(",", ":"), + ).encode() + headers = { + "X-GitHub-Delivery": "delivery-pr-colon-linked-issue", + "X-GitHub-Event": "pull_request", + "X-Hub-Signature-256": _signature("secret", body), + } + + with session_scope(sqlite_url) as session: + ensure_genesis(session) + create_bounty( + session, + repo="ramimbo/mergework", + issue_number=406, + issue_url="https://github.com/ramimbo/mergework/issues/406", + title="Small focused fixes", + reward_mrwk="50", + acceptance="Accepted PRs should link back to the bounty issue.", + ) + + result = handle_github_webhook(sqlite_url, headers, body, "secret") + + assert result["status"] == "paid" + with session_scope(sqlite_url) as session: + assert get_balance(session, "github:contributor") == 50_000_000 + + def test_accepted_issue_event_for_pull_request_does_not_pay_matching_bounty( sqlite_url: str, ) -> None: