3
3
import hashlib
4
4
import hmac
5
5
import json
6
- import re
7
6
from functools import namedtuple
8
7
from textwrap import dedent
9
8
19
18
from rest_framework .status import HTTP_400_BAD_REQUEST
20
19
from rest_framework .views import APIView
21
20
21
+ from readthedocs .builds .constants import BRANCH
22
22
from readthedocs .builds .constants import LATEST
23
+ from readthedocs .builds .constants import TAG
23
24
from readthedocs .core .signals import webhook_bitbucket
24
25
from readthedocs .core .signals import webhook_github
25
26
from readthedocs .core .signals import webhook_gitlab
26
- from readthedocs .core .views .hooks import build_branches
27
+ from readthedocs .core .views .hooks import VersionInfo
27
28
from readthedocs .core .views .hooks import build_external_version
29
+ from readthedocs .core .views .hooks import build_versions_from_names
28
30
from readthedocs .core .views .hooks import close_external_version
29
31
from readthedocs .core .views .hooks import get_or_create_external_version
30
32
from readthedocs .core .views .hooks import trigger_sync_versions
31
33
from readthedocs .integrations .models import HttpExchange
32
34
from readthedocs .integrations .models import Integration
33
35
from readthedocs .projects .models import Project
36
+ from readthedocs .vcs_support .backends .git import parse_version_from_ref
34
37
35
38
36
39
log = structlog .get_logger (__name__ )
@@ -205,7 +208,7 @@ def get_integration(self):
205
208
)
206
209
return self .integration
207
210
208
- def get_response_push (self , project , branches ):
211
+ def get_response_push (self , project , versions_info : list [ VersionInfo ] ):
209
212
"""
210
213
Build branches on push events and return API response.
211
214
@@ -219,14 +222,12 @@ def get_response_push(self, project, branches):
219
222
220
223
:param project: Project instance
221
224
:type project: Project
222
- :param branches: List of branch/tag names to build
223
- :type branches: list(str)
224
225
"""
225
- to_build , not_building = build_branches (project , branches )
226
+ to_build , not_building = build_versions_from_names (project , versions_info )
226
227
if not_building :
227
228
log .info (
228
- "Skipping project branches ." ,
229
- branches = branches ,
229
+ "Skipping project versions ." ,
230
+ versions = not_building ,
230
231
)
231
232
triggered = bool (to_build )
232
233
return {
@@ -520,18 +521,15 @@ def handle_webhook(self):
520
521
# Trigger a build for all branches in the push
521
522
if event == GITHUB_PUSH :
522
523
try :
523
- branch = self ._normalize_ref (self .data ["ref" ])
524
- return self .get_response_push (self .project , [branch ])
524
+ version_name , version_type = parse_version_from_ref (self .data ["ref" ])
525
+ return self .get_response_push (
526
+ self .project , [VersionInfo (name = version_name , type = version_type )]
527
+ )
525
528
except KeyError as exc :
526
529
raise ParseError ('Parameter "ref" is required' ) from exc
527
530
528
531
return None
529
532
530
- def _normalize_ref (self , ref ):
531
- """Remove `ref/(heads|tags)/` from the reference to match a Version on the db."""
532
- pattern = re .compile (r"^refs/(heads|tags)/" )
533
- return pattern .sub ("" , ref )
534
-
535
533
536
534
class GitLabWebhookView (WebhookMixin , APIView ):
537
535
"""
@@ -640,8 +638,10 @@ def handle_webhook(self):
640
638
return self .sync_versions_response (self .project )
641
639
# Normal push to master
642
640
try :
643
- branch = self ._normalize_ref (data ["ref" ])
644
- return self .get_response_push (self .project , [branch ])
641
+ version_name , version_type = parse_version_from_ref (self .data ["ref" ])
642
+ return self .get_response_push (
643
+ self .project , [VersionInfo (name = version_name , type = version_type )]
644
+ )
645
645
except KeyError as exc :
646
646
raise ParseError ('Parameter "ref" is required' ) from exc
647
647
@@ -659,10 +659,6 @@ def handle_webhook(self):
659
659
return self .get_closed_external_version_response (self .project )
660
660
return None
661
661
662
- def _normalize_ref (self , ref ):
663
- pattern = re .compile (r"^refs/(heads|tags)/" )
664
- return pattern .sub ("" , ref )
665
-
666
662
667
663
class BitbucketWebhookView (WebhookMixin , APIView ):
668
664
"""
@@ -722,21 +718,22 @@ def handle_webhook(self):
722
718
try :
723
719
data = self .request .data
724
720
changes = data ["push" ]["changes" ]
725
- branches = []
721
+ versions_info = []
726
722
for change in changes :
727
723
old = change ["old" ]
728
724
new = change ["new" ]
729
725
# Normal push to master
730
726
if old is not None and new is not None :
731
- branches .append (new ["name" ])
727
+ version_type = BRANCH if new ["type" ] == "branch" else TAG
728
+ versions_info .append (VersionInfo (name = new ["name" ], type = version_type ))
732
729
# BitBuck returns an array of changes rather than
733
730
# one webhook per change. If we have at least one normal push
734
731
# we don't trigger the sync versions, because that
735
732
# will be triggered with the normal push.
736
- if branches :
733
+ if versions_info :
737
734
return self .get_response_push (
738
735
self .project ,
739
- branches ,
736
+ versions_info ,
740
737
)
741
738
log .debug ("Triggered sync_versions." )
742
739
return self .sync_versions_response (self .project )
@@ -833,7 +830,9 @@ def handle_webhook(self):
833
830
if default_branch and isinstance (default_branch , str ):
834
831
self .update_default_branch (default_branch )
835
832
836
- return self .get_response_push (self .project , branches )
833
+ # branches can be a branch or a tag, so we set it to None, so both types are considered.
834
+ versions_info = [VersionInfo (name = branch , type = None ) for branch in branches ]
835
+ return self .get_response_push (self .project , versions_info )
837
836
except TypeError as exc :
838
837
raise ParseError ("Invalid request" ) from exc
839
838
0 commit comments