I’ve found that when I update my website, it’s tedious to manually copy the files up to my CPanel hosting platform. And my website source code is already on Github version control, so I wanted to be able to automatically update the static files when I push my HTML up to Github.
The only way to achieve this is to utilise Git’s post-receive hook (and Github’s webhooks) and trigger some code on my site which could a perform git pull.
Git hooks are actions that can run your own scripts when events happen to your repository – commit or pull for example – then do whatever task is handy for you. Webhooks are HTTP payloads sent from one server to another, when some event occurs, to trigger off another action in turn on the receiving server.
Some research led me to oxguy3’s deploy.php Github Gist which receives Github’s post-receive webhook and initiates a git pull on on the web host:
Set up a webhook on your repository in the settings of the Github repository and give it a password. Really I just followed oxguy3’s directions, it’s well documented.
Their PHP script is quite good, it even uses Github’s authorisation headers to prevent randoms from triggering the deploy script.
But oxguy3’s script had to ssh to their server (inside the script) since their host had blocked PHP shell_exec. But my web host hasn’t blocked shell_exec so I could take out those pieces of code. So my forked gist becomes:
The script also emails me when it’s complete and the output. If you started from an empty public_html folder you’d be right to run the script now. (I wasn’t though, read on if interested.)
On my actual website, acarrick.com, I already had website HTML up. I also couldn’t SSH easily to run git pull. But I could use the built-in git command in CPanel which pulled the repository into a non-public folder. So I copied the .git folder and overrode my existing HTML/CSS to my public_html folder and pushed up some new code to Github.
But when I ran it, all I got was 2 lines of git hashes. I had to create a temporary PHP script to run git commands in shell_exec to work out the issue. It turned out that my working copy and the repository were out of sync. So I could use git checkout –force to reset the state of the existing files so Git realises that it’s OK to pull down and merge.
<?php
$output = shell_exec('cd ~/public_html && git checkout --force 2>&1');
echo $output;
?>
The 2>&1 at the end of the output tells PHP to also capture the stderr from the shell command so you can see what went wrong. Earlier I used the above script but with git pull instead of checkout to see why it wasn’t merging.