Skip to content

Commit c74d294

Browse files
committed
Initial changes for PR Builder
1 parent 1207afb commit c74d294

File tree

5 files changed

+90
-6
lines changed

5 files changed

+90
-6
lines changed

readthedocs/api/v2/utils.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@
1313
STABLE,
1414
STABLE_VERBOSE_NAME,
1515
TAG,
16+
EXTERNAL,
1617
)
18+
from readthedocs.core.utils import trigger_build
1719
from readthedocs.builds.models import Version
1820

1921

@@ -77,6 +79,15 @@ def sync_versions(project, versions, type): # pylint: disable=redefined-builtin
7779
version_name,
7880
version_id,
7981
)
82+
elif type == EXTERNAL:
83+
created_version = Version.objects.create(
84+
project=project,
85+
type=type,
86+
identifier=version_id,
87+
verbose_name=version_name,
88+
)
89+
added.add(created_version.slug)
90+
8091
else:
8192
# New Version
8293
created_version = Version.objects.create(
@@ -135,6 +146,9 @@ def delete_versions(project, version_data):
135146
versions_tags = [
136147
version['verbose_name'] for version in version_data.get('tags', [])
137148
]
149+
external_versions = [
150+
version['verbose_name'] for version in version_data.get('external_branches', [])
151+
]
138152
versions_branches = [
139153
version['identifier'] for version in version_data.get('branches', [])
140154
]
@@ -147,6 +161,10 @@ def delete_versions(project, version_data):
147161
type=BRANCH,
148162
identifier__in=versions_branches,
149163
)
164+
to_delete_qs = to_delete_qs.exclude(
165+
type=EXTERNAL,
166+
verbose_name__in=external_versions,
167+
)
150168
to_delete_qs = to_delete_qs.exclude(uploaded=True)
151169
to_delete_qs = to_delete_qs.exclude(active=True)
152170
to_delete_qs = to_delete_qs.exclude(slug__in=NON_REPOSITORY_VERSIONS)
@@ -176,6 +194,21 @@ def run_automation_rules(project, versions_slug):
176194
rule.run(version)
177195

178196

197+
def trigger_external_build(project, version_list):
198+
"""
199+
Trigger Builds for all external versions provided.
200+
201+
The rules are sorted by priority.
202+
203+
"""
204+
for version_slug in version_list:
205+
version = project.versions(manager=EXTERNAL).get(slug=version_slug)
206+
version.active = True
207+
version.save()
208+
209+
trigger_build(project=project, version=version)
210+
211+
179212
class RemoteOrganizationPagination(PageNumberPagination):
180213
page_size = 25
181214

readthedocs/api/v2/views/integrations.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@
2929
GITHUB_EVENT_HEADER = 'HTTP_X_GITHUB_EVENT'
3030
GITHUB_SIGNATURE_HEADER = 'HTTP_X_HUB_SIGNATURE'
3131
GITHUB_PUSH = 'push'
32+
GITHUB_PULL_REQUEST = 'pull_request'
33+
GITHUB_PULL_REQUEST_OPEN = 'open'
34+
GITHUB_PULL_REQUEST_SYNC = 'synchronize'
3235
GITHUB_CREATE = 'create'
3336
GITHUB_DELETE = 'delete'
3437
GITLAB_TOKEN_HEADER = 'HTTP_X_GITLAB_TOKEN'
@@ -271,6 +274,10 @@ def handle_webhook(self):
271274
raise ParseError('Parameter "ref" is required')
272275
if event in (GITHUB_CREATE, GITHUB_DELETE):
273276
return self.sync_versions(self.project)
277+
278+
if event == GITHUB_PULL_REQUEST:
279+
return self.sync_versions(self.project)
280+
274281
return None
275282

276283
def _normalize_ref(self, ref):

readthedocs/api/v2/views/model_views.py

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from rest_framework.renderers import BaseRenderer, JSONRenderer
1111
from rest_framework.response import Response
1212

13-
from readthedocs.builds.constants import BRANCH, TAG, INTERNAL
13+
from readthedocs.builds.constants import BRANCH, TAG, INTERNAL, EXTERNAL
1414
from readthedocs.builds.models import Build, BuildCommandResult, Version
1515
from readthedocs.core.utils import trigger_build
1616
from readthedocs.core.utils.extend import SettingsOverrideObject
@@ -189,6 +189,7 @@ def sync_versions(self, request, **kwargs): # noqa: D205
189189
# Update All Versions
190190
data = request.data
191191
added_versions = set()
192+
added_external_versions = set()
192193
if 'tags' in data:
193194
ret_set = api_utils.sync_versions(
194195
project=project,
@@ -203,6 +204,15 @@ def sync_versions(self, request, **kwargs): # noqa: D205
203204
type=BRANCH,
204205
)
205206
added_versions.update(ret_set)
207+
208+
if 'external_branches' in data:
209+
ret_set = api_utils.sync_versions(
210+
project=project,
211+
versions=data['external_branches'],
212+
type=EXTERNAL,
213+
)
214+
added_external_versions.update(ret_set)
215+
206216
deleted_versions = api_utils.delete_versions(project, data)
207217
except Exception as e:
208218
log.exception('Sync Versions Error')
@@ -213,11 +223,13 @@ def sync_versions(self, request, **kwargs): # noqa: D205
213223
status=status.HTTP_400_BAD_REQUEST,
214224
)
215225

226+
all_added_versions = added_versions | added_external_versions
227+
216228
try:
217229
# The order of added_versions isn't deterministic.
218230
# We don't track the commit time or any other metadata.
219231
# We usually have one version added per webhook.
220-
api_utils.run_automation_rules(project, added_versions)
232+
api_utils.run_automation_rules(project, all_added_versions)
221233
except Exception:
222234
# Don't interrupt the request if something goes wrong
223235
# in the automation rules.
@@ -226,6 +238,12 @@ def sync_versions(self, request, **kwargs): # noqa: D205
226238
project.slug, added_versions
227239
)
228240

241+
if added_external_versions:
242+
api_utils.trigger_external_build(
243+
project=project,
244+
version_list=added_external_versions
245+
)
246+
229247
# TODO: move this to an automation rule
230248
promoted_version = project.update_stable_version()
231249
new_stable = project.get_stable_version()
@@ -250,7 +268,7 @@ def sync_versions(self, request, **kwargs): # noqa: D205
250268
trigger_build(project=project, version=promoted_version)
251269

252270
return Response({
253-
'added_versions': added_versions,
271+
'added_versions': all_added_versions,
254272
'deleted_versions': deleted_versions,
255273
})
256274

readthedocs/projects/tasks.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,12 @@ def sync_versions(self, version_repo):
165165
'verbose_name': v.verbose_name,
166166
} for v in version_repo.branches]
167167

168+
if version_repo.supports_external_branches:
169+
version_post_data['external_branches'] = [{
170+
'identifier': v.identifier,
171+
'verbose_name': v.verbose_name,
172+
} for v in version_repo.external_branches]
173+
168174
self.validate_duplicate_reserved_versions(version_post_data)
169175

170176
try:

readthedocs/vcs_support/backends/git.py

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ class Backend(BaseVCS):
2626

2727
supports_tags = True
2828
supports_branches = True
29+
supports_external_branches = True
2930
supports_submodules = True
3031
fallback_branch = 'master' # default branch
3132
repo_depth = 50
@@ -213,11 +214,30 @@ def branches(self):
213214

214215
for branch in branches:
215216
verbose_name = branch.name
216-
if verbose_name.startswith('origin/'):
217+
if not verbose_name.startswith('origin/external/'):
218+
if verbose_name.startswith('origin/'):
219+
verbose_name = verbose_name.replace('origin/', '')
220+
if verbose_name == 'HEAD':
221+
continue
222+
versions.append(VCSVersion(self, str(branch), verbose_name))
223+
return versions
224+
225+
@property
226+
def external_branches(self):
227+
repo = git.Repo(self.working_dir)
228+
versions = []
229+
branches = []
230+
231+
# ``repo.remotes.origin.refs`` returns remote branches
232+
if repo.remotes:
233+
branches += repo.remotes.origin.refs
234+
235+
for branch in branches:
236+
verbose_name = branch.name
237+
if verbose_name.startswith('origin/external/'):
217238
verbose_name = verbose_name.replace('origin/', '')
218-
if verbose_name == 'HEAD':
239+
versions.append(VCSVersion(self, str(branch.commit), verbose_name))
219240
continue
220-
versions.append(VCSVersion(self, str(branch), verbose_name))
221241
return versions
222242

223243
@property

0 commit comments

Comments
 (0)