forked from nikosk/youtrack-post-commit-hook
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpost-receive
120 lines (94 loc) · 3.98 KB
/
post-receive
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#!/usr/bin/env python3
import http.client
import logging
import urllib.request, urllib.parse, urllib.error
# youtrack username
username = ""
# youtrack password
password = ""
# youtrack base URL e.g.: youtrack.mydomain.tld:8080
youtrack_base_url = ""
# a url pattern for links to git commits
# eg: https://bitbucket.org/user/repo/commits/%s
# or https://github.com/user/repo/commit/%s
git_url_pattern = ""
logging.basicConfig(filename='post-receive.log', level=logging.DEBUG)
class YouTrackConnection(object):
def __init__(self, username, password, url):
self.http = http.client.HTTPConnection(url)
self.base_path = "/rest"
if self._login(username, password):
self.connected = True
else:
self.connected = False
def _login(self, username, password):
login_path = self.base_path + "/user/login"
body = "login=%s&password=%s" % (username, password)
headers = {"Content-Length": str(len(body)), "Content-Type":
"application/x-www-form-urlencoded"}
# self.http.set_debuglevel(4)
self.http.request('POST', login_path, body, headers)
response = self.http.getresponse()
data = response.read()
print(data)
self.headers = {'Cookie': response.getheader('set-cookie'), 'Cache-Control': 'no-cache'}
if response.status != 200:
return False
return True
def _req(self, method, uri, body=None):
headers = self.headers
if method == "PUT" or method == "POST":
headers = headers.copy()
headers['Content-Type'] = 'application/xml; charset=UTF-8'
headers['Content-Length'] = str(len(body))
print((self.base_path + uri + "\n"))
self.http.request(method, self.base_path + uri, body, headers)
response = self.http.getresponse()
print((response.status))
print((response.reason + "\n"))
data = response.read()
print(data.decode() + "\n")
return data
def execute(self, issueId, command, comment=None, group=None, runAs=None):
params = {'command': command}
if comment is not None:
params['comment'] = comment
if group is not None:
params['group'] = group
if runAs is not None:
params['runAs'] = runAs
self._req('POST', '/issue/' + issueId + "/execute?" + urllib.parse.urlencode(params), body='')
return True
def runAs(self, userEmail):
users = self._req('GET', '/admin/user?' + urllib.parse.urlencode({'q': userEmail}))
user = re.findall(r'login\="([^"]*)"', users.decode())[0]
return user
if __name__ == "__main__":
import subprocess
import re
message = subprocess.Popen(['git', 'log', '-1', '--pretty=%B'], stdout=subprocess.PIPE).communicate()[0].decode()
email = subprocess.Popen(['git', 'log', '-1', '--pretty=%ce'], stdout=subprocess.PIPE).communicate()[0].decode()
commit_hash = subprocess.Popen(['git', 'rev-parse', 'HEAD'], stdout=subprocess.PIPE).communicate()[0].decode()
issue_re = re.compile(r'([A-Z]{1,10}-[0-9]*).*')
command_re = re.compile(r'[A-Z]{1,10}-[0-9]*\s*([a-zA-Z]*)')
issue_id = re.findall(issue_re, message)
command = re.findall(command_re, message)
if command:
command = command[0].lower()
print((message, commit_hash, issue_id, command))
if issue_id:
c = YouTrackConnection(username, password, youtrack_base_url)
if c.connected:
runAs = c.runAs(email)
if command:
if command == "fix":
command = "Fixed"
print(("Fixing %s" % issue_id[0]))
command = "State " + command.title()
if issue_id and not command:
command = "tag WIP"
c.execute(issue_id[0]
, command
, message + "\n [" + git_url_pattern % commit_hash.strip() + "see commit]"
, None
, runAs)