summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOliver Poignant <oliver@poignant.se>2016-03-05 02:05:15 +0100
committerOliver Poignant <oliver@poignant.se>2016-03-05 02:05:15 +0100
commita1cb9ca8eceec8a7e1883b280a54c68100cafd7e (patch)
tree9e62011b347e8b26206282de02d848e8bfce9094
parent5b525b98a9226e1232e233fcbaea684a49c52255 (diff)
parentfd16c583425112d8d3be350fe40de5cae17f35c6 (diff)
downloadGit-Auto-Deploy-a1cb9ca8eceec8a7e1883b280a54c68100cafd7e.zip
Git-Auto-Deploy-a1cb9ca8eceec8a7e1883b280a54c68100cafd7e.tar.gz
Git-Auto-Deploy-a1cb9ca8eceec8a7e1883b280a54c68100cafd7e.tar.bz2
Merge pull request #69 from olipo186/development
Refactoring. Fixed some imminent issues.
-rwxr-xr-xGitAutoDeploy.conf.json.example35
-rwxr-xr-xGitAutoDeploy.py172
-rw-r--r--README.md20
-rw-r--r--docs/continious_delivery_process.gliffy (renamed from continious_delivery_process.gliffy)0
-rw-r--r--docs/continious_delivery_process.png (renamed from continious_delivery_process.png)bin48686 -> 48686 bytes
5 files changed, 139 insertions, 88 deletions
diff --git a/GitAutoDeploy.conf.json.example b/GitAutoDeploy.conf.json.example
index 15898f4..babdb98 100755
--- a/GitAutoDeploy.conf.json.example
+++ b/GitAutoDeploy.conf.json.example
@@ -1,14 +1,14 @@
{
- "pidfilepath": "~/.gitautodeploy.pid",
- "logfilepath": "~/gitautodeploy.log",
- "host": "0.0.0.0",
- "port": 8001,
- "global_deploy": [
- "echo Deploy started!",
- "echo Deploy completed!"
- ],
- "repositories":
- [{
+ "pidfilepath": "~/.gitautodeploy.pid",
+ "logfilepath": "~/gitautodeploy.log",
+ "host": "0.0.0.0",
+ "port": 8001,
+ "global_deploy": [
+ "echo Deploy started!",
+ "echo Deploy completed!"
+ ],
+ "repositories": [
+ {
"url": "https://github.com/olipo186/Git-Auto-Deploy.git",
"branch": "master",
"remote": "origin",
@@ -21,9 +21,14 @@
},
{
"url": "https://api.github.com/repos/olipo186/Git-Auto-Deploy",
- "pullrequestfilter": true,
- "action": "closed",
- "ref": "testing",
- "deploy": "echo deploying after pull request"
- }]
+ "deploy": "echo deploying after pull request",
+ "filters": [
+ {
+ "type": "pull-request-filter",
+ "action": "closed",
+ "ref": "testing-branch"
+ }
+ ]
+ }
+ ]
} \ No newline at end of file
diff --git a/GitAutoDeploy.py b/GitAutoDeploy.py
index 2ef3aae..f053245 100755
--- a/GitAutoDeploy.py
+++ b/GitAutoDeploy.py
@@ -119,31 +119,17 @@ class GitWrapper():
if 'path' in repo_config:
path = repo_config['path']
- cmds = []
- if 'deploy' in repo_config:
- cmds.append(repo_config['deploy'])
-
- gd = GitAutoDeploy().get_config()['global_deploy']
- if len(gd[0]) is not 0:
- cmds.insert(0, gd[0])
- if len(gd[1]) is not 0:
- cmds.append(gd[1])
-
logger.info('Executing deploy command(s)')
+
+ # Use repository path as default cwd when executing deploy commands
+ cwd = (repo_config['path'] if 'path' in repo_config else None)
- if logFilePath:
- with open(logFilePath, 'a') as logfile:
- for cmd in cmds:
- if 'path' in repo_config:
- call(['cd "' + path + '" && ' + cmd], stdout=logfile, stderr=logfile, shell=True)
- else:
- call([cmd], stdout=logfile, stderr=logfile, shell=True)
- else:
- for cmd in cmds:
- if 'path' in repo_config:
- call(['cd "' + path + '" && ' + cmd], shell=True)
- else:
- call([cmd], shell=True)
+ for cmd in repo_config['deploy_commands']:
+ if logFilePath:
+ with open(logFilePath, 'a') as logfile:
+ call([cmd], cwd=cwd, stdout=logfile, stderr=logfile, shell=True)
+ else:
+ call([cmd], cwd=cwd, shell=True)
class WebhookRequestHandler(BaseHTTPRequestHandler):
@@ -283,6 +269,10 @@ class WebhookRequestHandler(BaseHTTPRequestHandler):
return repo_urls, ref or "master", action
+# Used to describe when a filter does not match a request
+class FilterMatchError(Exception): pass
+
+
class GitAutoDeploy(object):
config_path = None
debug = True
@@ -369,28 +359,45 @@ class GitAutoDeploy(object):
# Process each matching repository
for repo_config in repo_configs:
- if repo_config['pullrequestfilter'] and (repo_config['ref'] != ref or repo_config['action'] != action):
+ try:
+ # Verify that all filters matches the request if specified
+ if 'filters' in repo_config:
+ for filter in repo_config['filters']:
+ if filter['type'] == 'pull-request-filter':
+ if filter['ref'] == ref and filter['action'] == action:
+ continue
+ raise FilterMatchError()
+ else:
+ logger.error('Unrecognized filter: ' % filter)
+ raise FilterMatchError()
+
+ except FilterMatchError as e:
continue
-
- if 'path' in repo_config:
- running_lock = Lock(os.path.join(repo_config['path'], 'status_running'))
- waiting_lock = Lock(os.path.join(repo_config['path'], 'status_waiting'))
+
+
+ # In case there is no path configured for the repository, no pull will
+ # be made.
+ if not 'path' in repo_config:
+ GitWrapper.deploy(repo_config)
+ continue
+
+ running_lock = Lock(os.path.join(repo_config['path'], 'status_running'))
+ waiting_lock = Lock(os.path.join(repo_config['path'], 'status_waiting'))
try:
- if 'path' in repo_config:
- # Attempt to obtain the status_running lock
- while not running_lock.obtain():
+ # Attempt to obtain the status_running lock
+ while not running_lock.obtain():
- # If we're unable, try once to obtain the status_waiting lock
- if not waiting_lock.has_lock() and not waiting_lock.obtain():
- logger.error("Unable to obtain the status_running lock nor the status_waiting lock. Another process is " +
- "already waiting, so we'll ignore the request.")
+ # If we're unable, try once to obtain the status_waiting lock
+ if not waiting_lock.has_lock() and not waiting_lock.obtain():
+ logger.error("Unable to obtain the status_running lock nor the status_waiting lock. Another process is " +
+ "already waiting, so we'll ignore the request.")
- # If we're unable to obtain the waiting lock, ignore the request
- break
+ # If we're unable to obtain the waiting lock, ignore the request
+ break
- # Keep on attempting to obtain the status_running lock until we succeed
- time.sleep(5)
+ # Keep on attempting to obtain the status_running lock until we succeed
+ time.sleep(5)
n = 4
while 0 < n and 0 != GitWrapper.pull(repo_config):
@@ -400,20 +407,18 @@ class GitAutoDeploy(object):
GitWrapper.deploy(repo_config)
except Exception as e:
- if 'path' in repo_config:
- logger.error('Error during \'pull\' or \'deploy\' operation on path: %s' % repo_config['path'])
+ logger.error('Error during \'pull\' or \'deploy\' operation on path: %s' % repo_config['path'])
logger.error(e)
finally:
- if 'path' in repo_config:
- # Release the lock if it's ours
- if running_lock.has_lock():
- running_lock.release()
+ # Release the lock if it's ours
+ if running_lock.has_lock():
+ running_lock.release()
- # Release the lock if it's ours
- if waiting_lock.has_lock():
- waiting_lock.release()
+ # Release the lock if it's ours
+ if waiting_lock.has_lock():
+ waiting_lock.release()
def get_default_config_path(self):
import os
@@ -483,6 +488,30 @@ class GitAutoDeploy(object):
for repo_config in self._config['repositories']:
+ # Setup branch if missing
+ if 'branch' not in repo_config:
+ repo_config['branch'] = "master"
+
+ # Setup remote if missing
+ if 'remote' not in repo_config:
+ repo_config['remote'] = "origin"
+
+ # Setup deploy commands list if not present
+ if 'deploy_commands' not in repo_config:
+ repo_config['deploy_commands'] = []
+
+ # Check if any global pre deploy commands is specified
+ if len(self._config['global_deploy'][0]) is not 0:
+ repo_config['deploy_commands'].insert(0, self._config['global_deploy'][0])
+
+ # Check if any repo specific deploy command is specified
+ if 'deploy' in repo_config:
+ repo_config['deploy_commands'].append(repo_config['deploy'])
+
+ # Check if any global post deploy command is specified
+ if len(self._config['global_deploy'][1]) is not 0:
+ repo_config['deploy_commands'].append(self._config['global_deploy'][1])
+
# If a Bitbucket repository is configured using the https:// URL, a username is usually
# specified in the beginning of the URL. To be able to compare configured Bitbucket
# repositories with incoming web hook events, this username needs to be stripped away in a
@@ -496,29 +525,39 @@ class GitAutoDeploy(object):
if 'path' in repo_config:
repo_config['path'] = os.path.expanduser(repo_config['path'])
- if 'path' in repo_config:
- if not os.path.isdir(repo_config['path']):
+ return self._config
- logger.error("Directory %s not found" % repo_config['path'])
- GitWrapper.clone(url=repo_config['url'], branch=repo_config['branch'] if 'branch' in repo_config else None, path=repo_config['path'])
+ def clone_all_repos(self):
+ """Iterates over all configured repositories and clones them to their
+ configured paths."""
+ import os
+ import re
- if not os.path.isdir(repo_config['path']):
- logger.warning("Unable to clone %s branch of repository %s. So repo will not pull. Only deploy command will run(if it exist)" % (repo_config['branch'] if 'branch' in repo_config else "default", repo_config['url']))
- # sys.exit(2)
+ # Iterate over all configured repositories
+ for repo_config in self._config['repositories']:
+
+ # Only clone repositories with a configured path
+ if 'path' not in repo_config:
+ logger.info("Repository %s will not be cloned (no path configured)" % repo_config['url'])
+ continue
+
+ if os.path.isdir(repo_config['path']) and os.path.isdir(repo_config['path']+'/.git'):
+ logger.info("Repository %s already present" % repo_config['url'])
+ continue
- else:
- logger.info("Repository %s successfully cloned" % repo_config['url'])
- if not os.path.isdir(repo_config['path'] + '/.git'):
- logger.warning("Directory %s is not a Git repository. So repo will not pull. Only deploy command will run(if it exist)" % repo_config['path'])
- # sys.exit(2)
+ # Clone repository
+ GitWrapper.clone(url=repo_config['url'], branch=repo_config['branch'], path=repo_config['path'])
+
+ if os.path.isdir(repo_config['path']):
+ logger.info("Repository %s successfully cloned" % repo_config['url'])
else:
- logger.warning("'Path' was not found in config. So repo will not pull. Only deploy command will run(if it exist)")
+ logger.error("Unable to clone %s branch of repository %s" % (repo_config['branch'], repo_config['url']))
- return self._config
def get_matching_repo_configs(self, urls):
- """Iterates over the various repo URLs provided as argument (git://, ssh:// and https:// for the repo) and
- compare them to any repo URL specified in the config"""
+ """Iterates over the various repo URLs provided as argument (git://,
+ ssh:// and https:// for the repo) and compare them to any repo URL
+ specified in the config"""
config = self.get_config()
configs = []
@@ -682,6 +721,9 @@ class GitAutoDeploy(object):
# Initialize base config
self.get_config()
+
+ # Clone all repos once initially
+ self.clone_all_repos()
if self.daemon:
logger.info('Starting Git Auto Deploy in daemon mode')
@@ -697,6 +739,8 @@ class GitAutoDeploy(object):
# Clear any existing lock files, with no regard to possible ongoing processes
for repo_config in self.get_config()['repositories']:
+
+ # Do we have a physical repository?
if 'path' in repo_config:
Lock(os.path.join(repo_config['path'], 'status_running')).clear()
Lock(os.path.join(repo_config['path'], 'status_waiting')).clear()
diff --git a/README.md b/README.md
index f5566f4..e3f6660 100644
--- a/README.md
+++ b/README.md
@@ -80,20 +80,22 @@ The easiest way to configure your system to automatically start ```GitAutoDeploy
## Continious Delivery via Pull request
-![Workflow](./continious_delivery_process.png)
+![Workflow](./docs/continious_delivery_process.png)
If you use continious delivery (such as this workflow) you may want to trigger deploy event when pull request is opened or closed.
You can follow next steps to implement CD process:
* Set repo "url" to ```"https://api.github.com"```
-* Enable "pullrequestfilter"
+* Add filter type "pull-request-filter" as described below
* Configure "action" that you want to listen
-* Configure branch in which pull request trying to merge (called "ref" in configure)
+* Configure branch in which pull request trying to merge (variable "ref" below)
Example
-```
-"url": "https://api.github.com/repos/olipo186/Git-Auto-Deploy",
-"pullrequestfilter": true,
-"action": "closed",
-"ref": "testing",
-"deploy": "echo deploying after pull request"
+```"url": "https://api.github.com/repos/olipo186/Git-Auto-Deploy",
+"deploy": "echo deploying after pull request",
+"filters": [
+{
+ "type": "pull-request-filter",
+ "action": "closed",
+ "ref": "testing-branch"
+}]
``` \ No newline at end of file
diff --git a/continious_delivery_process.gliffy b/docs/continious_delivery_process.gliffy
index 13e1fca..13e1fca 100644
--- a/continious_delivery_process.gliffy
+++ b/docs/continious_delivery_process.gliffy
diff --git a/continious_delivery_process.png b/docs/continious_delivery_process.png
index 2dc01b4..2dc01b4 100644
--- a/continious_delivery_process.png
+++ b/docs/continious_delivery_process.png
Binary files differ