@@ -79,6 +79,7 @@ class Repository:
7979 treeclosed = - 1
8080 treeclosed_src = None
8181 gh = None
82+ gh_test_on_fork = None
8283 label = None
8384 db = None
8485
@@ -133,7 +134,7 @@ class PullReqState:
133134 delegate = ''
134135
135136 def __init__ (self , num , head_sha , status , db , repo_label , mergeable_que ,
136- gh , owner , name , label_events , repos ):
137+ gh , owner , name , label_events , repos , test_on_fork ):
137138 self .head_advanced ('' , use_db = False )
138139
139140 self .num = num
@@ -149,6 +150,7 @@ def __init__(self, num, head_sha, status, db, repo_label, mergeable_que,
149150 self .timeout_timer = None
150151 self .test_started = time .time ()
151152 self .label_events = label_events
153+ self .test_on_fork = test_on_fork
152154
153155 def head_advanced (self , head_sha , * , use_db = True ):
154156 self .head_sha = head_sha
@@ -313,6 +315,22 @@ def get_repo(self):
313315 assert repo .name == self .name
314316 return repo
315317
318+ def get_test_on_fork_repo (self ):
319+ if not self .test_on_fork :
320+ return None
321+
322+ repo = self .repos [self .repo_label ].gh_test_on_fork
323+ if not repo :
324+ repo = self .gh .repository (
325+ self .test_on_fork ['owner' ],
326+ self .test_on_fork ['name' ],
327+ )
328+ self .repos [self .repo_label ].gh_test_on_fork = repo
329+
330+ assert repo .owner .login == self .test_on_fork ['owner' ]
331+ assert repo .name == self .test_on_fork ['name' ]
332+ return repo
333+
316334 def save (self ):
317335 db_query (
318336 self .db ,
@@ -792,9 +810,9 @@ def handle_hook_response(state, hook_cfg, body, extra_data):
792810def git_push (git_cmd , branch , state ):
793811 merge_sha = subprocess .check_output (git_cmd ('rev-parse' , 'HEAD' )).decode ('ascii' ).strip () # noqa
794812
795- if utils .silent_call (git_cmd ('push' , '-f' , 'origin' , branch )):
813+ if utils .silent_call (git_cmd ('push' , '-f' , 'test- origin' , branch )):
796814 utils .logged_call (git_cmd ('branch' , '-f' , 'homu-tmp' , branch ))
797- utils .logged_call (git_cmd ('push' , '-f' , 'origin' , 'homu-tmp' ))
815+ utils .logged_call (git_cmd ('push' , '-f' , 'test- origin' , 'homu-tmp' ))
798816
799817 def inner ():
800818 utils .github_create_status (
@@ -814,14 +832,14 @@ def fail(err):
814832
815833 utils .retry_until (inner , fail , state )
816834
817- utils .logged_call (git_cmd ('push' , '-f' , 'origin' , branch ))
835+ utils .logged_call (git_cmd ('push' , '-f' , 'test- origin' , branch ))
818836
819837 return merge_sha
820838
821839
822840def init_local_git_cmds (repo_cfg , git_cfg ):
823841 fpath = 'cache/{}/{}' .format (repo_cfg ['owner' ], repo_cfg ['name' ])
824- url = 'git@github.com:{}/{}.git' .format (repo_cfg ['owner' ], repo_cfg ['name' ]) # noqa
842+ genurl = lambda cfg : 'git@github.com:{}/{}.git' .format (cfg ['owner' ], cfg ['name' ]) # noqa
825843
826844 if not os .path .exists (SSH_KEY_FILE ):
827845 os .makedirs (os .path .dirname (SSH_KEY_FILE ), exist_ok = True )
@@ -831,7 +849,18 @@ def init_local_git_cmds(repo_cfg, git_cfg):
831849
832850 if not os .path .exists (fpath ):
833851 utils .logged_call (['git' , 'init' , fpath ])
834- utils .logged_call (['git' , '-C' , fpath , 'remote' , 'add' , 'origin' , url ]) # noqa
852+
853+ remotes = {
854+ 'origin' : genurl (repo_cfg ),
855+ 'test-origin' : genurl (repo_cfg .get ('test-on-fork' , repo_cfg )),
856+ }
857+
858+ for remote , url in remotes .items ():
859+ try :
860+ utils .logged_call (['git' , '-C' , fpath , 'remote' , 'set-url' , remote , url ]) # noqa
861+ utils .logged_call (['git' , '-C' , fpath , 'remote' , 'set-url' , '--push' , remote , url ]) # noqa
862+ except subprocess .CalledProcessError :
863+ utils .logged_call (['git' , '-C' , fpath , 'remote' , 'add' , remote , url ]) # noqa
835864
836865 return lambda * args : ['git' , '-C' , fpath ] + list (args )
837866
@@ -1511,7 +1540,7 @@ def synchronize(repo_label, repo_cfg, logger, gh, states, repos, db, mergeable_q
15111540 status = info .state
15121541 break
15131542
1514- state = PullReqState (pull .number , pull .head .sha , status , db , repo_label , mergeable_que , gh , repo_cfg ['owner' ], repo_cfg ['name' ], repo_cfg .get ('labels' , {}), repos ) # noqa
1543+ state = PullReqState (pull .number , pull .head .sha , status , db , repo_label , mergeable_que , gh , repo_cfg ['owner' ], repo_cfg ['name' ], repo_cfg .get ('labels' , {}), repos , repo_cfg . get ( 'test-on-fork' ) ) # noqa
15151544 state .title = pull .title
15161545 state .body = pull .body
15171546 state .head_ref = pull .head .repo [0 ] + ':' + pull .head .ref
@@ -1702,6 +1731,13 @@ def main():
17021731 repo_cfgs [repo_label ] = repo_cfg
17031732 repo_labels [repo_cfg ['owner' ], repo_cfg ['name' ]] = repo_label
17041733
1734+ # If test-on-fork is enabled point both the main repo and the fork to
1735+ # the same homu "repository". This will allow events coming from both
1736+ # GitHub repositories to be processed the same way.
1737+ if 'test-on-fork' in repo_cfg :
1738+ tof = repo_cfg ['test-on-fork' ]
1739+ repo_labels [tof ['owner' ], tof ['name' ]] = repo_label
1740+
17051741 repo_states = {}
17061742 repos [repo_label ] = Repository (None , repo_label , db )
17071743
@@ -1710,7 +1746,7 @@ def main():
17101746 'SELECT num, head_sha, status, title, body, head_ref, base_ref, assignee, approved_by, priority, try_, rollup, delegate, merge_sha FROM pull WHERE repo = ?' , # noqa
17111747 [repo_label ])
17121748 for num , head_sha , status , title , body , head_ref , base_ref , assignee , approved_by , priority , try_ , rollup , delegate , merge_sha in db .fetchall (): # noqa
1713- state = PullReqState (num , head_sha , status , db , repo_label , mergeable_que , gh , repo_cfg ['owner' ], repo_cfg ['name' ], repo_cfg .get ('labels' , {}), repos ) # noqa
1749+ state = PullReqState (num , head_sha , status , db , repo_label , mergeable_que , gh , repo_cfg ['owner' ], repo_cfg ['name' ], repo_cfg .get ('labels' , {}), repos , repo_cfg . get ( 'test-on-fork' ) ) # noqa
17141750 state .title = title
17151751 state .body = body
17161752 state .head_ref = head_ref
0 commit comments