1
+ # -*- coding: utf-8 -*-
1
2
"""Common utilty functions."""
2
3
3
4
from __future__ import absolute_import
16
17
from future .backports .urllib .parse import urlparse
17
18
from celery import group , chord
18
19
19
- from readthedocs .builds .constants import LATEST
20
+ from readthedocs .builds .constants import LATEST , BUILD_STATE_TRIGGERED
20
21
from readthedocs .doc_builder .constants import DOCKER_LIMITS
21
22
22
23
@@ -75,37 +76,48 @@ def cname_to_slug(host):
75
76
return slug
76
77
77
78
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 ):
79
81
"""
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.
81
86
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
84
93
"""
85
94
# Avoid circular import
86
95
from readthedocs .projects .tasks import UpdateDocsTask
87
96
from readthedocs .builds .models import Build
88
97
89
98
if project .skip :
99
+ log .info (
100
+ 'Build not triggered because Project.skip=True: project=%s' ,
101
+ project .slug ,
102
+ )
90
103
return None
91
104
92
105
if not version :
93
106
version = project .versions .get (slug = LATEST )
94
107
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
+ }
101
114
102
- build = None
103
115
if record :
104
116
build = Build .objects .create (
105
117
project = project ,
106
118
version = version ,
107
119
type = 'html' ,
108
- state = 'triggered' ,
120
+ state = BUILD_STATE_TRIGGERED ,
109
121
success = True ,
110
122
)
111
123
kwargs ['build_pk' ] = build .pk
@@ -120,16 +132,38 @@ def trigger_build(project, version=None, record=True, force=False):
120
132
if project .container_time_limit :
121
133
time_limit = int (project .container_time_limit )
122
134
except ValueError :
123
- pass
135
+ log .warning ('Invalid time_limit for project: %s' , project .slug )
136
+
124
137
# Add 20% overhead to task, to ensure the build can timeout and the task
125
138
# will cleanly finish.
126
139
options ['soft_time_limit' ] = time_limit
127
140
options ['time_limit' ] = int (time_limit * 1.2 )
128
141
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
+
131
145
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 ()
133
167
134
168
135
169
def send_email (recipient , subject , template , template_html , context = None ,
0 commit comments