forked from PaulKinlan/Github-Auto-Deploy
-
Notifications
You must be signed in to change notification settings - Fork 0
/
GitAutoDeploy.py
executable file
·126 lines (106 loc) · 4.3 KB
/
GitAutoDeploy.py
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
121
122
123
124
125
126
#!/usr/bin/env python
import json, urlparse, sys, os
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
from subprocess import call
class GitAutoDeploy(BaseHTTPRequestHandler):
CONFIG_FILEPATH = './GitAutoDeploy.conf.json'
config = None
quiet = False
daemon = False
@classmethod
def getConfig(myClass):
if(myClass.config == None):
try:
configString = open(myClass.CONFIG_FILEPATH).read()
except:
sys.exit('Could not load ' + myClass.CONFIG_FILEPATH + ' file')
try:
myClass.config = json.loads(configString)
except:
sys.exit(myClass.CONFIG_FILEPATH + ' file is not valid json')
for repository in myClass.config['repositories']:
if(not os.path.isdir(repository['path'])):
sys.exit('Directory ' + repository['path'] + ' not found')
if(not os.path.isdir(repository['path'] + '/.git')):
sys.exit('Directory ' + repository['path'] + ' is not a Git repository')
return myClass.config
def do_POST(self):
if(not GitAutoDeploy.quiet):
print "\nPost request received"
url_refs = self.parseRequest()
deployed = 0
for url, ref in url_refs:
paths = self.getMatchingPaths(url, ref)
if(not GitAutoDeploy.quiet):
print "\nFound ",len(paths)," matching path(s)"
for path in paths:
self.pull(path)
self.deploy(path)
deployed += 1
if(deployed > 0):
self.respond()
def parseRequest(self):
length = int(self.headers.getheader('content-length'))
body = self.rfile.read(length)
post = urlparse.parse_qs(body)
items = []
for itemString in post['payload']:
item = json.loads(itemString)
items.append((item['repository']['url'], item['ref']))
return items
def getMatchingPaths(self, repoUrl, ref):
res = []
config = self.getConfig()
for repository in config['repositories']:
if(not GitAutoDeploy.quiet):
print "\nComparing ", repoUrl, "with ", repository['url']
print "Comparing ", repository.get('ref', ''), "with ", ('', ref)
if(repository['url'] == repoUrl and repository.get('ref', '') in ('', ref)):
res.append((repository['path'], repository.get('ref','')))
return res
def respond(self):
self.send_response(200)
self.send_header('Content-type', 'text/plain')
self.end_headers()
def pull(self, path):
if(not self.quiet):
print "\nPulling update for %s refspec %s" % path
call(['cd "' + path[0] + '" && git pull origin "' + path[1] +'"'], shell=True)
def deploy(self, path):
config = self.getConfig()
for repository in config['repositories']:
if(repository['path'] == path[0]):
if 'deploy' in repository:
if(not self.quiet):
print '\nExecuting deploy command'
call(['cd "' + path[0] + '" && ' + repository['deploy']], shell=True)
break
def main():
try:
server = None
for arg in sys.argv:
if(arg == '-d' or arg == '--daemon-mode'):
GitAutoDeploy.daemon = True
GitAutoDeploy.quiet = True
if(arg == '-q' or arg == '--quiet'):
GitAutoDeploy.quiet = True
if(GitAutoDeploy.daemon):
pid = os.fork()
if(pid != 0):
sys.exit()
os.setsid()
if(not GitAutoDeploy.quiet):
print 'Github Autodeploy Service v 0.1 started'
else:
print 'Github Autodeploy Service v 0.1 started in daemon mode'
server = HTTPServer(('', GitAutoDeploy.getConfig()['port']), GitAutoDeploy)
server.serve_forever()
except (KeyboardInterrupt, SystemExit) as e:
if(e): # wtf, why is this creating a new line?
print >> sys.stderr, e
if(not server is None):
server.socket.close()
if(not GitAutoDeploy.quiet):
print 'Goodbye'
if __name__ == '__main__':
main()