OLD | NEW |
1 # Copyright 2016 The Chromium Authors. All rights reserved. | 1 # Copyright 2016 The Chromium Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 import logging | 5 import logging |
6 | 6 |
7 from webkitpy.w3c.local_wpt import LocalWPT | 7 from webkitpy.w3c.local_wpt import LocalWPT |
8 from webkitpy.w3c.chromium_commit import ChromiumCommit | 8 from webkitpy.w3c.chromium_commit import ChromiumCommit |
9 | 9 |
10 _log = logging.getLogger(__name__) | 10 _log = logging.getLogger(__name__) |
| 11 |
11 CHROMIUM_WPT_DIR = 'third_party/WebKit/LayoutTests/imported/wpt/' | 12 CHROMIUM_WPT_DIR = 'third_party/WebKit/LayoutTests/imported/wpt/' |
12 | 13 |
| 14 # TODO(jeffcarp): have the script running this fetch Chromium origin/master |
| 15 # TODO(jeffcarp): move WPT fetch out of its constructor to match planned Chromiu
mWPT pattern |
13 | 16 |
14 class TestExporter(object): | 17 class TestExporter(object): |
15 | 18 |
16 def __init__(self, host, wpt_github, dry_run=False): | 19 def __init__(self, host, wpt_github, dry_run=False): |
17 self.host = host | 20 self.host = host |
18 self.wpt_github = wpt_github | 21 self.wpt_github = wpt_github |
| 22 self.dry_run = dry_run |
19 self.local_wpt = LocalWPT(self.host) | 23 self.local_wpt = LocalWPT(self.host) |
20 self.dry_run = dry_run | |
21 | 24 |
22 def run(self): | 25 def run(self): |
23 # First, poll for an in-flight pull request and merge if exists | 26 """Query in-flight pull requests, then merge PR or create one. |
| 27 |
| 28 This script assumes it will be run on a regular interval. On |
| 29 each invocation, it will either attempt to merge or attempt to |
| 30 create a PR, never both. |
| 31 """ |
24 pull_requests = self.wpt_github.in_flight_pull_requests() | 32 pull_requests = self.wpt_github.in_flight_pull_requests() |
25 | 33 |
26 if len(pull_requests) == 1: | 34 if len(pull_requests) == 1: |
27 pull_request = pull_requests.pop() | 35 self.merge_in_flight_pull_request(pull_requests.pop()) |
28 | |
29 _log.info('In-flight PR found: #%d', pull_request['number']) | |
30 _log.info(pull_request['title']) | |
31 | |
32 # TODO(jeffcarp): Check the PR status here | |
33 | |
34 if self.dry_run: | |
35 _log.info('[dry_run] Would have attempted to merge PR') | |
36 else: | |
37 _log.info('Merging...') | |
38 self.wpt_github.merge_pull_request(pull_request['number']) | |
39 _log.info('PR merged!') | |
40 elif len(pull_requests) > 1: | 36 elif len(pull_requests) > 1: |
41 _log.error(pull_requests) | 37 _log.error(pull_requests) |
42 # TODO(jeffcarp): Print links to PRs | 38 # TODO(jeffcarp): Print links to PRs |
43 raise Exception('More than two in-flight PRs!') | 39 raise Exception('More than two in-flight PRs!') |
| 40 else: |
| 41 self.export_first_exportable_commit() |
44 | 42 |
45 # Second, look for exportable commits in Chromium | 43 def merge_in_flight_pull_request(self, pull_request): |
46 # At this point, no in-flight PRs should exist | 44 """Attempt to merge an in-flight PR. |
47 # If there was an issue merging, it should have errored out | |
48 | 45 |
49 # TODO(jeffcarp): have the script running this fetch Chromium origin/mas
ter | 46 Args: |
50 # TODO(jeffcarp): move WPT fetch out of its constructor to match planned
ChromiumWPT pattern | 47 pull_request: a PR object returned from the GitHub API. |
| 48 """ |
| 49 |
| 50 _log.info('In-flight PR found: #%d', pull_request['number']) |
| 51 _log.info(pull_request['title']) |
| 52 |
| 53 # TODO(jeffcarp): Check the PR status here (for Travis CI, etc.) |
| 54 |
| 55 if self.dry_run: |
| 56 _log.info('[dry_run] Would have attempted to merge PR') |
| 57 return |
| 58 |
| 59 _log.info('Merging...') |
| 60 self.wpt_github.merge_pull_request(pull_request['number']) |
| 61 _log.info('PR merged! Deleting branch.') |
| 62 self.wpt_github.delete_remote_branch('chromium-export-try') |
| 63 _log.info('Branch deleted!') |
| 64 |
| 65 def export_first_exportable_commit(self): |
| 66 """Looks for exportable commits in Chromium, creates PR if found.""" |
51 | 67 |
52 wpt_commit, chromium_commit = self.local_wpt.most_recent_chromium_commit
() | 68 wpt_commit, chromium_commit = self.local_wpt.most_recent_chromium_commit
() |
53 assert chromium_commit, 'No Chromium commit found, this is impossible' | 69 assert chromium_commit, 'No Chromium commit found, this is impossible' |
54 | 70 |
55 wpt_behind_master = self.local_wpt.commits_behind_master(wpt_commit) | 71 wpt_behind_master = self.local_wpt.commits_behind_master(wpt_commit) |
56 | 72 |
57 _log.info('\nLast Chromium export commit in web-platform-tests:') | 73 _log.info('\nLast Chromium export commit in web-platform-tests:') |
58 _log.info('web-platform-tests@%s', wpt_commit) | 74 _log.info('web-platform-tests@%s', wpt_commit) |
59 _log.info('(%d behind web-platform-tests@origin/master)', wpt_behind_mas
ter) | 75 _log.info('(%d behind web-platform-tests@origin/master)', wpt_behind_mas
ter) |
60 | 76 |
(...skipping 11 matching lines...) Expand all Loading... |
72 for commit in exportable_commits: | 88 for commit in exportable_commits: |
73 _log.info('- %s %s', commit, commit.subject()) | 89 _log.info('- %s %s', commit, commit.subject()) |
74 | 90 |
75 outbound_commit = exportable_commits[0] | 91 outbound_commit = exportable_commits[0] |
76 _log.info('Picking the earliest commit and creating a PR') | 92 _log.info('Picking the earliest commit and creating a PR') |
77 _log.info('- %s %s', outbound_commit.sha, outbound_commit.subject()) | 93 _log.info('- %s %s', outbound_commit.sha, outbound_commit.subject()) |
78 | 94 |
79 patch = outbound_commit.format_patch() | 95 patch = outbound_commit.format_patch() |
80 message = outbound_commit.message() | 96 message = outbound_commit.message() |
81 | 97 |
82 # TODO: now do a test comparison of patch against local WPT | |
83 | |
84 if self.dry_run: | 98 if self.dry_run: |
85 _log.info('[dry_run] Stopping before creating PR') | 99 _log.info('[dry_run] Stopping before creating PR') |
86 _log.info('\n\n[dry_run] message:') | 100 _log.info('\n\n[dry_run] message:') |
87 _log.info(message) | 101 _log.info(message) |
88 _log.info('\n\n[dry_run] patch:') | 102 _log.info('\n\n[dry_run] patch:') |
89 _log.info(patch) | 103 _log.info(patch) |
90 return | 104 return |
91 | 105 |
92 local_branch_name = self.local_wpt.create_branch_with_patch(message, pat
ch) | 106 remote_branch_name = self.local_wpt.create_branch_with_patch(message, pa
tch) |
93 | 107 |
94 response_data = self.wpt_github.create_pr( | 108 response_data = self.wpt_github.create_pr( |
95 local_branch_name=local_branch_name, | 109 remote_branch_name=remote_branch_name, |
96 desc_title=outbound_commit.subject(), | 110 desc_title=outbound_commit.subject(), |
97 body=outbound_commit.body()) | 111 body=outbound_commit.body()) |
98 | 112 |
99 _log.info('Create PR response: %s', response_data) | 113 _log.info('Create PR response: %s', response_data) |
100 | 114 |
101 if response_data: | 115 if response_data: |
102 data, status_code = self.wpt_github.add_label(response_data['number'
]) | 116 data, status_code = self.wpt_github.add_label(response_data['number'
]) |
103 _log.info('Add label response (status %s): %s', status_code, data) | 117 _log.info('Add label response (status %s): %s', status_code, data) |
104 | 118 |
105 def exportable_commits_since(self, commit): | 119 def exportable_commits_since(self, commit): |
(...skipping 16 matching lines...) Expand all Loading... |
122 def is_exportable(chromium_commit): | 136 def is_exportable(chromium_commit): |
123 patch = chromium_commit.format_patch() | 137 patch = chromium_commit.format_patch() |
124 return ( | 138 return ( |
125 patch | 139 patch |
126 and self.local_wpt.test_patch(patch) | 140 and self.local_wpt.test_patch(patch) |
127 and 'NOEXPORT=true' not in chromium_commit.message() | 141 and 'NOEXPORT=true' not in chromium_commit.message() |
128 and not chromium_commit.message().startswith('Import ') | 142 and not chromium_commit.message().startswith('Import ') |
129 ) | 143 ) |
130 | 144 |
131 return [c for c in chromium_commits if is_exportable(c)] | 145 return [c for c in chromium_commits if is_exportable(c)] |
OLD | NEW |