OLD | NEW |
1 from __future__ import print_function | 1 from __future__ import print_function |
2 | 2 |
3 import argparse | 3 import argparse |
4 import json | 4 import json |
5 import logging | 5 import logging |
6 import os | 6 import os |
7 import re | 7 import re |
8 import stat | 8 import stat |
9 import subprocess | 9 import subprocess |
10 import sys | 10 import sys |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
82 self.name = name | 82 self.name = name |
83 | 83 |
84 def __enter__(self): | 84 def __enter__(self): |
85 print("travis_fold:start:%s" % self.name, file=sys.stderr) | 85 print("travis_fold:start:%s" % self.name, file=sys.stderr) |
86 | 86 |
87 def __exit__(self, type, value, traceback): | 87 def __exit__(self, type, value, traceback): |
88 print("travis_fold:end:%s" % self.name, file=sys.stderr) | 88 print("travis_fold:end:%s" % self.name, file=sys.stderr) |
89 | 89 |
90 | 90 |
91 class GitHub(object): | 91 class GitHub(object): |
92 def __init__(self, org, repo, token): | 92 def __init__(self, org, repo, token, browser): |
93 self.token = token | 93 self.token = token |
94 self.headers = {"Accept": "application/vnd.github.v3+json"} | 94 self.headers = {"Accept": "application/vnd.github.v3+json"} |
95 self.auth = (self.token, "x-oauth-basic") | 95 self.auth = (self.token, "x-oauth-basic") |
96 self.org = org | 96 self.org = org |
97 self.repo = repo | 97 self.repo = repo |
98 self.base_url = "https://api.github.com/repos/%s/%s/" % (org, repo) | 98 self.base_url = "https://api.github.com/repos/%s/%s/" % (org, repo) |
| 99 self.browser = browser |
99 | 100 |
100 def _headers(self, headers): | 101 def _headers(self, headers): |
101 if headers is None: | 102 if headers is None: |
102 headers = {} | 103 headers = {} |
103 rv = self.headers.copy() | 104 rv = self.headers.copy() |
104 rv.update(headers) | 105 rv.update(headers) |
105 return rv | 106 return rv |
106 | 107 |
107 def post(self, url, data, headers=None): | 108 def post(self, url, data, headers=None): |
108 logger.debug("POST %s" % url) | 109 logger.debug("POST %s" % url) |
109 if data is not None: | 110 if data is not None: |
110 data = json.dumps(data) | 111 data = json.dumps(data) |
111 resp = requests.post( | 112 resp = requests.post( |
112 url, | 113 url, |
113 data=data, | 114 data=data, |
114 headers=self._headers(headers), | 115 headers=self._headers(headers), |
115 auth=self.auth | 116 auth=self.auth |
116 ) | 117 ) |
117 resp.raise_for_status() | 118 resp.raise_for_status() |
118 return resp | 119 return resp |
119 | 120 |
| 121 def patch(self, url, data, headers=None): |
| 122 logger.debug("PATCH %s" % url) |
| 123 if data is not None: |
| 124 data = json.dumps(data) |
| 125 resp = requests.patch( |
| 126 url, |
| 127 data=data, |
| 128 headers=self._headers(headers), |
| 129 auth=self.auth |
| 130 ) |
| 131 resp.raise_for_status() |
| 132 return resp |
| 133 |
120 def get(self, url, headers=None): | 134 def get(self, url, headers=None): |
121 logger.debug("GET %s" % url) | 135 logger.debug("GET %s" % url) |
122 resp = requests.get( | 136 resp = requests.get( |
123 url, | 137 url, |
124 headers=self._headers(headers), | 138 headers=self._headers(headers), |
125 auth=self.auth | 139 auth=self.auth |
126 ) | 140 ) |
127 resp.raise_for_status() | 141 resp.raise_for_status() |
128 return resp | 142 return resp |
129 | 143 |
130 def post_comment(self, issue_number, body): | 144 def post_comment(self, issue_number, body): |
131 url = urljoin(self.base_url, "issues/%s/comments" % issue_number) | 145 user = self.get(urljoin(self.base_url, "/user")).json() |
132 return self.post(url, {"body": body}) | 146 issue_comments_url = urljoin(self.base_url, "issues/%s/comments" % issue
_number) |
| 147 comments = self.get(issue_comments_url).json() |
| 148 title_line = "# %s #" % self.browser.title() |
| 149 data = {"body": body} |
| 150 for comment in comments: |
| 151 if (comment["user"]["login"] == user["login"] and |
| 152 comment["body"].startswith(title_line)): |
| 153 comment_url = urljoin(self.base_url, "issues/comments/%s" % comm
ent["id"]) |
| 154 self.patch(comment_url, data) |
| 155 break |
| 156 else: |
| 157 self.post(issue_comments_url, data) |
133 | 158 |
134 def releases(self): | 159 def releases(self): |
135 url = urljoin(self.base_url, "releases/latest") | 160 url = urljoin(self.base_url, "releases/latest") |
136 return self.get(url) | 161 return self.get(url) |
137 | 162 |
138 | 163 |
139 class GitHubCommentHandler(logging.Handler): | 164 class GitHubCommentHandler(logging.Handler): |
140 def __init__(self, github, pull_number): | 165 def __init__(self, github, pull_number): |
141 logging.Handler.__init__(self) | 166 logging.Handler.__init__(self) |
142 self.github = github | 167 self.github = github |
(...skipping 17 matching lines...) Expand all Loading... |
160 | 185 |
161 def __init__(self, github_token): | 186 def __init__(self, github_token): |
162 self.github_token = github_token | 187 self.github_token = github_token |
163 | 188 |
164 | 189 |
165 class Firefox(Browser): | 190 class Firefox(Browser): |
166 product = "firefox" | 191 product = "firefox" |
167 | 192 |
168 def install(self): | 193 def install(self): |
169 call("pip", "install", "-r", "w3c/wptrunner/requirements_firefox.txt") | 194 call("pip", "install", "-r", "w3c/wptrunner/requirements_firefox.txt") |
170 resp = get("https://archive.mozilla.org/pub/firefox/nightly/latest-mozil
la-central/firefox-52.0a1.en-US.linux-x86_64.tar.bz2") | 195 resp = get("https://archive.mozilla.org/pub/firefox/nightly/latest-mozil
la-central/firefox-53.0a1.en-US.linux-x86_64.tar.bz2") |
171 untar(resp.raw) | 196 untar(resp.raw) |
172 | 197 |
173 if not os.path.exists("profiles"): | 198 if not os.path.exists("profiles"): |
174 os.mkdir("profiles") | 199 os.mkdir("profiles") |
175 with open(os.path.join("profiles", "prefs_general.js"), "wb") as f: | 200 with open(os.path.join("profiles", "prefs_general.js"), "wb") as f: |
176 resp = get("https://hg.mozilla.org/mozilla-central/raw-file/tip/test
ing/profiles/prefs_general.js") | 201 resp = get("https://hg.mozilla.org/mozilla-central/raw-file/tip/test
ing/profiles/prefs_general.js") |
177 f.write(resp.content) | 202 f.write(resp.content) |
178 call("pip", "install", "-r", os.path.join("w3c", "wptrunner", "requireme
nts_firefox.txt")) | 203 call("pip", "install", "-r", os.path.join("w3c", "wptrunner", "requireme
nts_firefox.txt")) |
179 | 204 |
180 def _latest_geckodriver_version(self): | 205 def _latest_geckodriver_version(self): |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
237 | 262 |
238 def get(url): | 263 def get(url): |
239 logger.debug("GET %s" % url) | 264 logger.debug("GET %s" % url) |
240 resp = requests.get(url, stream=True) | 265 resp = requests.get(url, stream=True) |
241 resp.raise_for_status() | 266 resp.raise_for_status() |
242 return resp | 267 return resp |
243 | 268 |
244 | 269 |
245 def call(*args): | 270 def call(*args): |
246 logger.debug("%s" % " ".join(args)) | 271 logger.debug("%s" % " ".join(args)) |
247 return subprocess.check_output(args) | 272 try: |
| 273 return subprocess.check_output(args) |
| 274 except subprocess.CalledProcessError as e: |
| 275 logger.critical("%s exited with return code %i" % |
| 276 (e.cmd, e.returncode)) |
| 277 logger.critical(e.output) |
| 278 raise |
248 | 279 |
249 | 280 |
250 def get_git_cmd(repo_path): | 281 def get_git_cmd(repo_path): |
251 def git(cmd, *args): | 282 def git(cmd, *args): |
252 full_cmd = ["git", cmd] + list(args) | 283 full_cmd = ["git", cmd] + list(args) |
253 try: | 284 try: |
254 return subprocess.check_output(full_cmd, cwd=repo_path, stderr=subpr
ocess.STDOUT) | 285 return subprocess.check_output(full_cmd, cwd=repo_path, stderr=subpr
ocess.STDOUT) |
255 except subprocess.CalledProcessError as e: | 286 except subprocess.CalledProcessError as e: |
256 logger.error("Git command exited with status %i" % e.returncode) | 287 logger.error("Git command exited with status %i" % e.returncode) |
257 logger.error(e.output) | 288 logger.error(e.output) |
(...skipping 23 matching lines...) Expand all Loading... |
281 with zipfile.ZipFile(fileobj) as zip_data: | 312 with zipfile.ZipFile(fileobj) as zip_data: |
282 for info in zip_data.infolist(): | 313 for info in zip_data.infolist(): |
283 zip_data.extract(info) | 314 zip_data.extract(info) |
284 perm = info.external_attr >> 16 & 0x1FF | 315 perm = info.external_attr >> 16 & 0x1FF |
285 os.chmod(info.filename, perm) | 316 os.chmod(info.filename, perm) |
286 | 317 |
287 | 318 |
288 def setup_github_logging(args): | 319 def setup_github_logging(args): |
289 gh_handler = None | 320 gh_handler = None |
290 if args.comment_pr: | 321 if args.comment_pr: |
291 github = GitHub("w3c", "web-platform-tests", args.gh_token) | 322 github = GitHub("w3c", "web-platform-tests", args.gh_token, args.browser
) |
292 try: | 323 try: |
293 pr_number = int(args.comment_pr) | 324 pr_number = int(args.comment_pr) |
294 except ValueError: | 325 except ValueError: |
295 pass | 326 pass |
296 else: | 327 else: |
297 gh_handler = GitHubCommentHandler(github, pr_number) | 328 gh_handler = GitHubCommentHandler(github, pr_number) |
298 gh_handler.setLevel(logging.INFO) | 329 gh_handler.setLevel(logging.INFO) |
299 logger.debug("Setting up GitHub logging") | 330 logger.debug("Setting up GitHub logging") |
300 logger.addHandler(gh_handler) | 331 logger.addHandler(gh_handler) |
301 else: | 332 else: |
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
590 return retcode | 621 return retcode |
591 | 622 |
592 | 623 |
593 if __name__ == "__main__": | 624 if __name__ == "__main__": |
594 try: | 625 try: |
595 retcode = main() | 626 retcode = main() |
596 except: | 627 except: |
597 raise | 628 raise |
598 else: | 629 else: |
599 sys.exit(retcode) | 630 sys.exit(retcode) |
OLD | NEW |