async def _refresh(owner, repo, action="user", **extra_data): event_type = "refresh" try: installation = github.get_installation(owner, repo) except exceptions.MergifyNotInstalled: return responses.Response("Mergify not installed", status_code=404) data = { "installation": installation, "action": action, "repository": { "name": repo, "owner": { "login": owner }, "full_name": f"{owner}/{repo}", }, "sender": { "login": "******" }, } data.update(extra_data) await github_events.job_filter_and_dispatch(event_type, str(uuid.uuid4()), data) return responses.Response("Refresh queued", status_code=202)
async def subscription_cache_update( installation_id, request: requests.Request): # pragma: no cover sub = await request.json() if sub is None: return responses.Response("Empty content", status_code=400) await sub_utils.save_subscription_to_cache(installation_id, sub) return responses.Response("Cache updated", status_code=200)
async def subscription_cache_update( owner_id, request: requests.Request): # pragma: no cover sub = await request.json() if sub is None: return responses.Response("Empty content", status_code=400) await subscription.Subscription.from_dict( owner_id, sub).save_subscription_to_cache() return responses.Response("Cache updated", status_code=200)
async def subscription_cache_update( owner_id: str, request: requests.Request) -> responses.Response: # pragma: no cover sub = await request.json() if sub is None: return responses.Response("Empty content", status_code=400) global _AREDIS_CACHE await subscription.Subscription.from_dict( _AREDIS_CACHE, int(owner_id), sub).save_subscription_to_cache() return responses.Response("Cache updated", status_code=200)
async def tokens_cache_delete( owner_id: github_types.GitHubAccountIdType, redis_cache: utils.RedisCache = fastapi.Depends( # noqa: B008 redis.get_redis_cache), ) -> responses.Response: try: await user_tokens.UserTokens.delete(redis_cache, owner_id) except NotImplementedError: return responses.Response("Deleting tokens is disabled", status_code=400) return responses.Response("Cache cleaned", status_code=200)
async def application_cache_delete( api_access_key: str, redis_links: redis_utils.RedisLinks = fastapi.Depends( # noqa: B008 redis.get_redis_links ), ) -> responses.Response: try: await application.Application.delete(redis_links.cache, api_access_key) except NotImplementedError: return responses.Response("Deleting subscription is disabled", status_code=400) return responses.Response("Cache cleaned", status_code=200)
async def subscription_cache_delete( owner_id: github_types.GitHubAccountIdType, redis_links: redis_utils.RedisLinks = fastapi.Depends( # noqa: B008 redis.get_redis_links ), ) -> responses.Response: try: await subscription.Subscription.delete_subscription(redis_links.cache, owner_id) except NotImplementedError: return responses.Response("Deleting subscription is disabled", status_code=400) return responses.Response("Cache cleaned", status_code=200)
async def subscription_cache_update( owner_id: github_types.GitHubAccountIdType, request: requests.Request, redis_cache: utils.RedisCache = fastapi.Depends( # noqa: B008 redis.get_redis_cache), ) -> responses.Response: sub = await request.json() if sub is None: return responses.Response("Empty content", status_code=400) await subscription.Subscription.from_dict( redis_cache, int(owner_id), sub).save_subscription_to_cache() return responses.Response("Cache updated", status_code=200)
async def refresh_pull( owner: github_types.GitHubLogin, repo_name: github_types.GitHubRepositoryName, pull_request_number: github_types.GitHubPullRequestNumber, action: github_types.GitHubEventRefreshActionType = "user", redis_cache: utils.RedisCache = fastapi.Depends( # noqa: B008 redis.get_redis_cache), redis_stream: utils.RedisStream = fastapi.Depends( # noqa: B008 redis.get_redis_stream), ) -> responses.Response: action = RefreshActionSchema(action) async with github.aget_client(owner_name=owner) as client: try: repository = await client.item(f"/repos/{owner}/{repo_name}") except http.HTTPNotFound: return responses.JSONResponse(status_code=404, content="repository not found") await utils.send_refresh( redis_cache, redis_stream, repository, pull_request_number=pull_request_number, action=action, ) return responses.Response("Refresh queued", status_code=202)
async def event_handler(request: requests.Request): event_type = request.headers.get("X-GitHub-Event") event_id = request.headers.get("X-GitHub-Delivery") data = await request.json() await github_events.job_filter_and_dispatch(event_type, event_id, data) if (config.WEBHOOK_APP_FORWARD_URL and config.WEBHOOK_FORWARD_EVENT_TYPES is not None and event_type in config.WEBHOOK_FORWARD_EVENT_TYPES): raw = await request.body() loop = asyncio.get_running_loop() await loop.run_in_executor( None, forward_events.post.s( config.WEBHOOK_APP_FORWARD_URL, data=raw.decode(), headers={ "X-GitHub-Event": event_type, "X-GitHub-Delivery": event_id, "X-Hub-Signature": request.headers.get("X-Hub-Signature"), "User-Agent": request.headers.get("User-Agent"), "Content-Type": request.headers.get("Content-Type"), }, ).delay, ) return responses.Response("Event queued", status_code=202)
async def marketplace_handler(request: requests.Request): # pragma: no cover event_type = request.headers.get("X-GitHub-Event") event_id = request.headers.get("X-GitHub-Delivery") data = await request.json() loop = asyncio.get_running_loop() await loop.run_in_executor( None, legacy_github_events.job_marketplace.s(event_type, event_id, data).apply_async, ) if config.WEBHOOK_MARKETPLACE_FORWARD_URL: raw = await request.body() await loop.run_in_executor( None, forward_events.post.s( config.WEBHOOK_MARKETPLACE_FORWARD_URL, data=raw.decode(), headers={ "X-GitHub-Event": event_type, "X-GitHub-Delivery": event_id, "X-Hub-Signature": request.headers.get("X-Hub-Signature"), "User-Agent": request.headers.get("User-Agent"), "Content-Type": request.headers.get("Content-Type"), }, ).delay, ) return responses.Response("Event queued", status_code=202)
async def refresh_branch( owner: github_types.GitHubLogin, repo_name: github_types.GitHubRepositoryName, branch: str, redis_cache: utils.RedisCache = fastapi.Depends( # noqa: B008 redis.get_redis_cache ), redis_stream: utils.RedisStream = fastapi.Depends( # noqa: B008 redis.get_redis_stream ), ) -> responses.Response: async with github.aget_client(owner_name=owner) as client: try: repository = await client.item(f"/repos/{owner}/{repo_name}") except http.HTTPNotFound: return responses.JSONResponse( status_code=404, content="repository not found" ) await github_events.send_refresh( redis_cache, redis_stream, repository, ref=github_types.GitHubRefType(f"refs/heads/{branch}"), ) return responses.Response("Refresh queued", status_code=202)
async def subscription_cache_delete( owner_id: github_types.GitHubAccountIdType, redis_cache: utils.RedisCache = fastapi.Depends( # noqa: B008 redis.get_redis_cache), ) -> responses.Response: await subscription.Subscription.delete(redis_cache, owner_id) return responses.Response("Cache cleaned", status_code=200)
async def refresh_pull( owner_login: github_types.GitHubLogin, repo_name: github_types.GitHubRepositoryName, pull_request_number: github_types.GitHubPullRequestNumber, action: github_types.GitHubEventRefreshActionType = "user", redis_links: redis_utils.RedisLinks = fastapi.Depends( # noqa: B008 redis.get_redis_links), ) -> responses.Response: action = RefreshActionSchema(action) installation_json = await github.get_installation_from_login(owner_login) async with github.aget_client(installation_json) as client: try: repository = await client.item(f"/repos/{owner_login}/{repo_name}") except http.HTTPNotFound: return responses.JSONResponse(status_code=404, content="repository not found") await utils.send_pull_refresh( redis_links.stream, repository, action=action, pull_request_number=pull_request_number, source="API", ) return responses.Response("Refresh queued", status_code=202)
async def refresh_branch( owner_login: github_types.GitHubLogin, repo_name: github_types.GitHubRepositoryName, branch: str, redis_cache: utils.RedisCache = fastapi.Depends( # noqa: B008 redis.get_redis_cache), redis_stream: utils.RedisStream = fastapi.Depends( # noqa: B008 redis.get_redis_stream), ) -> responses.Response: installation_json = await github.get_installation_from_login(owner_login) async with github.aget_client(installation_json) as client: try: repository = await client.item(f"/repos/{owner_login}/{repo_name}") except http.HTTPNotFound: return responses.JSONResponse(status_code=404, content="repository not found") await utils.send_branch_refresh( redis_cache, redis_stream, repository, action="user", source="API", ref=github_types.GitHubRefType(f"refs/heads/{branch}"), ) return responses.Response("Refresh queued", status_code=202)
async def event_handler(request: requests.Request, ) -> responses.Response: event_type = request.headers.get("X-GitHub-Event") event_id = request.headers.get("X-GitHub-Delivery") data = await request.json() try: await github_events.job_filter_and_dispatch(_AREDIS_STREAM, event_type, event_id, data) except github_events.IgnoredEvent as ie: status_code = 200 reason = f"Event ignored: {ie.reason}" else: status_code = 202 reason = "Event queued" if (config.WEBHOOK_APP_FORWARD_URL and config.WEBHOOK_FORWARD_EVENT_TYPES is not None and event_type in config.WEBHOOK_FORWARD_EVENT_TYPES): raw = await request.body() await http_post( config.WEBHOOK_APP_FORWARD_URL, data=raw.decode(), headers={ "X-GitHub-Event": event_type, "X-GitHub-Delivery": event_id, "X-Hub-Signature": request.headers.get("X-Hub-Signature"), "User-Agent": request.headers.get("User-Agent"), "Content-Type": request.headers.get("Content-Type"), }, ) return responses.Response(reason, status_code=status_code)
async def marketplace_handler( request: requests.Request, ) -> responses.Response: # pragma: no cover event_type = request.headers.get("X-GitHub-Event") event_id = request.headers.get("X-GitHub-Delivery") data = await request.json() LOG.info( "Marketplace event", event_type=event_type, event_id=event_id, sender=data["sender"]["login"], gh_owner=data["marketplace_purchase"]["account"]["login"], ) await cleanup_subscription(data) if config.WEBHOOK_MARKETPLACE_FORWARD_URL: raw = await request.body() await http_post( config.WEBHOOK_MARKETPLACE_FORWARD_URL, data=raw.decode(), headers={ "X-GitHub-Event": event_type, "X-GitHub-Delivery": event_id, "X-Hub-Signature": request.headers.get("X-Hub-Signature"), "User-Agent": request.headers.get("User-Agent"), "Content-Type": request.headers.get("Content-Type"), }, ) return responses.Response("Event queued", status_code=202)
def test_database_status_without_exception(): expected = 'UP' response = responses.Response() actual = healthcheck.database(response, MockSession()) assert expected == actual['status'] assert status.HTTP_200_OK == response.status_code
async def subscription_cache_update( owner_id: github_types.GitHubAccountIdType, request: requests.Request, redis_cache: utils.RedisCache = fastapi.Depends( # noqa: B008 redis.get_redis_cache), ) -> responses.Response: sub = await request.json() if sub is None: return responses.Response("Empty content", status_code=400) try: await subscription.Subscription.update_subscription( redis_cache, int(owner_id), sub) except NotImplementedError: return responses.Response("updating subscription is disabled", status_code=400) return responses.Response("Cache updated", status_code=200)
def test_database_status_with_exception(): expected = 'DOWN' response = responses.Response() actual = healthcheck.database(response, MockSession(True)) assert expected == actual['status'] assert status.HTTP_503_SERVICE_UNAVAILABLE == response.status_code
async def event_testing_handler_post(request: requests.Request): # pragma: no cover event_type = request.headers.get("X-GitHub-Event") event_id = request.headers.get("X-GitHub-Delivery") data = await request.json() await _AREDIS_CACHE.rpush( "events-testing", json.dumps({"id": event_id, "type": event_type, "payload": data}), ) return responses.Response("Event queued", status_code=202)
async def application_cache_update( api_access_key: str, request: requests.Request, redis_cache: utils.RedisCache = fastapi.Depends( # noqa: B008 redis.get_redis_cache), ) -> responses.Response: data = typing.cast(typing.Optional[application.ApplicationDashboardJSON], await request.json()) if data is None: return responses.Response("Empty content", status_code=400) try: await application.Application.update(redis_cache, api_access_key, data) except NotImplementedError: return responses.Response("Updating application is disabled", status_code=400) return responses.Response("Cache updated", status_code=200)
async def index( setup_action: typing.Optional[str] = None, ) -> responses.Response: # pragma: no cover if setup_action: return responses.Response( "Your Mergify installation succeeded.", status_code=200, ) return responses.RedirectResponse(url="https://mergify.com")
async def marketplace_testng_handler(request: requests.Request): # pragma: no cover event_type = request.headers.get("X-GitHub-Event") event_id = request.headers.get("X-GitHub-Delivery") data = await request.json() LOG.debug( "received marketplace testing events", event_type=event_type, event_id=event_id, data=data, ) return responses.Response("Event ignored", status_code=202)
async def event_handler( request: requests.Request, redis_cache: utils.RedisCache = fastapi.Depends( # noqa: B008 redis.get_redis_cache ), redis_stream: utils.RedisStream = fastapi.Depends( # noqa: B008 redis.get_redis_stream ), ) -> responses.Response: event_type = request.headers.get("X-GitHub-Event") event_id = request.headers.get("X-GitHub-Delivery") data = await request.json() try: await github_events.filter_and_dispatch( redis_cache, redis_stream, event_type, event_id, data ) except github_events.IgnoredEvent as ie: status_code = 200 reason = f"Event ignored: {ie.reason}" else: status_code = 202 reason = "Event queued" if ( config.WEBHOOK_APP_FORWARD_URL and config.WEBHOOK_FORWARD_EVENT_TYPES is not None and event_type in config.WEBHOOK_FORWARD_EVENT_TYPES ): raw = await request.body() try: async with http.AsyncClient(timeout=EVENT_FORWARD_TIMEOUT) as client: await client.post( config.WEBHOOK_APP_FORWARD_URL, content=raw.decode(), headers={ "X-GitHub-Event": event_type, "X-GitHub-Delivery": event_id, "X-Hub-Signature": request.headers.get("X-Hub-Signature"), "User-Agent": request.headers.get("User-Agent"), "Content-Type": request.headers.get("Content-Type"), }, ) except httpx.TimeoutException: LOG.warning( "Fail to forward GitHub event", event_type=event_type, event_id=event_id, sender=data["sender"]["login"], ) return responses.Response(reason, status_code=status_code)
async def refresh_repo( owner: github_types.GitHubLogin, repo_name: github_types.GitHubRepositoryName) -> responses.Response: global _AREDIS_STREAM, _AREDIS_CACHE async with github.aget_client(owner_name=owner) as client: try: repository = await client.item(f"/repos/{owner}/{repo_name}") except http.HTTPNotFound: return responses.JSONResponse(status_code=404, content="repository not found") await github_events.send_refresh(_AREDIS_CACHE, _AREDIS_STREAM, repository) return responses.Response("Refresh queued", status_code=202)
async def _refresh( owner: github_types.GitHubLogin, repo: str, action: github_types.GitHubEventRefreshActionType = "user", ref: typing.Optional[github_types.GitHubRefType] = None, pull_request: typing.Optional[github_types.GitHubPullRequest] = None, ) -> responses.Response: data = github_types.GitHubEventRefresh({ "action": action, "organization": { "login": owner, "id": github_types.GitHubAccountIdType(0), "type": "Organization", }, "installation": { "id": 0, "account": { "login": owner, "id": github_types.GitHubAccountIdType(0), "type": "Organization", }, }, "repository": { "default_branch": github_types.GitHubRefType(""), "id": github_types.GitHubRepositoryIdType(0), "private": False, "archived": False, "url": "", "name": repo, "owner": { "login": owner, "id": github_types.GitHubAccountIdType(0), "type": "Organization", }, "full_name": f"{owner}/{repo}", }, "sender": { "login": github_types.GitHubLogin("<internal>"), "id": github_types.GitHubAccountIdType(0), "type": "User", }, "ref": ref, "pull_request": pull_request, }) await github_events.filter_and_dispatch(_AREDIS_STREAM, "refresh", str(uuid.uuid4()), data) return responses.Response("Refresh queued", status_code=202)
async def marketplace_handler( request: requests.Request, redis_links: redis_utils.RedisLinks = fastapi.Depends( # noqa: B008 redis.get_redis_links), ) -> responses.Response: event_type = request.headers.get("X-GitHub-Event") event_id = request.headers.get("X-GitHub-Delivery") data = await request.json() LOG.info( "Marketplace event", event_type=event_type, event_id=event_id, sender=data["sender"]["login"], gh_owner=data["marketplace_purchase"]["account"]["login"], ) await subscription.Subscription.delete_subscription( redis_links.cache, data["marketplace_purchase"]["account"]["id"]) if config.WEBHOOK_MARKETPLACE_FORWARD_URL: raw = await request.body() try: async with http.AsyncClient( timeout=EVENT_FORWARD_TIMEOUT) as client: await client.post( config.WEBHOOK_MARKETPLACE_FORWARD_URL, content=raw.decode(), headers={ "X-GitHub-Event": event_type, "X-GitHub-Delivery": event_id, "X-Hub-Signature": request.headers.get("X-Hub-Signature"), "User-Agent": request.headers.get("User-Agent"), "Content-Type": request.headers.get("Content-Type"), }, ) except httpx.TimeoutException: LOG.warning( "Fail to forward Marketplace event", event_type=event_type, event_id=event_id, sender=data["sender"]["login"], gh_owner=data["marketplace_purchase"]["account"]["login"], ) return responses.Response("Event queued", status_code=202)
async def _refresh(owner, repo, action="user", **extra_data): event_type = "refresh" data = { "action": action, "repository": { "name": repo, "owner": {"login": owner}, "full_name": f"{owner}/{repo}", }, "sender": {"login": "******"}, } data.update(extra_data) await github_events.job_filter_and_dispatch( app.aredis_stream, event_type, str(uuid.uuid4()), data ) return responses.Response("Refresh queued", status_code=202)
async def refresh_pull( owner: github_types.GitHubLogin, repo_name: github_types.GitHubRepositoryName, pull_request_number: github_types.GitHubPullRequestNumber, action: github_types.GitHubEventRefreshActionType = "user", ) -> responses.Response: action = RefreshActionSchema(action) async with github.aget_client(owner_name=owner) as client: try: repository = await client.item(f"/repos/{owner}/{repo_name}") except http.HTTPNotFound: return responses.JSONResponse(status_code=404, content="repository not found") global _AREDIS_STREAM, _AREDIS_CACHE await github_events.send_refresh( _AREDIS_CACHE, _AREDIS_STREAM, repository, pull_request_number=pull_request_number, action=action, ) return responses.Response("Refresh queued", status_code=202)