1
1
from __future__ import annotations
2
2
3
3
import logging
4
- from collections .abc import Mapping
5
4
from enum import StrEnum
6
5
from typing import Any
7
6
10
9
from sentry import eventstore
11
10
from sentry .integrations .base import IntegrationInstallation
12
11
from sentry .integrations .models .repository_project_path_config import RepositoryProjectPathConfig
13
- from sentry .integrations .services .integration import RpcOrganizationIntegration
14
12
from sentry .integrations .source_code_management .metrics import (
15
13
SCMIntegrationInteractionEvent ,
16
14
SCMIntegrationInteractionType ,
@@ -85,7 +83,7 @@ def process_event(project_id: int, group_id: int, event_id: str) -> list[CodeMap
85
83
trees_helper = CodeMappingTreesHelper (trees )
86
84
code_mappings = trees_helper .generate_code_mappings (frames_to_process , platform )
87
85
dry_run = platform_config .is_dry_run_platform ()
88
- create_configurations (code_mappings , installation , project , platform , dry_run )
86
+ create_repos_and_code_mappings (code_mappings , installation , project , platform , dry_run )
89
87
except (InstallationNotFoundError , InstallationCannotGetTreesError ):
90
88
pass
91
89
@@ -162,7 +160,7 @@ def get_trees_for_org(
162
160
return trees
163
161
164
162
165
- def create_configurations (
163
+ def create_repos_and_code_mappings (
166
164
code_mappings : list [CodeMapping ],
167
165
installation : IntegrationInstallation ,
168
166
project : Project ,
@@ -179,59 +177,57 @@ def create_configurations(
179
177
180
178
organization_id = organization_integration .organization_id
181
179
for code_mapping in code_mappings :
182
- process_code_mapping (
183
- organization_id ,
184
- organization_integration ,
185
- project ,
186
- code_mapping ,
187
- platform ,
188
- dry_run ,
180
+ repository = (
181
+ Repository .objects .filter (name = code_mapping .repo .name , organization_id = organization_id )
182
+ .order_by ("-date_added" )
183
+ .first ()
189
184
)
190
185
191
-
192
- def process_code_mapping (
193
- organization_id : int ,
194
- organization_integration : RpcOrganizationIntegration ,
195
- project : Project ,
196
- code_mapping : CodeMapping ,
197
- platform : str ,
198
- dry_run : bool ,
199
- ) -> None :
200
- repository = (
201
- Repository .objects .filter (name = code_mapping .repo .name , organization_id = organization_id )
202
- .order_by ("-date_added" )
203
- .first ()
204
- )
205
-
206
- if not repository and not dry_run :
207
- repository = Repository .objects .create (
208
- name = code_mapping .repo .name ,
209
- organization_id = organization_id ,
210
- integration_id = organization_integration .integration_id ,
186
+ if not repository :
187
+ if not dry_run :
188
+ repository = Repository .objects .create (
189
+ name = code_mapping .repo .name ,
190
+ organization_id = organization_id ,
191
+ integration_id = organization_integration .integration_id ,
192
+ )
193
+ metrics .incr (
194
+ key = f"{ METRIC_PREFIX } .repository.created" ,
195
+ tags = {"platform" : platform , "dry_run" : dry_run },
196
+ sample_rate = 1.0 ,
197
+ )
198
+
199
+ extra = {
200
+ "project_id" : project .id ,
201
+ "stack_root" : code_mapping .stacktrace_root ,
202
+ "repository_name" : code_mapping .repo .name ,
203
+ }
204
+ # The project and stack_root are unique together
205
+ existing_code_mappings = RepositoryProjectPathConfig .objects .filter (
206
+ project = project , stack_root = code_mapping .stacktrace_root
211
207
)
212
-
213
- create_code_mapping ( code_mapping , project , repository , organization_integration , dry_run )
214
- tags : Mapping [ str , str | bool ] = { "platform" : platform , "dry_run" : dry_run }
215
- metrics . incr ( key = f" { METRIC_PREFIX } .code_mapping.created" , tags = tags , sample_rate = 1.0 )
216
- metrics . incr ( key = f" { METRIC_PREFIX } .repository.created" , tags = tags , sample_rate = 1.0 )
217
-
218
-
219
- def create_code_mapping (
220
- code_mapping : CodeMapping ,
221
- project : Project ,
222
- repository : Repository | None ,
223
- organization_integration : RpcOrganizationIntegration ,
224
- dry_run : bool ,
225
- ) -> None :
226
- if not dry_run and repository :
227
- RepositoryProjectPathConfig . objects . create (
228
- project = project ,
229
- stack_root = code_mapping .stacktrace_root ,
230
- repository = repository ,
231
- organization_integration_id = organization_integration . id ,
232
- integration_id = organization_integration . integration_id ,
233
- organization_id = organization_integration . organization_id ,
234
- source_root = code_mapping .source_path ,
235
- default_branch = code_mapping . repo . branch ,
236
- automatically_generated = True ,
208
+ if existing_code_mappings . exists ():
209
+ logger . warning ( "Investigate." , extra = extra )
210
+ continue
211
+
212
+ if not dry_run :
213
+ if repository is None : # This is mostly to appease the type checker
214
+ logger . warning ( "Investigate." , extra = extra )
215
+ continue
216
+
217
+ RepositoryProjectPathConfig . objects . create (
218
+ project = project ,
219
+ stack_root = code_mapping . stacktrace_root ,
220
+ repository = repository ,
221
+ organization_integration_id = organization_integration . id ,
222
+ integration_id = organization_integration . integration_id ,
223
+ organization_id = organization_integration . organization_id ,
224
+ source_root = code_mapping . source_path ,
225
+ default_branch = code_mapping .repo . branch ,
226
+ automatically_generated = True ,
227
+ )
228
+
229
+ metrics . incr (
230
+ key = f" { METRIC_PREFIX } . code_mapping.created" ,
231
+ tags = { "platform" : platform , "dry_run" : dry_run } ,
232
+ sample_rate = 1.0 ,
237
233
)
0 commit comments