Skip to content

Commit deb877d

Browse files
committed
Split trigger_build to be able to prepare_build first
Added a ``ImportWizard.trigger_initial_build`` method to be override from corporate site. Also, instead of using ``trigger_build`` to create the Celery task and call it immediately, split it to use ``prepare_build`` first to create the task and use ``trigger_build`` to effectively triggers it.
1 parent 2f4a4cc commit deb877d

File tree

3 files changed

+59
-19
lines changed

3 files changed

+59
-19
lines changed

common

readthedocs/core/utils/__init__.py

Lines changed: 51 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
# -*- coding: utf-8 -*-
12
"""Common utilty functions."""
23

34
from __future__ import absolute_import
@@ -16,7 +17,7 @@
1617
from future.backports.urllib.parse import urlparse
1718
from celery import group, chord
1819

19-
from readthedocs.builds.constants import LATEST
20+
from readthedocs.builds.constants import LATEST, BUILD_STATE_TRIGGERED
2021
from readthedocs.doc_builder.constants import DOCKER_LIMITS
2122

2223

@@ -75,37 +76,48 @@ def cname_to_slug(host):
7576
return slug
7677

7778

78-
def trigger_build(project, version=None, record=True, force=False):
79+
def prepare_build(
80+
project, version=None, record=True, force=False, immutable=True):
7981
"""
80-
Trigger build for project and version.
82+
Prepare a build in a Celery task for project and version.
83+
84+
If project has a ``build_queue``, execute the task on this build queue. If
85+
project has ``skip=True``, the build is not triggered.
8186
82-
If project has a ``build_queue``, execute task on this build queue. Queue
83-
will be prefixed with ``build-`` to unify build queue names.
87+
:param project: project's documentation to be built
88+
:param version: version of the project to be built. Default: ``latest``
89+
:param record: whether or not record the build in a new Build object
90+
:param force: build the HTML documentation even if the files haven't changed
91+
:param immutable: whether or not create an immutable Celery signature
92+
:returns: Celery signature of UpdateDocsTask to be executed
8493
"""
8594
# Avoid circular import
8695
from readthedocs.projects.tasks import UpdateDocsTask
8796
from readthedocs.builds.models import Build
8897

8998
if project.skip:
99+
log.info(
100+
'Build not triggered because Project.skip=True: project=%s',
101+
project.slug,
102+
)
90103
return None
91104

92105
if not version:
93106
version = project.versions.get(slug=LATEST)
94107

95-
kwargs = dict(
96-
pk=project.pk,
97-
version_pk=version.pk,
98-
record=record,
99-
force=force,
100-
)
108+
kwargs = {
109+
'pk': project.pk,
110+
'version_pk': version.pk,
111+
'record': record,
112+
'force': force,
113+
}
101114

102-
build = None
103115
if record:
104116
build = Build.objects.create(
105117
project=project,
106118
version=version,
107119
type='html',
108-
state='triggered',
120+
state=BUILD_STATE_TRIGGERED,
109121
success=True,
110122
)
111123
kwargs['build_pk'] = build.pk
@@ -120,16 +132,38 @@ def trigger_build(project, version=None, record=True, force=False):
120132
if project.container_time_limit:
121133
time_limit = int(project.container_time_limit)
122134
except ValueError:
123-
pass
135+
log.warning('Invalid time_limit for project: %s', project.slug)
136+
124137
# Add 20% overhead to task, to ensure the build can timeout and the task
125138
# will cleanly finish.
126139
options['soft_time_limit'] = time_limit
127140
options['time_limit'] = int(time_limit * 1.2)
128141

129-
update_docs = UpdateDocsTask()
130-
update_docs.apply_async(kwargs=kwargs, **options)
142+
update_docs_task = UpdateDocsTask()
143+
return update_docs_task.si(kwargs=kwargs, **options)
144+
131145

132-
return build
146+
def trigger_build(project, version=None, record=True, force=False):
147+
"""
148+
Trigger a Build.
149+
150+
Helper that calls ``prepare_build`` and just effectively trigger the Celery
151+
task to be executed by a worker.
152+
153+
:param project: project's documentation to be built
154+
:param version: version of the project to be built. Default: ``latest``
155+
:param record: whether or not record the build in a new Build object
156+
:param force: build the HTML documentation even if the files haven't changed
157+
:returns: Celery AsyncResult promise
158+
"""
159+
update_docs_task = prepare_build(
160+
project,
161+
version,
162+
record,
163+
force,
164+
immutable=True,
165+
)
166+
return update_docs_task.apply_async()
133167

134168

135169
def send_email(recipient, subject, template, template_html, context=None,

readthedocs/projects/views/private.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,10 +233,16 @@ def done(self, form_list, **kwargs):
233233
setattr(project, field, value)
234234
project.save()
235235
project_import.send(sender=project, request=self.request)
236-
trigger_build(project)
236+
self.trigger_initial_build(project)
237237
return HttpResponseRedirect(
238238
reverse('projects_detail', args=[project.slug]))
239239

240+
def trigger_initial_build(self, project):
241+
"""
242+
Trigger initial build.
243+
"""
244+
return trigger_build(project)
245+
240246
def is_advanced(self):
241247
"""Determine if the user selected the `show advanced` field."""
242248
data = self.get_cleaned_data_for_step('basics') or {}

0 commit comments

Comments
 (0)