diff --git a/GitAutoDeploy.conf.json.example b/GitAutoDeploy.conf.json.example index 35aba2d..f7d6a05 100644 --- a/GitAutoDeploy.conf.json.example +++ b/GitAutoDeploy.conf.json.example @@ -1,13 +1,16 @@ { - "port": 8001, - "repositories": - [{ - "url": "https://github.com/logsol/Test-Repo", + "port": 8001, + "repositories": [{ + "url": "https://github.com/logsol/Test-Repo", "path": "/home/logsol/projects/Test-Repo", "deploy": "echo deploying" - }, - { + }, { "url": "https://github.com/logsol/Katharsis-Framework", "path": "/home/logsol/projects/Katharsis-Framework" + }, { + "branch": "name-of-branch", + "url": "https://bitbucket.org/team_name/repo_name", + "path": "/home/fouad/projects/webapp/beta", + "deploy": "git pull origin name-of-branch && service webapp restart" }] } diff --git a/GitAutoDeploy.py b/GitAutoDeploy.py index 1e61cc6..2671434 100755 --- a/GitAutoDeploy.py +++ b/GitAutoDeploy.py @@ -35,33 +35,71 @@ def getConfig(myClass): return myClass.config def do_POST(self): - event = self.headers.getheader('X-Github-Event') - if event == 'ping': + isValid = False + + agent = self.headers.getheader("User-Agent") + + # print User-Agent, helps to diagnose, bitbucket should be "Bitbucket-Webhooks/2.0" + if not self.quiet: + print "User Agent is: ", agent + + if agent == "Bitbucket-Webhooks/2.0": + isValid = self.processBitBucketRequest() + else: + isValid = self.processGithubRequest() + + + for url in self.urls: + paths = self.getMatchingPaths(url) + for path in paths: + self.fetch(path) + self.deploy(path) + + def processGithubRequest(self): + self.event = self.headers.getheader('X-Github-Event') + if not self.quiet: + print "Recieved event", self.event + + if self.event == 'ping': if not self.quiet: print 'Ping event received' self.respond(204) - return - if event != 'push': + return False + if self.event != 'push': if not self.quiet: print 'We only handle ping and push events' self.respond(304) - return + return False self.respond(204) - urls = self.parseRequest() - for url in urls: - paths = self.getMatchingPaths(url) - for path in paths: - self.fetch(path) - self.deploy(path) - - def parseRequest(self): length = int(self.headers.getheader('content-length')) body = self.rfile.read(length) payload = json.loads(body) self.branch = payload['ref'] - return [payload['repository']['url']] + self.urls = [payload['repository']['url']] + return True + + def processBitBucketRequest(self): + self.event = self.headers.getheader('X-Event-Key') + if not self.quiet: + print "Recieved event", self.event + + if self.event != 'repo:push': + if not self.quiet: + print 'We only handle ping and push events' + self.respond(304) + return False + + length = int(self.headers.getheader('content-length')) + body = self.rfile.read(length) + self.respond(204) + payload = json.loads(body) + self.branch = payload['push']['changes'][0]['new']['name'] + self.urls = [payload['repository']['links']['html']['href']] + + return True + def getMatchingPaths(self, repoUrl): res = [] @@ -95,7 +133,7 @@ def deploy(self, path): if(not self.quiet): print 'Executing deploy command' call(['cd "' + path + '" && ' + repository['deploy']], shell=True) - + elif not self.quiet: print 'Push to different branch (%s != %s), not deploying' % (branch, self.branch) break @@ -103,13 +141,13 @@ def deploy(self, path): def main(): try: server = None - for arg in sys.argv: + 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): @@ -120,7 +158,7 @@ def main(): print 'Github Autodeploy Service v0.2 started' else: print 'Github Autodeploy Service v 0.2 started in daemon mode' - + server = HTTPServer(('', GitAutoDeploy.getConfig()['port']), GitAutoDeploy) server.serve_forever() except (KeyboardInterrupt, SystemExit) as e: diff --git a/test/bitbucket.json b/test/bitbucket.json new file mode 100644 index 0000000..a797af8 --- /dev/null +++ b/test/bitbucket.json @@ -0,0 +1,198 @@ +{ + "actor": { + "username": "emmap1", + "display_name": "Emma", + "uuid": "{a54f16da-24e9-4d7f-a3a7-b1ba2cd98aa3}", + "links": { + "self": { + "href": "https://api.bitbucket.org/api/2.0/users/emmap1" + }, + "html": { + "href": "https://api.bitbucket.org/emmap1" + }, + "avatar": { + "href": "https://bitbucket-api-assetroot.s3.amazonaws.com/c/photos/2015/Feb/26/3613917261-0-emmap1-avatar_avatar.png" + } + } + }, + "repository": { + "links": { + "self": { + "href": "https://api.bitbucket.org/api/2.0/repositories/team_name/repo_name" + }, + "html": { + "href": "https://bitbucket.org/team_name/repo_name" + }, + "avatar": { + "href": "https://api-staging-assetroot.s3.amazonaws.com/c/photos/2014/Aug/01/bitbucket-logo-2629490769-3_avatar.png" + } + }, + "uuid": "{673a6070-3421-46c9-9d48-90745f7bfe8e}", + "full_name": "team_name/repo_name", + "name": "repo_name", + "scm": "git", + "is_private": true + }, + "push": { + "changes": [{ + "new": { + "type": "branch", + "name": "name-of-branch", + "target": { + "type": "commit", + "hash": "709d658dc5b6d6afcd46049c2f332ee3f515a67d", + "author": { + "username": "emmap1", + "display_name": "Emma", + "uuid": "{a54f16da-24e9-4d7f-a3a7-b1ba2cd98aa3}", + "links": { + "self": { + "href": "https://api.bitbucket.org/api/2.0/users/emmap1" + }, + "html": { + "href": "https://api.bitbucket.org/emmap1" + }, + "avatar": { + "href": "https://bitbucket-api-assetroot.s3.amazonaws.com/c/photos/2015/Feb/26/3613917261-0-emmap1-avatar_avatar.png" + } + } + }, + "message": "new commit message\n", + "date": "2015-06-09T03:34:49+00:00", + "parents": [{ + "type": "commit", + "hash": "1e65c05c1d5171631d92438a13901ca7dae9618c", + "links": { + "self": { + "href": "https://api.bitbucket.org/2.0/repositories/user_name/repo_name/commit/8cbbd65829c7ad834a97841e0defc965718036a0" + }, + "html": { + "href": "https://bitbucket.org/user_name/repo_name/commits/8cbbd65829c7ad834a97841e0defc965718036a0" + } + } + }], + "links": { + "self": { + "href": "https://api.bitbucket.org/2.0/repositories/user_name/repo_name/commit/c4b2b7914156a878aa7c9da452a09fb50c2091f2" + }, + "html": { + "href": "https://bitbucket.org/user_name/repo_name/commits/c4b2b7914156a878aa7c9da452a09fb50c2091f2" + } + } + }, + "links": { + "self": { + "href": "https://api.bitbucket.org/2.0/repositories/user_name/repo_name/refs/branches/master" + }, + "commits": { + "href": "https://api.bitbucket.org/2.0/repositories/user_name/repo_name/commits/master" + }, + "html": { + "href": "https://bitbucket.org/user_name/repo_name/branch/master" + } + } + }, + "old": { + "type": "branch", + "name": "name-of-branch", + "target": { + "type": "commit", + "hash": "1e65c05c1d5171631d92438a13901ca7dae9618c", + "author": { + "username": "emmap1", + "display_name": "Emma", + "uuid": "{a54f16da-24e9-4d7f-a3a7-b1ba2cd98aa3}", + "links": { + "self": { + "href": "https://api.bitbucket.org/api/2.0/users/emmap1" + }, + "html": { + "href": "https://api.bitbucket.org/emmap1" + }, + "avatar": { + "href": "https://bitbucket-api-assetroot.s3.amazonaws.com/c/photos/2015/Feb/26/3613917261-0-emmap1-avatar_avatar.png" + } + } + }, + "message": "old commit message\n", + "date": "2015-06-08T21:34:56+00:00", + "parents": [{ + "type": "commit", + "hash": "e0d0c2041e09746be5ce4b55067d5a8e3098c843", + "links": { + "self": { + "href": "https://api.bitbucket.org/2.0/repositories/user_name/repo_name/commit/9c4a3452da3bc4f37af5a6bb9c784246f44406f7" + }, + "html": { + "href": "https://bitbucket.org/user_name/repo_name/commits/9c4a3452da3bc4f37af5a6bb9c784246f44406f7" + } + } + }], + "links": { + "self": { + "href": "https://api.bitbucket.org/2.0/repositories/user_name/repo_name/commit/b99ea6dad8f416e57c5ca78c1ccef590600d841b" + }, + "html": { + "href": "https://bitbucket.org/user_name/repo_name/commits/b99ea6dad8f416e57c5ca78c1ccef590600d841b" + } + } + }, + "links": { + "self": { + "href": "https://api.bitbucket.org/2.0/repositories/user_name/repo_name/refs/branches/master" + }, + "commits": { + "href": "https://api.bitbucket.org/2.0/repositories/user_name/repo_name/commits/master" + }, + "html": { + "href": "https://bitbucket.org/user_name/repo_name/branch/master" + } + } + }, + "links": { + "html": { + "href": "https://bitbucket.org/user_name/repo_name/branches/compare/c4b2b7914156a878aa7c9da452a09fb50c2091f2..b99ea6dad8f416e57c5ca78c1ccef590600d841b" + }, + "diff": { + "href": "https://api.bitbucket.org/2.0/repositories/user_name/repo_name/diff/c4b2b7914156a878aa7c9da452a09fb50c2091f2..b99ea6dad8f416e57c5ca78c1ccef590600d841b" + }, + "commits": { + "href": "https://api.bitbucket.org/2.0/repositories/user_name/repo_name/commits?include=c4b2b7914156a878aa7c9da452a09fb50c2091f2&exclude=b99ea6dad8f416e57c5ca78c1ccef590600d841b" + } + }, + "created": false, + "forced": false, + "closed": false, + "commits": [{ + "hash": "03f4a7270240708834de475bcf21532d6134777e", + "type": "commit", + "message": "commit message\n", + "author": { + "username": "emmap1", + "display_name": "Emma", + "uuid": "{a54f16da-24e9-4d7f-a3a7-b1ba2cd98aa3}", + "links": { + "self": { + "href": "https://api.bitbucket.org/api/2.0/users/emmap1" + }, + "html": { + "href": "https://api.bitbucket.org/emmap1" + }, + "avatar": { + "href": "https://bitbucket-api-assetroot.s3.amazonaws.com/c/photos/2015/Feb/26/3613917261-0-emmap1-avatar_avatar.png" + } + } + }, + "links": { + "self": { + "href": "https://api.bitbucket.org/2.0/repositories/user/repo/commit/03f4a7270240708834de475bcf21532d6134777e" + }, + "html": { + "href": "https://bitbucket.org/user/repo/commits/03f4a7270240708834de475bcf21532d6134777e" + } + } + }], + "truncated": false + }] + } +} diff --git a/test/test.sh b/test/test.sh new file mode 100755 index 0000000..56023e0 --- /dev/null +++ b/test/test.sh @@ -0,0 +1,3 @@ + +# test bitbucket webhook +curl -X POST -H "User-Agent: Bitbucket-Webhooks/2.0" -H "X-Request-UUID: d0fe7a78-8f44-4ce1-9af3-5af731113caa" -H "X-Event-Key: repo:push" -H "X-Attempt-Number: 1" -H "X-Hook-UUID: 0ae064cd-be16-4e85-9824-3fc68f967d16" -H "Content-Type: application/json" -d@bitbucket.json 'http://localhost:8001'