30
30
)
31
31
from readthedocs .builds .models import Build , Version
32
32
from readthedocs .builds .utils import memcache_lock
33
- from readthedocs .core .permissions import AdminPermission
34
33
from readthedocs .core .utils import send_email , trigger_build
35
34
from readthedocs .integrations .models import HttpExchange
36
35
from readthedocs .notifications .models import Notification
37
36
from readthedocs .oauth .notifications import MESSAGE_OAUTH_BUILD_STATUS_FAILURE
38
- from readthedocs .projects .constants import GITHUB_BRAND , GITLAB_BRAND
39
37
from readthedocs .projects .models import Project , WebHookEvent
40
38
from readthedocs .storage import build_commands_storage
41
39
from readthedocs .worker import app
@@ -385,24 +383,16 @@ def sync_versions_task(project_pk, tags_data, branches_data, **kwargs):
385
383
@app .task (max_retries = 3 , default_retry_delay = 60 , queue = "web" )
386
384
def send_build_status (build_pk , commit , status ):
387
385
"""
388
- Send Build Status to Git Status API for project external versions.
389
-
390
- It tries using these services' account in order:
391
-
392
- 1. user's account that imported the project
393
- 2. each user's account from the project's maintainers
386
+ Send build status to GitHub/GitLab for a given build/commit.
394
387
395
388
:param build_pk: Build primary key
396
389
:param commit: commit sha of the pull/merge request
397
390
:param status: build status failed, pending, or success to be sent.
398
391
"""
399
- # TODO: Send build status for Bitbucket.
400
392
build = Build .objects .filter (pk = build_pk ).first ()
401
393
if not build :
402
394
return
403
395
404
- provider_name = build .project .git_provider_name
405
-
406
396
log .bind (
407
397
build_id = build .pk ,
408
398
project_slug = build .project .slug ,
@@ -412,76 +402,42 @@ def send_build_status(build_pk, commit, status):
412
402
413
403
log .debug ("Sending build status." )
414
404
415
- if provider_name in [GITHUB_BRAND , GITLAB_BRAND ]:
416
- # get the service class for the project e.g: GitHubService.
417
- service_class = build .project .git_service_class ()
418
- users = AdminPermission .admins (build .project )
419
-
420
- if build .project .remote_repository :
421
- remote_repository = build .project .remote_repository
422
- remote_repository_relations = (
423
- remote_repository .remote_repository_relations .filter (
424
- account__isnull = False ,
425
- # Use ``user_in=`` instead of ``user__projects=`` here
426
- # because User's are not related to Project's directly in
427
- # Read the Docs for Business
428
- user__in = AdminPermission .members (build .project ),
429
- )
430
- .select_related ("account" , "user" )
431
- .only ("user" , "account" )
432
- )
405
+ # Get the service class for the project e.g: GitHubService.
406
+ # We fallback to guess the service from the repo,
407
+ # in the future we should only consider projects that have a remote repository.
408
+ service_class = build .project .get_git_service_class (fallback_to_clone_url = True )
409
+ if not service_class :
410
+ log .info ("Project isn't connected to a Git service, not sending build status." )
411
+ return False
433
412
434
- # Try using any of the users' maintainer accounts
435
- # Try to loop through all remote repository relations for the projects users
436
- for relation in remote_repository_relations :
437
- service = service_class (relation .user , relation .account )
438
- # Send status report using the API.
439
- success = service .send_build_status (
440
- build ,
441
- commit ,
442
- status ,
443
- )
413
+ if not service_class .supports_build_status :
414
+ log .info ("Git service doesn't support build status." )
415
+ return False
444
416
445
- if success :
446
- log .debug (
447
- "Build status report sent correctly." ,
448
- user_username = relation .user .username ,
449
- )
450
- return True
451
- else :
452
- log .warning ("Project does not have a RemoteRepository." )
453
- # Try to send build status for projects with no RemoteRepository
454
- for user in users :
455
- services = service_class .for_user (user )
456
- # Try to loop through services for users all social accounts
457
- # to send successful build status
458
- for service in services :
459
- success = service .send_build_status (
460
- build ,
461
- commit ,
462
- status ,
463
- )
464
- if success :
465
- log .debug (
466
- "Build status report sent correctly using an user account." ,
467
- user_username = user .username ,
468
- )
469
- return True
470
-
471
- # NOTE: this notifications was attached to every user.
472
- # Now, I'm attaching it to the project itself since it's a problem at project level.
473
- Notification .objects .add (
474
- message_id = MESSAGE_OAUTH_BUILD_STATUS_FAILURE ,
475
- attached_to = build .project ,
476
- format_values = {
477
- "provider_name" : provider_name ,
478
- "url_connect_account" : reverse ("socialaccount_connections" ),
479
- },
480
- dismissable = True ,
417
+ for service in service_class .for_project (build .project ):
418
+ success = service .send_build_status (
419
+ build ,
420
+ commit ,
421
+ status ,
481
422
)
423
+ if success :
424
+ log .debug ("Build status report sent correctly." )
425
+ return True
426
+
427
+ Notification .objects .add (
428
+ message_id = MESSAGE_OAUTH_BUILD_STATUS_FAILURE ,
429
+ attached_to = build .project ,
430
+ format_values = {
431
+ "provider_name" : service_class .provider_name ,
432
+ "url_connect_account" : reverse ("socialaccount_connections" ),
433
+ },
434
+ dismissable = True ,
435
+ )
482
436
483
- log .info ("No social account or repository permission available." )
484
- return False
437
+ log .info (
438
+ "No social account or repository permission available, no build status sent."
439
+ )
440
+ return False
485
441
486
442
487
443
@app .task (queue = "web" )
0 commit comments