wordpressbashgitgithooksgit-post-receive

Git post-receive hook doesn't work with Github


Background and Setup

I'm trying to follow the last part of this tutorial here to create a post-receive Git hook (really just an example, the instructions everywhere else are basically identical).

As well as my local repository, I have a GitHub repo set up as a remote called central, and a production server set up as a remote called live. I have everything in place such that I'm able to easily push from the local repository to GitHub, and SSH into the production server to pull from GitHub.

The Goal

I want to do away with the latter step entirely, so that all I need to do is push to the central repository, from where the production server will pull those changes automatically - and everything I've seen tells me a post-receive hook is the way to do this.

The Problem

For some reason, everything I've tried so far to get the post-receive hook to work has failed.

My post-receive file exists on my production server in .git/hooks/, it's been made executable with chmod ug+x, and yes, "post-receive" is spelt right. The post-receive file contains the following Bash code:

#!/bin/sh
cd ~/www.example.com/public_html || exit
unset GIT_DIR
git pull central master
exec git update-server-info

I can even SSH into the production server and execute the post-receive hook manually, and yet for some reason it isn't triggered when I push to the central repository, despite the fact that all the guides specify this is the way it should work.

The single way that I've diverged from these guides is that the repository on my server is a non-bare one, but from what I've learnt of the differences between the two this shouldn't make a difference where it's already been established that I can push and pull as normal.

So why exactly is my post-receive hook not working?

Edit: Test 1

Changing the cd line to:

cd ~/www.example.com/public_html && touch ./cd_ran_successfully || exit

...and then doing the push command locally results in no cd_ran_successfully file being created on the server. However, manually executing the file when logged into the server, does create the file. This indicates some sort of problem with the user/process that the shared server is using to execute the file, but other than that I have no idea.


Solution

  • A post-receive hook is a server-side hook, it needs to be on your git server.

    Generally, to run custom hooks you will need to host your own git server. From what it sounds like what you want, you need to setup your production server to also host a git server that you can set up as a different git remote that you can push to.

    Then you can setup your post-receive to deploy the files as needed.

    Alternatively, you can setup a pre-push script to let your prod server know an update is available, albeit it is pretty hacky.

    pre-push:

    #!/usr/bin/env bash
    
    ssh user@prod "/home/user/my_script.sh &"
    

    my_script.sh

    #!/usr/bin/env bash
    
    # Wait for push to go through
    sleep(25)
    
    cd git_dir && git pull
    
    # Deploy
    cp git_dir/binary /usr/bin/