|
6 | 6 | from urllib.parse import urlparse |
7 | 7 |
|
8 | 8 | from django import forms |
| 9 | +from django.db import transaction |
9 | 10 | from django.http.request import HttpRequest |
10 | 11 | from django.http.response import HttpResponseBase |
11 | 12 | from django.urls import reverse |
@@ -355,30 +356,34 @@ def update_organization_config(self, data: MutableMapping[str, Any]) -> None: |
355 | 356 |
|
356 | 357 | data["sync_status_forward"] = bool(project_mappings) |
357 | 358 |
|
358 | | - IntegrationExternalProject.objects.filter( |
359 | | - organization_integration_id=self.org_integration.id |
360 | | - ).delete() |
361 | | - |
362 | | - for project_path, statuses in project_mappings.items(): |
363 | | - # Validate status values |
364 | | - valid_statuses = {GitLabIssueStatus.OPENED.value, GitLabIssueStatus.CLOSED.value} |
365 | | - if statuses["on_resolve"] not in valid_statuses: |
366 | | - raise IntegrationError( |
367 | | - f"Invalid resolve status: {statuses['on_resolve']}. Must be 'opened' or 'closed'." |
368 | | - ) |
369 | | - if statuses["on_unresolve"] not in valid_statuses: |
370 | | - raise IntegrationError( |
371 | | - f"Invalid unresolve status: {statuses['on_unresolve']}. Must be 'opened' or 'closed'." |
| 359 | + with transaction.atomic(): |
| 360 | + IntegrationExternalProject.objects.filter( |
| 361 | + organization_integration_id=self.org_integration.id |
| 362 | + ).delete() |
| 363 | + |
| 364 | + for project_path, statuses in project_mappings.items(): |
| 365 | + # Validate status values |
| 366 | + valid_statuses = { |
| 367 | + GitLabIssueStatus.OPENED.value, |
| 368 | + GitLabIssueStatus.CLOSED.value, |
| 369 | + } |
| 370 | + if statuses["on_resolve"] not in valid_statuses: |
| 371 | + raise IntegrationError( |
| 372 | + f"Invalid resolve status: {statuses['on_resolve']}. Must be 'opened' or 'closed'." |
| 373 | + ) |
| 374 | + if statuses["on_unresolve"] not in valid_statuses: |
| 375 | + raise IntegrationError( |
| 376 | + f"Invalid unresolve status: {statuses['on_unresolve']}. Must be 'opened' or 'closed'." |
| 377 | + ) |
| 378 | + |
| 379 | + IntegrationExternalProject.objects.create( |
| 380 | + organization_integration_id=self.org_integration.id, |
| 381 | + external_id=project_path, |
| 382 | + name=project_path, |
| 383 | + resolved_status=statuses["on_resolve"], |
| 384 | + unresolved_status=statuses["on_unresolve"], |
372 | 385 | ) |
373 | 386 |
|
374 | | - IntegrationExternalProject.objects.create( |
375 | | - organization_integration_id=self.org_integration.id, |
376 | | - external_id=project_path, |
377 | | - name=project_path, |
378 | | - resolved_status=statuses["on_resolve"], |
379 | | - unresolved_status=statuses["on_unresolve"], |
380 | | - ) |
381 | | - |
382 | 387 | # Check webhook version BEFORE updating config to determine if migration is needed |
383 | 388 | current_webhook_version = config.get(GITLAB_WEBHOOK_VERSION_KEY, 0) |
384 | 389 |
|
|
0 commit comments