Reputation: 8642
I have a remote repository (bitbucket), a server repository (linux) and many local repositories (developers).
I want the server to be notified if some developer changes a branch in the remote.
Until now i tried using a bash script declared in cron in the server but the minimal resolution is 1 minute, so to adapt it for real-time seems to be very tricky. However, my approach is this:
path=/some/dir/
# something new in remote
if git fetch origin && [ `git rev-list HEAD...origin/master --count` != 0 ]
then
echo 'Remote repository has changed. Pull needed' &>>$path/git-backup.log
echo $d >> $path/git-backup.log
git merge origin/master &>>$path/git-backup.log
fi
Upvotes: 4
Views: 2842
Reputation: 8642
Finally I solved it
In bitbucket side
All you need is to declare a Webhook pointing to the server.
In the server side
You need a mechanism listening some port all the time. This is the content of celery_listengit.py which is running all the time:
import subprocess
import threading
from tasks import git_pull
from flask import *
app = Flask(__name__)
@app.route("/", methods=['GET', 'POST'])
def listen_git4pull():
# Range of bitbucket IP Addresses that we know.
trusted = ['131.103.20', '165.254.145', '04.192.143']
incoming = '.'.join(str(request.remote_addr).split('.')[:-1])
if incoming in trusted:
git_pull.delay()
# OK
resp = Response(status=200, mimetype='application/json')
else:
# HTTP not authorized
resp = Response(status=403, mimetype='application/json')
return resp
class CeleryThread(threading.Thread):
def run(self):
error_message = ('Something went wrong when trying to '
'start celery. Make sure it is '
'accessible to this script')
command = ['celery',
'-A',
'tasks',
'worker',
'--loglevel=info']
try:
_ = subprocess.check_output(command)
except Exception:
raise Exception(error_message)
if __name__ == '__main__':
celery_thread = CeleryThread()
celery_thread.start()
app.run(host='0.0.0.0')
And this is the contents of tasks, where git_pull() function is declared. This have to be delayed because git.pull() could take a lot of time, so it must run after server responds with HTPP OK status:
from git import *
from celery.app.base import Celery
app = Celery('tasks',
backend='amqp://guest@localhost//',
broker='amqp://guest@localhost//')
app.conf.update(
CELERY_ACCEPT_CONTENT=['json'],
CELERY_TASK_SERIALIZER='json',
CELERY_RESULT_SERIALIZER='json',)
@app.task
def git_pull():
repo = Repo('.')
o = repo.remotes.origin
o.fetch()
o.pull()
Upvotes: 3