Git Sync Remote Branch Automatically by Webhook
How to make your local repository always sync with GitHub repository? The answer is webhook.
When the repo received a push event, GitHub will send a
POST
request to the webhook URL with details of any
subscribed events. What we need to do is to implement a webhook (on
local side) which performs git pull
to keep sync with
remote.
Simplest GitHub Webhook Implementation
What's a webhook?
Webhooks allow you to build or set up integrations, such as GitHub Apps or OAuth Apps, which subscribe to certain events on GitHub.com. When one of those events is triggered, we'll send a HTTP POST payload to the webhook's configured URL. Webhooks can be used to update an external issue tracker, trigger CI builds, update a backup mirror, or even deploy to your production server. You're only limited by your imagination
Here we implement a simplest webhook which handles push event from
GitHub. No secret, no payload parsing, just
git pull --ff-only origin master
when receiving the push
event. More complicated webhook development can refer to here.
#!/usr/bin/python
import git
import logging
from flask import Flask
logging.basicConfig(level=logging.INFO)
app = Flask('gitwebhook')
def pull():
repo = git.Repo('/home/local/repo/folder')
repo.git.checkout('master')
repo.git.pull('--ff-only', 'origin', 'master')
@app.route('/push',methods = ['POST'])
def handle_push():
logging.info("Received push event")
try:
pull()
except Exception as ex:
return str(ex), 500
return 'Success'
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
The above code is pretty clean and self-explained. We use
Flask
as the webserver and leverage gitpython
to perform git operations.
Then we can serve the webhook on your local machine which can access
the local repo /home/local/repo/folder
. Assume the server
is running at https://example.com:5000/
.
Configure Webhook on GitHub
Goto repo Settings
-> Webhooks
->
Add Webhook
:
Done.
Let's check the delivery result by clicking the webhooks detail,
Recent Deliveries
:
The webhook return success if it pulls remote master by fast-forward, otherwise, an exception will be thrown and return HTTP 500.