Skip to content

Commit

Permalink
add needs_webhook_secret_backfill to upload task (#521)
Browse files Browse the repository at this point in the history
  • Loading branch information
nora-codecov authored Jun 27, 2024
1 parent 6b8726c commit 646d815
Show file tree
Hide file tree
Showing 3 changed files with 269 additions and 73 deletions.
118 changes: 68 additions & 50 deletions services/repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,58 @@ def get_or_create_author(
return author


WEBHOOK_EVENTS = {
"github": ["pull_request", "delete", "push", "public", "status", "repository"],
"github_enterprise": [
"pull_request",
"delete",
"push",
"public",
"status",
"repository",
],
"bitbucket": [
"repo:push",
"pullrequest:created",
"pullrequest:updated",
"pullrequest:fulfilled",
"repo:commit_status_created",
"repo:commit_status_updated",
],
# https://confluence.atlassian.com/bitbucketserver/post-service-webhook-for-bitbucket-server-776640367.html
"bitbucket_server": [
"repo:modified",
"repo:refs_changed",
"pr:opened",
"pr:merged",
"pr:declined",
"pr:deleted",
],
"gitlab": {
"push_events": True,
"issues_events": False,
"merge_requests_events": True,
"tag_push_events": False,
"note_events": False,
"job_events": False,
"build_events": True,
"pipeline_events": True,
"wiki_events": False,
},
"gitlab_enterprise": {
"push_events": True,
"issues_events": False,
"merge_requests_events": True,
"tag_push_events": False,
"note_events": False,
"job_events": False,
"build_events": True,
"pipeline_events": True,
"wiki_events": False,
},
}


async def create_webhook_on_provider(
repository_service, token=None, webhook_secret: Optional[str] = None
):
Expand All @@ -362,56 +414,6 @@ async def create_webhook_on_provider(
webhook_url = get_config("setup", "webhook_url") or get_config(
"setup", "codecov_url"
)
WEBHOOK_EVENTS = {
"github": ["pull_request", "delete", "push", "public", "status", "repository"],
"github_enterprise": [
"pull_request",
"delete",
"push",
"public",
"status",
"repository",
],
"bitbucket": [
"repo:push",
"pullrequest:created",
"pullrequest:updated",
"pullrequest:fulfilled",
"repo:commit_status_created",
"repo:commit_status_updated",
],
# https://confluence.atlassian.com/bitbucketserver/post-service-webhook-for-bitbucket-server-776640367.html
"bitbucket_server": [
"repo:modified",
"repo:refs_changed",
"pr:opened",
"pr:merged",
"pr:declined",
"pr:deleted",
],
"gitlab": {
"push_events": True,
"issues_events": False,
"merge_requests_events": True,
"tag_push_events": False,
"note_events": False,
"job_events": False,
"build_events": True,
"pipeline_events": True,
"wiki_events": False,
},
"gitlab_enterprise": {
"push_events": True,
"issues_events": False,
"merge_requests_events": True,
"tag_push_events": False,
"note_events": False,
"job_events": False,
"build_events": True,
"pipeline_events": True,
"wiki_events": False,
},
}

if webhook_secret is None:
webhook_secret = get_config(
Expand All @@ -428,6 +430,22 @@ async def create_webhook_on_provider(
)


async def gitlab_webhook_update(repository_service, hookid, secret):
"""
Edits an existing Gitlab webhook - adds a secret.
"""
webhook_url = get_config("setup", "webhook_url") or get_config(
"setup", "codecov_url"
)
return await repository_service.edit_webhook(
hookid=hookid,
name=f"Codecov Webhook. {webhook_url}",
url=f"{webhook_url}/webhooks/{repository_service.service}",
events=WEBHOOK_EVENTS[repository_service.service],
secret=secret,
)


def get_repo_provider_service_by_id(db_session, repoid, commitid=None):
repo = db_session.query(Repository).filter(Repository.repoid == int(repoid)).first()

Expand Down
139 changes: 139 additions & 0 deletions tasks/tests/unit/test_upload_task.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import json
import uuid
from datetime import datetime, timedelta
from pathlib import Path
from unittest.mock import MagicMock, call
Expand All @@ -8,6 +9,7 @@
from celery.exceptions import Retry
from redis.exceptions import LockError
from shared.reports.enums import UploadState, UploadType
from shared.torngit import GitlabEnterprise
from shared.torngit.exceptions import TorngitClientError, TorngitRepoNotFoundError
from shared.torngit.gitlab import Gitlab
from shared.utils.sessions import SessionType
Expand Down Expand Up @@ -1497,6 +1499,143 @@ def test_possibly_setup_webhooks_gitlab(
token=None,
)

def test_needs_webhook_secret_backfill(self, dbsession, mocker, mock_configuration):
mock_configuration.set_params({"gitlab": {"bot": {"key": "somekey"}}})
repository = RepositoryFactory.create(
repoid="5678", hookid="1234", webhook_secret=None
)
dbsession.add(repository)
commit = CommitFactory.create(repository=repository)
dbsession.add(commit)
gitlab_provider = mocker.MagicMock(
Gitlab, get_commit_diff=mock.AsyncMock(return_value={})
)
mock_repo_provider = mocker.patch(
"services.repository._get_repo_provider_service_instance"
)
mock_repo_provider.return_value = gitlab_provider
gitlab_provider.data = mocker.MagicMock()
gitlab_provider.service = "gitlab"
task = UploadTask()
res = task.possibly_setup_webhooks(commit, gitlab_provider)
assert res is False

assert repository.webhook_secret is not None
gitlab_provider.edit_webhook.assert_called_with(
hookid=repository.hookid,
name="Codecov Webhook. None",
url="None/webhooks/gitlab",
events={
"push_events": True,
"issues_events": False,
"merge_requests_events": True,
"tag_push_events": False,
"note_events": False,
"job_events": False,
"build_events": True,
"pipeline_events": True,
"wiki_events": False,
},
secret=commit.repository.webhook_secret,
)

def test_needs_webhook_secret_backfill_gle(
self, dbsession, mocker, mock_configuration
):
mock_configuration.set_params(
{"gitlab_enterprise": {"bot": {"key": "somekey"}}}
)
repository = RepositoryFactory.create(
repoid="5678", hookid="1234", webhook_secret=None
)
dbsession.add(repository)
commit = CommitFactory.create(repository=repository)
dbsession.add(commit)
gitlab_e_provider = mocker.MagicMock(
GitlabEnterprise, get_commit_diff=mock.AsyncMock(return_value={})
)
mock_repo_provider = mocker.patch(
"services.repository._get_repo_provider_service_instance"
)
mock_repo_provider.return_value = gitlab_e_provider
gitlab_e_provider.data = mocker.MagicMock()
gitlab_e_provider.service = "gitlab"
task = UploadTask()
res = task.possibly_setup_webhooks(commit, gitlab_e_provider)
assert res is False

assert repository.webhook_secret is not None
gitlab_e_provider.edit_webhook.assert_called_with(
hookid=repository.hookid,
name="Codecov Webhook. None",
url="None/webhooks/gitlab",
events={
"push_events": True,
"issues_events": False,
"merge_requests_events": True,
"tag_push_events": False,
"note_events": False,
"job_events": False,
"build_events": True,
"pipeline_events": True,
"wiki_events": False,
},
secret=commit.repository.webhook_secret,
)

def test_doesnt_need_webhook_secret_backfill(
self, dbsession, mocker, mock_configuration
):
mock_configuration.set_params({"gitlab": {"bot": {"key": "somekey"}}})
secret = str(uuid.uuid4())
repository = RepositoryFactory.create(
repoid="5678", hookid="1234", webhook_secret=secret
)
dbsession.add(repository)
commit = CommitFactory.create(repository=repository)
dbsession.add(commit)
gitlab_provider = mocker.MagicMock(
Gitlab, get_commit_diff=mock.AsyncMock(return_value={})
)
mock_repo_provider = mocker.patch(
"services.repository._get_repo_provider_service_instance"
)
mock_repo_provider.return_value = gitlab_provider
gitlab_provider.data = mocker.MagicMock()
gitlab_provider.service = "gitlab"
task = UploadTask()
res = task.possibly_setup_webhooks(commit, gitlab_provider)
assert res is False

assert repository.webhook_secret is secret
gitlab_provider.edit_webhook.assert_not_called()

def test_doesnt_need_webhook_secret_backfill_no_hookid(
self, dbsession, mocker, mock_configuration
):
mock_configuration.set_params({"gitlab": {"bot": {"key": "somekey"}}})
repository = RepositoryFactory.create(
repoid="5678", hookid=None, webhook_secret=None, using_integration=True
)
dbsession.add(repository)
commit = CommitFactory.create(repository=repository)
dbsession.add(commit)
gitlab_provider = mocker.MagicMock(
Gitlab, get_commit_diff=mock.AsyncMock(return_value={})
)
mock_repo_provider = mocker.patch(
"services.repository._get_repo_provider_service_instance"
)
mock_repo_provider.return_value = gitlab_provider
gitlab_provider.data = mocker.MagicMock()
gitlab_provider.service = "gitlab"
task = UploadTask()
res = task.possibly_setup_webhooks(commit, gitlab_provider)
assert res is False

assert repository.webhook_secret is None
gitlab_provider.edit_webhook.assert_not_called()

def test_upload_not_ready_to_build_report(
self, dbsession, mocker, mock_configuration, mock_repo_provider, mock_redis
):
Expand Down
Loading

0 comments on commit 646d815

Please sign in to comment.