Skip to content

Commit f1e7ca7

Browse files
authored
delete commits when deleting repos (#5292)
1 parent cbb023b commit f1e7ca7

File tree

3 files changed

+99
-5
lines changed

3 files changed

+99
-5
lines changed

src/sentry/api/endpoints/organization_repository_details.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from sentry.api.serializers import serialize
1313
from sentry.constants import ObjectStatus
1414
from sentry.models import Repository
15-
from sentry.tasks.deletion import generic_delete
15+
from sentry.tasks.deletion import delete_repository
1616

1717
delete_logger = logging.getLogger('sentry.deletions.api')
1818

@@ -75,10 +75,8 @@ def delete(self, request, organization, repo_id):
7575
transaction_id = uuid4().hex
7676
countdown = 86400
7777

78-
generic_delete.apply_async(
78+
delete_repository.apply_async(
7979
kwargs={
80-
'app_label': Repository._meta.app_label,
81-
'model_name': Repository._meta.model_name,
8280
'object_id': repo.id,
8381
'transaction_id': transaction_id,
8482
'actor_id': request.user.id,

src/sentry/tasks/deletion.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -504,3 +504,49 @@ def delete_objects(models, relation, transaction_id=None, limit=100, logger=None
504504
if has_more:
505505
return True
506506
return has_more
507+
508+
509+
@instrumented_task(name='sentry.tasks.deletion.delete_repository', queue='cleanup',
510+
default_retry_delay=60 * 5, max_retries=None)
511+
@retry(exclude=(DeleteAborted,))
512+
def delete_repository(object_id, transaction_id=None, continuous=True,
513+
actor_id=None, **kwargs):
514+
from sentry.models import Commit, Repository, User
515+
516+
try:
517+
repo = Repository.objects.get(id=object_id)
518+
except Repository.DoesNotExist:
519+
return
520+
521+
if repo.status == ObjectStatus.VISIBLE:
522+
raise DeleteAborted
523+
524+
if repo.status == ObjectStatus.PENDING_DELETION:
525+
if actor_id:
526+
actor = User.objects.get(id=actor_id)
527+
else:
528+
actor = None
529+
repo.update(status=ObjectStatus.DELETION_IN_PROGRESS)
530+
pending_delete.send(sender=Repository, instance=repo, actor=actor)
531+
532+
has_more = delete_objects(
533+
(Commit,),
534+
transaction_id=transaction_id,
535+
relation={'repository_id': repo.id},
536+
logger=logger,
537+
)
538+
if has_more:
539+
if continuous:
540+
delete_repository.apply_async(
541+
kwargs={'object_id': object_id, 'transaction_id': transaction_id},
542+
countdown=15,
543+
)
544+
return
545+
546+
repo_id = repo.id
547+
repo.delete()
548+
logger.info('object.delete.executed', extra={
549+
'object_id': repo_id,
550+
'transaction_id': transaction_id,
551+
'model': Repository.__name__,
552+
})

tests/sentry/tasks/test_deletion.py

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
)
1717
from sentry.tasks.deletion import (
1818
delete_api_application, delete_group, delete_organization, delete_project,
19-
delete_tag_key, delete_team, generic_delete, revoke_api_tokens
19+
delete_repository, delete_tag_key, delete_team, generic_delete, revoke_api_tokens
2020
)
2121
from sentry.testutils import TestCase
2222

@@ -369,3 +369,53 @@ def test_deletes(self):
369369
generic_delete('sentry', 'project', object_id=project.id)
370370

371371
assert not Project.objects.filter(id=project.id).exists()
372+
373+
374+
class DeleteRepoTest(TestCase):
375+
def test_does_not_delete_visible(self):
376+
org = self.create_organization()
377+
repo = Repository.objects.create(
378+
status=ObjectStatus.VISIBLE,
379+
provider='dummy',
380+
organization_id=org.id,
381+
name='example/example',
382+
)
383+
384+
with self.tasks():
385+
with pytest.raises(DeleteAborted):
386+
delete_repository(object_id=repo.id)
387+
388+
repo = Repository.objects.get(id=repo.id)
389+
assert repo.status == ObjectStatus.VISIBLE
390+
391+
def test_deletes(self):
392+
org = self.create_organization()
393+
repo = Repository.objects.create(
394+
status=ObjectStatus.PENDING_DELETION,
395+
organization_id=org.id,
396+
provider='dummy',
397+
name='example/example',
398+
)
399+
repo2 = Repository.objects.create(
400+
status=ObjectStatus.PENDING_DELETION,
401+
organization_id=org.id,
402+
provider='dummy',
403+
name='example/example2',
404+
)
405+
commit = Commit.objects.create(
406+
repository_id=repo.id,
407+
organization_id=org.id,
408+
key='1234abcd',
409+
)
410+
commit2 = Commit.objects.create(
411+
repository_id=repo2.id,
412+
organization_id=org.id,
413+
key='1234abcd',
414+
)
415+
416+
with self.tasks():
417+
delete_repository(object_id=repo.id)
418+
419+
assert not Repository.objects.filter(id=repo.id).exists()
420+
assert not Commit.objects.filter(id=commit.id).exists()
421+
assert Commit.objects.filter(id=commit2.id).exists()

0 commit comments

Comments
 (0)