I love GitHub Pages. They remind me the first time I witnessed the elegance of the deployment using git strategy: simply git push to the master branch of your repository and your static web page is updated. As simple as that.

I wanted to be able to deploy with the same elegance on my own servers and for more complex applications. I thought I understood how it worked but not how to automate it. So I would manually ssh into the server, cdmy way into the project folder, then git pull. Every. time. Not really convenient.

When I discovered Trellis I learned to use ansible to be able to deploy by using a oneliner: ./deploy.sh production domain.com)…

But then Ansible is a power tool, which does a lot of other things than just deploy. And I learned the hard way that I should not update my local Ansible version otherwise… All hell break loose. 
Also, I would still have to git push to the remote prior to launching the deployment.

One line to rule them all

Working at BeCode is cool because you get to meet dozen of fellow developers, craving to learn and explore. One of our learners pointed me in the direction of using a GitHub Post-Receive hook, thanks to which deployment is a simple : git push production master. The hook launches a local script that git checkout the master branch on the production server, then runs any other custom operations you want (such as composer updatefor example).

Let’s see how to set it up.

1. Setup a bare Git repository on production server

First, create a “bare” repository – one that does not contain the working copy files. It basically is the content of the .git repository folder in a normal working copy. Name it whatever you like (you could also omit the .git part from project.git but I find it best to keep it):

cd /path/to/project/folder/
mkdir project-name.git
cd project-name.git
git init --bare

2. Configure the GitHub hook

Create a post-receive hook at /path/to/project/folder/project-name.git/hooks/post-receive

Fill it with the following code:

#!/bin/sh
NOW=$(date +'%d-%m-%Y_%T')
# check out master branch
GIT_WORK_TREE=/path/to/destination/folder/htdocs git checkout -f master

# custom steps for deployment
# For example, let's execute composer to refresh our dependencies : 
cd /path/to/destination/folder/htdocs
composer update
# backup current version, in case we need to do a rollback
cp -R /path/to/destination/folder/htdocs/. /backups/project-name/$NOW/

Make sure it is executable:

chmod +x post-receive

3. Add the remote-repository to your local system

Let’s now add this bare repository to our local system as a remote. Let’s call this remote “production”. (It could also be called “staging” or “live” or “test”… should you want to deploy to a different system or to multiple systems.)

cd ~/path/to/working-copy/
$ git remote add production username(Replace this parenthesis with the @ sign)myserver.com:/path/to/project/folder/project-name.git

And… that’s it!

You can now deploy using this beautiful one liner git push production master.

Going beyond ? TDD !!

With this, I have the raw basis of a deployment pipeline. The next step would be to add code testing to make sure code updates do not introduce bugs or break anything (regression testing). I assume I should look at how to use Ansible for that.

Since I don’t know how to do that yet, I’ll leave you to google dev.to/search your way around that one !


This article was originally posted on dev.to