Skip to content

Commit 770a82e

Browse files
committed
Report build status in a smarter way
It could happen that the person that has imported the project does not have permissions anymore to send Build Status to the social service (e.g. GitHub). In that case, we were just skipping the report to the service completely. On the other hand, if the project didn't have a RemoreRepository, we were trying using all the mantainers' accounts to report the status. This commit uses the same re-trying code, but also when the first attempt using the account of the user that imported the repository, failed.
1 parent 8eb41fd commit 770a82e

File tree

1 file changed

+62
-35
lines changed

1 file changed

+62
-35
lines changed

readthedocs/projects/tasks.py

Lines changed: 62 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -2137,62 +2137,89 @@ def send_build_status(build_pk, commit, status):
21372137
"""
21382138
Send Build Status to Git Status API for project external versions.
21392139
2140+
It tries using these services' account in order:
2141+
2142+
1. user's account that imported the project
2143+
2. each user's account from the project's maintainers
2144+
21402145
:param build_pk: Build primary key
21412146
:param commit: commit sha of the pull/merge request
21422147
:param status: build status failed, pending, or success to be sent.
21432148
"""
2149+
# TODO: Send build status for BitBucket.
2150+
service = None
2151+
success = None
21442152
build = Build.objects.get(pk=build_pk)
21452153
provider_name = build.project.git_provider_name
21462154

21472155
if provider_name in [GITHUB_BRAND, GITLAB_BRAND]:
21482156
# get the service class for the project e.g: GitHubService.
21492157
service_class = build.project.git_service_class()
2158+
2159+
# First, try using user who imported the project's account
21502160
try:
21512161
service = service_class(
21522162
build.project.remote_repository.users.first(),
21532163
build.project.remote_repository.account
21542164
)
2155-
# Send status report using the API.
2156-
service.send_build_status(build, commit, status)
2157-
21582165
except RemoteRepository.DoesNotExist:
2159-
users = build.project.users.all()
2160-
2161-
# Try to loop through all project users to get their social accounts
2162-
for user in users:
2163-
user_accounts = service_class.for_user(user)
2164-
# Try to loop through users all social accounts to send a successful request
2165-
for account in user_accounts:
2166-
# Currently we only support GitHub Status API
2167-
if account.provider_name == provider_name:
2168-
success = account.send_build_status(build, commit, status)
2169-
if success:
2170-
return True
2171-
2172-
for user in users:
2173-
# Send Site notification about Build status reporting failure
2174-
# to all the users of the project.
2175-
notification = GitBuildStatusFailureNotification(
2176-
context_object=build.project,
2177-
extra_context={'provider_name': provider_name},
2178-
user=user,
2179-
success=False,
2180-
)
2181-
notification.send()
2166+
log.warning(
2167+
'Project does not have a RemoteRepository. project= %s',
2168+
build.project.slug,
2169+
)
21822170

2171+
if service is not None:
2172+
# Send status report using the API.
2173+
success = service.send_build_status(build, commit, status)
2174+
2175+
if success:
21832176
log.info(
2184-
'No social account or repository permission available for %s',
2185-
build.project.slug
2177+
'Build status report sent correctly. project=%s build=%s status=%s commit=%s',
2178+
build.project.slug,
2179+
build.pk,
2180+
status,
2181+
commit,
21862182
)
2187-
return False
2188-
2189-
except Exception:
2190-
log.exception('Send build status task failed for %s', build.project.slug)
2191-
return False
2183+
return True
21922184

2193-
return False
2185+
# Try using any of the users' maintainer accounts
2186+
# Try to loop through all project users to get their social accounts
2187+
users = build.project.users.all()
2188+
for user in users:
2189+
user_accounts = service_class.for_user(user)
2190+
# Try to loop through users all social accounts to send a successful request
2191+
for account in user_accounts:
2192+
# Currently we only support GitHub Status API
2193+
if account.provider_name == provider_name:
2194+
success = account.send_build_status(build, commit, status)
2195+
if success:
2196+
log.info(
2197+
'Build status report sent correctly using an user account. '
2198+
'project=%s build=%s status=%s commit=%s user=%s',
2199+
build.project.slug,
2200+
build.pk,
2201+
status,
2202+
commit,
2203+
user.username,
2204+
)
2205+
return True
2206+
2207+
for user in users:
2208+
# Send Site notification about Build status reporting failure
2209+
# to all the users of the project.
2210+
notification = GitBuildStatusFailureNotification(
2211+
context_object=build.project,
2212+
extra_context={'provider_name': provider_name},
2213+
user=user,
2214+
success=False,
2215+
)
2216+
notification.send()
21942217

2195-
# TODO: Send build status for BitBucket.
2218+
log.info(
2219+
'No social account or repository permission available for %s',
2220+
build.project.slug
2221+
)
2222+
return False
21962223

21972224

21982225
def send_external_build_status(version_type, build_pk, commit, status):

0 commit comments

Comments
 (0)