Skip to content

Commit cf95da8

Browse files
committed
feat(repos): Activate repo webhook and syncing task for GHE
This enables the same github syncing for GHE
1 parent 784ec6e commit cf95da8

File tree

4 files changed

+115
-2
lines changed

4 files changed

+115
-2
lines changed

src/sentry/integrations/github/tasks/sync_repos.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ def github_repo_sync_beat() -> None:
246246
name="github_repo_sync",
247247
schedule_key="github-repo-sync-beat",
248248
queryset=OrganizationIntegration.objects.filter(
249-
integration__provider="github",
249+
integration__provider__in=["github", "github_enterprise"],
250250
integration__status=ObjectStatus.ACTIVE,
251251
status=ObjectStatus.ACTIVE,
252252
),

src/sentry/integrations/github_enterprise/webhook.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
from sentry.integrations.github.webhook import (
2222
GitHubWebhook,
2323
InstallationEventWebhook,
24+
InstallationRepositoriesEventWebhook,
2425
IssuesEventWebhook,
2526
PullRequestEventWebhook,
2627
PushEventWebhook,
@@ -106,6 +107,12 @@ class GitHubEnterpriseInstallationEventWebhook(GitHubEnterpriseWebhook, Installa
106107
pass
107108

108109

110+
class GitHubEnterpriseInstallationRepositoriesEventWebhook(
111+
GitHubEnterpriseWebhook, InstallationRepositoriesEventWebhook
112+
):
113+
pass
114+
115+
109116
class GitHubEnterprisePushEventWebhook(GitHubEnterpriseWebhook, PushEventWebhook):
110117
pass
111118

@@ -348,6 +355,7 @@ class GitHubEnterpriseWebhookEndpoint(GitHubEnterpriseWebhookBase):
348355
"push": GitHubEnterprisePushEventWebhook,
349356
"pull_request": GitHubEnterprisePullRequestEventWebhook,
350357
"installation": GitHubEnterpriseInstallationEventWebhook,
358+
"installation_repositories": GitHubEnterpriseInstallationRepositoriesEventWebhook,
351359
"issues": GitHubEnterpriseIssuesEventWebhook,
352360
}
353361

tests/sentry/integrations/github/tasks/test_sync_repos.py

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,12 @@
88
from sentry.constants import ObjectStatus
99
from sentry.integrations.github.integration import GitHubIntegrationProvider
1010
from sentry.integrations.github.tasks.sync_repos import sync_repos_for_org
11+
from sentry.integrations.github_enterprise.integration import GitHubEnterpriseIntegrationProvider
1112
from sentry.integrations.models.organization_integration import OrganizationIntegration
1213
from sentry.models.auditlogentry import AuditLogEntry
1314
from sentry.models.repository import Repository
1415
from sentry.silo.base import SiloMode
15-
from sentry.testutils.cases import IntegrationTestCase
16+
from sentry.testutils.cases import IntegrationTestCase, TestCase
1617
from sentry.testutils.silo import assume_test_silo_mode, assume_test_silo_mode_of, control_silo_test
1718

1819

@@ -218,3 +219,44 @@ def test_rate_limited_raises_for_retry(self, _: MagicMock) -> None:
218219

219220
with self.feature("organizations:github-repo-auto-sync"), pytest.raises(RetryTaskError):
220221
sync_repos_for_org(self.oi.id)
222+
223+
224+
@control_silo_test
225+
class SyncReposForOrgGHETestCase(TestCase):
226+
@patch("sentry.integrations.github.client.GitHubBaseClient.get_repos")
227+
def test_creates_new_repos_for_ghe(self, mock_get_repos: MagicMock) -> None:
228+
GitHubEnterpriseIntegrationProvider().setup()
229+
230+
integration = self.create_integration(
231+
organization=self.organization,
232+
external_id="35.232.149.196:12345",
233+
provider="github_enterprise",
234+
metadata={
235+
"domain_name": "35.232.149.196/testorg",
236+
"installation_id": "12345",
237+
"installation": {
238+
"id": "2",
239+
"private_key": "private_key",
240+
"verify_ssl": True,
241+
},
242+
},
243+
)
244+
oi = OrganizationIntegration.objects.get(
245+
organization_id=self.organization.id, integration=integration
246+
)
247+
248+
mock_get_repos.return_value = [
249+
{"id": 1, "full_name": "testorg/repo1"},
250+
{"id": 2, "full_name": "testorg/repo2"},
251+
]
252+
253+
with self.feature(
254+
["organizations:github-repo-auto-sync", "organizations:github-repo-auto-sync-apply"]
255+
):
256+
sync_repos_for_org(oi.id)
257+
258+
with assume_test_silo_mode(SiloMode.CELL):
259+
repos = Repository.objects.filter(organization_id=self.organization.id).order_by("name")
260+
261+
assert len(repos) == 2
262+
assert repos[0].provider == "integrations:github_enterprise"

tests/sentry/integrations/github_enterprise/test_webhooks.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414
PULL_REQUEST_OPENED_EVENT_EXAMPLE,
1515
PUSH_EVENT_EXAMPLE_INSTALLATION,
1616
)
17+
from sentry.integrations.github_enterprise.webhook import (
18+
GitHubEnterpriseInstallationRepositoriesEventWebhook,
19+
)
1720
from sentry.integrations.services.integration import integration_service
1821
from sentry.models.commit import Commit
1922
from sentry.models.commitauthor import CommitAuthor
@@ -253,6 +256,66 @@ def test_missing_signature_fail_without_option_set(self, mock_installation: Magi
253256
assert b"Missing headers X-Hub-Signature-256 or X-Hub-Signature" in response.content
254257

255258

259+
@patch("sentry.integrations.github_enterprise.client.get_jwt")
260+
@patch("sentry.integrations.github_enterprise.webhook.get_installation_metadata")
261+
class InstallationRepositoriesEventWebhookTest(APITestCase):
262+
def setUp(self) -> None:
263+
self.url = "/extensions/github-enterprise/webhook/"
264+
self.metadata = {
265+
"url": "35.232.149.196",
266+
"id": "2",
267+
"name": "test-app",
268+
"webhook_secret": "b3002c3e321d4b7880360d397db2ccfd",
269+
"private_key": "private_key",
270+
"verify_ssl": True,
271+
}
272+
273+
@patch(
274+
"sentry.integrations.github.tasks.sync_repos_on_install_change.sync_repos_on_install_change.apply_async"
275+
)
276+
def test_handler_dispatches_task_with_ghe_provider(
277+
self,
278+
mock_apply_async: MagicMock,
279+
mock_get_installation_metadata: MagicMock,
280+
mock_get_jwt: MagicMock,
281+
) -> None:
282+
"""Verify the GHE handler looks up integrations with the correct provider."""
283+
mock_get_jwt.return_value = ""
284+
mock_get_installation_metadata.return_value = self.metadata
285+
286+
integration = self.create_integration(
287+
external_id="35.232.149.196:12345",
288+
organization=self.project.organization,
289+
provider="github_enterprise",
290+
metadata={
291+
"domain_name": "35.232.149.196/testorg",
292+
"installation_id": "12345",
293+
"installation": {
294+
"id": "2",
295+
"private_key": "private_key",
296+
"verify_ssl": True,
297+
},
298+
},
299+
)
300+
301+
handler = GitHubEnterpriseInstallationRepositoriesEventWebhook()
302+
handler(
303+
event={
304+
"installation": {"id": 12345},
305+
"action": "added",
306+
"repositories_added": [{"id": 1, "full_name": "testorg/repo", "private": False}],
307+
"repositories_removed": [],
308+
"repository_selection": "selected",
309+
"sender": {"id": 1, "login": "testuser"},
310+
},
311+
host="35.232.149.196",
312+
)
313+
314+
mock_apply_async.assert_called_once()
315+
kwargs = mock_apply_async.call_args[1]["kwargs"]
316+
assert kwargs["integration_id"] == integration.id
317+
318+
256319
@patch("sentry.integrations.github_enterprise.client.get_jwt")
257320
@patch("sentry.integrations.github_enterprise.webhook.get_installation_metadata")
258321
class PushEventWebhookTest(APITestCase):

0 commit comments

Comments
 (0)