##// END OF EJS Templates
PR tester can now post results to Github as a comment.
Thomas Kluyver -
Show More
@@ -0,0 +1,42 b''
1 """Functions for Github authorisation."""
2 from __future__ import print_function
3
4 try:
5 input = raw_input
6 except NameError:
7 pass
8
9 import requests
10 import keyring
11 import getpass
12 import json
13
14 # Keyring stores passwords by a 'username', but we're not storing a username and
15 # password
16 fake_username = 'ipython_tools'
17
18 def get_auth_token():
19 token = keyring.get_password('github', fake_username)
20 if token is not None:
21 return token
22
23 print("Please enter your github username and password. These are not "
24 "stored, only used to get an oAuth token. You can revoke this at "
25 "any time on Github.")
26 user = input("Username: ")
27 pw = getpass.getpass("Password: ")
28
29 auth_request = {
30 "scopes": [
31 "public_repo"
32 ],
33 "note": "IPython tools"
34 }
35 response = requests.post('https://api.github.com/authorizations',
36 auth=(user, pw), data=json.dumps(auth_request))
37 response.raise_for_status()
38 token = json.loads(response.text)['token']
39 keyring.set_password('github', fake_username, token)
40 return token
41
42
@@ -13,6 +13,7 b' from glob import glob'
13 import json
13 import json
14 import os
14 import os
15 import re
15 import re
16 import requests
16 import shutil
17 import shutil
17 from subprocess import call, check_call, check_output, PIPE, STDOUT, CalledProcessError
18 from subprocess import call, check_call, check_output, PIPE, STDOUT, CalledProcessError
18 try:
19 try:
@@ -20,9 +21,12 b' try:'
20 except ImportError:
21 except ImportError:
21 from urllib2 import urlopen
22 from urllib2 import urlopen
22
23
24 import gh_auth
25
23 basedir = os.path.join(os.path.expanduser("~"), ".ipy_pr_tests")
26 basedir = os.path.join(os.path.expanduser("~"), ".ipy_pr_tests")
24 repodir = os.path.join(basedir, "ipython")
27 repodir = os.path.join(basedir, "ipython")
25 ipy_repository = 'git://github.com/ipython/ipython.git'
28 ipy_repository = 'git://github.com/ipython/ipython.git'
29 gh_project="ipython/ipython"
26
30
27 supported_pythons = ['python2.6', 'python2.7', 'python3.1', 'python3.2']
31 supported_pythons = ['python2.6', 'python2.7', 'python3.1', 'python3.2']
28 unavailable_pythons = []
32 unavailable_pythons = []
@@ -66,8 +70,8 b' def setup():'
66 check_call(['git', 'pull', ipy_repository, 'master'])
70 check_call(['git', 'pull', ipy_repository, 'master'])
67 os.chdir(basedir)
71 os.chdir(basedir)
68
72
69 def get_pull_request(num, project="ipython/ipython"):
73 def get_pull_request(num):
70 url = "https://api.github.com/repos/{project}/pulls/{num}".format(project=project, num=num)
74 url = "https://api.github.com/repos/{project}/pulls/{num}".format(project=gh_project, num=num)
71 response = urlopen(url).read().decode('utf-8')
75 response = urlopen(url).read().decode('utf-8')
72 return json.loads(response)
76 return json.loads(response)
73
77
@@ -102,7 +106,7 b' def run_tests(venv):'
102 try:
106 try:
103 return True, check_output([iptest], stderr=STDOUT).decode('utf-8')
107 return True, check_output([iptest], stderr=STDOUT).decode('utf-8')
104 except CalledProcessError as e:
108 except CalledProcessError as e:
105 return False, e.output
109 return False, e.output.decode('utf-8')
106
110
107 def post_gist(content, description='IPython test log', filename="results.log"):
111 def post_gist(content, description='IPython test log', filename="results.log"):
108 """Post some text to a Gist, and return the URL."""
112 """Post some text to a Gist, and return the URL."""
@@ -120,6 +124,34 b' def post_gist(content, description=\'IPython test log\', filename="results.log"):'
120 response_data = json.loads(response.read().decode('utf-8'))
124 response_data = json.loads(response.read().decode('utf-8'))
121 return response_data['html_url']
125 return response_data['html_url']
122
126
127 def markdown_format(pr, results):
128 def format_result(py, passed, gist_url, missing_libraries):
129 s = "* %s: " % py
130 if passed:
131 s += "OK"
132 else:
133 s += "Failed, log at %s" % gist_url
134 if missing_libraries:
135 s += " (libraries not available: " + missing_libraries + ")"
136 return s
137
138 lines = ["**Test results for commit %s merged into master**" % pr['head']['sha'][:7],
139 "Platform: " + sys.platform,
140 ""] + \
141 [format_result(*r) for r in results] + \
142 ["",
143 "Not available for testing:" + ", ".join(unavailable_pythons)]
144 return "\n".join(lines)
145
146 def post_results_comment(pr, results, num):
147 body = markdown_format(pr, results)
148 url = 'https://api.github.com/repos/{project}/issues/{num}/comments'.format(project=gh_project, num=num)
149 payload = json.dumps({'body': body})
150 auth_token = gh_auth.get_auth_token()
151 headers = {'Authorization': 'token ' + auth_token}
152 r = requests.post(url, data=payload, headers=headers)
153
154
123 if __name__ == '__main__':
155 if __name__ == '__main__':
124 import sys
156 import sys
125 num = sys.argv[1]
157 num = sys.argv[1]
@@ -151,3 +183,5 b" if __name__ == '__main__':"
151 if missing_libraries:
183 if missing_libraries:
152 print(" Libraries not available:", missing_libraries)
184 print(" Libraries not available:", missing_libraries)
153 print("Not available for testing:", ", ".join(unavailable_pythons))
185 print("Not available for testing:", ", ".join(unavailable_pythons))
186 post_results_comment(pr, results, num)
187 print("(Posted to Github)")
General Comments 0
You need to be logged in to leave comments. Login now