Skip to content

Commit d790b5f

Browse files
authored
[utils] Cross repositories pull request test support (#4583)
* [utils] Cross repositories pull request test support
1 parent 7a386c8 commit d790b5f

File tree

1 file changed

+40
-12
lines changed

1 file changed

+40
-12
lines changed

utils/update-checkout

Lines changed: 40 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,10 @@ from __future__ import print_function
1414
import argparse
1515
import json
1616
import os
17+
import re
1718
import sys
1819

20+
1921
from functools import reduce
2022

2123
sys.path.append(os.path.dirname(__file__))
@@ -32,7 +34,8 @@ sys.path.append(os.path.join(SCRIPT_DIR, 'swift_build_support'))
3234
from swift_build_support import shell # noqa (E402)
3335

3436

35-
def update_single_repository(repo_path, branch, reset_to_remote, should_clean):
37+
def update_single_repository(repo_path, branch, reset_to_remote, should_clean,
38+
cross_repos_pr):
3639
if not os.path.isdir(repo_path):
3740
return
3841

@@ -43,12 +46,12 @@ def update_single_repository(repo_path, branch, reset_to_remote, should_clean):
4346
if should_clean:
4447
shell.call(['git', 'clean', '-fdx'],
4548
echo=True)
46-
shell.call(['git', 'submodule', 'foreach', '--recursive', 'git', 'clean', '-fdx'],
47-
echo=True)
48-
shell.call(['git', 'submodule', 'foreach', '--recursive', 'git', 'reset', '--hard', 'HEAD'],
49-
echo=True)
49+
shell.call(['git', 'submodule', 'foreach', '--recursive', 'git',
50+
'clean', '-fdx'], echo=True)
51+
shell.call(['git', 'submodule', 'foreach', '--recursive', 'git',
52+
'reset', '--hard', 'HEAD'], echo=True)
5053
status = shell.call(['git', 'reset', '--hard', 'HEAD'],
51-
echo=True)
54+
echo=True)
5255
if status:
5356
print("Please, commit your changes.")
5457
print(status)
@@ -73,17 +76,19 @@ def update_single_repository(repo_path, branch, reset_to_remote, should_clean):
7376
# Prior to Git 2.6, this is the way to do a "git pull
7477
# --rebase" that respects rebase.autostash. See
7578
# http://stackoverflow.com/a/30209750/125349
76-
shell.call(["git", "rebase", "FETCH_HEAD"], echo=True)
79+
if not cross_repos_pr:
80+
shell.call(["git", "rebase", "FETCH_HEAD"], echo=True)
7781
shell.call(["git", "submodule", "update", "--recursive"],
7882
echo=True)
7983

8084

81-
def update_all_repositories(args, config, scheme_name):
85+
def update_all_repositories(args, config, scheme_name, cross_repos_pr):
8286
repo_branch = scheme_name
8387
for repo_name in config['repos'].keys():
8488
if repo_name in args.skip_repository_list:
8589
print("--- Skipping '" + repo_name + "' ---")
8690
continue
91+
repo_path = os.path.join(SWIFT_SOURCE_ROOT, repo_name)
8792
if scheme_name:
8893
# This loop is only correct, since we know that each alias set has
8994
# unique contents. This is checked by verify config. Thus the first
@@ -93,12 +98,22 @@ def update_all_repositories(args, config, scheme_name):
9398
if scheme_name not in v['aliases']:
9499
continue
95100
repo_branch = v['repos'][repo_name]
101+
remote_repo_id = config['repos'][repo_name]['remote']['id']
102+
if remote_repo_id in cross_repos_pr:
103+
pr_id = cross_repos_pr[remote_repo_id]
104+
repo_branch = "ci_pr_{0}".format(pr_id)
105+
with shell.pushd(repo_path, dry_run=False, echo=False):
106+
shell.capture(["git", "branch", "-D", repo_branch],
107+
echo=True, allow_non_zero_exit=True)
108+
shell.call(["git", "fetch", "origin",
109+
"pull/{0}/merge:{1}"
110+
.format(pr_id, repo_branch)], echo=True)
96111
break
97-
98-
update_single_repository(os.path.join(SWIFT_SOURCE_ROOT, repo_name),
112+
update_single_repository(repo_path,
99113
repo_branch,
100114
args.reset_to_remote,
101-
args.clean)
115+
args.clean,
116+
cross_repos_pr)
102117

103118

104119
def obtain_additional_swift_sources(
@@ -217,17 +232,30 @@ By default, updates your checkouts of Swift, SourceKit, LLDB, and SwiftPM.""")
217232
"--config",
218233
default=os.path.join(SCRIPT_DIR, "update-checkout-config.json"),
219234
help="Configuration file to use")
235+
parser.add_argument(
236+
"--github-comment",
237+
help="""Check out related pull requests referenced in the given
238+
free-form GitHub-style comment.""",
239+
metavar='GITHUB-COMMENT',
240+
dest='github_comment')
220241
args = parser.parse_args()
221242

222243
clone = args.clone
223244
clone_with_ssh = args.clone_with_ssh
224245
skip_history = args.skip_history
225246
scheme = args.scheme
247+
github_comment = args.github_comment
226248

227249
with open(args.config) as f:
228250
config = json.load(f)
229251
validate_config(config)
230252

253+
cross_repos_pr = {}
254+
if github_comment:
255+
repos_with_pr = re.findall(r'apple/[-a-zA-Z0-9_]+#\d+', github_comment)
256+
print("Found related pull requests:", str(repos_with_pr))
257+
cross_repos_pr = dict(pr.split('#') for pr in repos_with_pr)
258+
231259
if clone or clone_with_ssh:
232260
# If branch is None, default to using the default branch alias
233261
# specified by our configuration file.
@@ -238,7 +266,7 @@ By default, updates your checkouts of Swift, SourceKit, LLDB, and SwiftPM.""")
238266
config, clone_with_ssh, scheme, skip_history,
239267
args.skip_repository_list)
240268

241-
update_all_repositories(args, config, scheme)
269+
update_all_repositories(args, config, scheme, cross_repos_pr)
242270

243271
return 0
244272

0 commit comments

Comments
 (0)