4
4
from collections import namedtuple
5
5
from datetime import datetime , timedelta
6
6
7
- from . import git
7
+ from . import git , gitlab
8
+ from .commit import Commit
8
9
from .interval import IntervalUnion
9
10
from .project import Project
10
11
from .user import User
@@ -114,19 +115,23 @@ def add_trailers(self, merge_request):
114
115
return sha
115
116
116
117
def get_mr_ci_status (self , merge_request , commit_sha = None ):
118
+ temp_branch = self .opts .temp_branch
117
119
if commit_sha is None :
118
120
commit_sha = merge_request .sha
119
- pipelines = Pipeline .pipelines_by_branch (
120
- merge_request .source_project_id ,
121
- merge_request .source_branch ,
122
- self ._api ,
123
- )
121
+ if temp_branch and merge_request .source_project_id != self ._project .id :
122
+ pid = self ._project .id
123
+ ref = temp_branch
124
+ self .update_temp_branch (merge_request , commit_sha )
125
+ else :
126
+ pid = merge_request .source_project_id
127
+ ref = merge_request .source_branch
128
+ pipelines = Pipeline .pipelines_by_branch (pid , ref , self ._api )
124
129
current_pipeline = next (iter (pipelines ), None )
125
130
126
131
if current_pipeline and current_pipeline .sha == commit_sha :
127
132
ci_status = current_pipeline .status
128
133
else :
129
- log .warning ('No pipeline listed for %s on branch %s' , commit_sha , merge_request . source_branch )
134
+ log .warning ('No pipeline listed for %s on branch %s' , commit_sha , ref )
130
135
ci_status = None
131
136
132
137
return ci_status
@@ -196,7 +201,7 @@ def fetch_source_project(self, merge_request):
196
201
remote = 'source'
197
202
remote_url = source_project .ssh_url_to_repo
198
203
self ._repo .fetch (
199
- remote = remote ,
204
+ remote_name = remote ,
200
205
remote_url = remote_url ,
201
206
)
202
207
return source_project , remote_url , remote
@@ -281,6 +286,43 @@ def update_from_target_branch_and_push(
281
286
else :
282
287
assert source_repo_url is not None
283
288
289
+ def update_temp_branch (self , merge_request , commit_sha ):
290
+ api = self ._api
291
+ project_id = self ._project .id
292
+ temp_branch = self .opts .temp_branch
293
+ waiting_time_in_secs = 30
294
+
295
+ try :
296
+ sha_branch = Commit .last_on_branch (project_id , temp_branch , api ).id
297
+ except gitlab .NotFound :
298
+ sha_branch = None
299
+ if sha_branch != commit_sha :
300
+ log .info ('Setting up %s in target project' , temp_branch )
301
+ self .delete_temp_branch (merge_request .source_project_id )
302
+ self ._project .create_branch (temp_branch , commit_sha , api )
303
+ self ._project .protect_branch (temp_branch , api )
304
+ merge_request .comment (
305
+ ('The temporary branch **{branch}** was updated to [{sha:.8}](../commit/{sha}) ' +
306
+ 'and local pipelines will be used.' ).format (
307
+ branch = temp_branch , sha = commit_sha
308
+ )
309
+ )
310
+
311
+ time .sleep (waiting_time_in_secs )
312
+
313
+ def delete_temp_branch (self , source_project_id ):
314
+ temp_branch = self .opts .temp_branch
315
+
316
+ if temp_branch and source_project_id != self ._project .id :
317
+ try :
318
+ self ._project .unprotect_branch (temp_branch , self ._api )
319
+ except gitlab .ApiError :
320
+ pass
321
+ try :
322
+ self ._project .delete_branch (temp_branch , self ._api )
323
+ except gitlab .ApiError :
324
+ pass
325
+
284
326
285
327
def _get_reviewer_names_and_emails (approvals , api ):
286
328
"""Return a list ['A. Prover <a.prover@example.com', ...]` for `merge_request.`"""
@@ -298,6 +340,7 @@ def _get_reviewer_names_and_emails(approvals, api):
298
340
'embargo' ,
299
341
'ci_timeout' ,
300
342
'use_merge_strategy' ,
343
+ 'temp_branch' ,
301
344
]
302
345
303
346
@@ -312,7 +355,8 @@ def requests_commit_tagging(self):
312
355
def default (
313
356
cls , * ,
314
357
add_tested = False , add_part_of = False , add_reviewers = False , reapprove = False ,
315
- approval_timeout = None , embargo = None , ci_timeout = None , use_merge_strategy = False
358
+ approval_timeout = None , embargo = None , ci_timeout = None , use_merge_strategy = False ,
359
+ temp_branch = ""
316
360
):
317
361
approval_timeout = approval_timeout or timedelta (seconds = 0 )
318
362
embargo = embargo or IntervalUnion .empty ()
@@ -326,6 +370,7 @@ def default(
326
370
embargo = embargo ,
327
371
ci_timeout = ci_timeout ,
328
372
use_merge_strategy = use_merge_strategy ,
373
+ temp_branch = temp_branch ,
329
374
)
330
375
331
376
0 commit comments