GitLab Webhooks

Some versions ago, I think it was version 5.2, GitLab introduced Webhooks. I didn't like them at first but that changed since I found a great PHP-script, which I slightly modified.

I am a big fan of GitLab (even though the updateprocedures are pure horror) and I am using it for all the jobs and projects I am working on. I think GitLab is a great alternative to GitHub.

To get a smoothly running workflow and because I don't want to copy or pull files after pushing them to see the Changes on the websites, I use hooks.

Hooks?

Hooks are little scripts, run at a certain time. For example when changes where pushed to a repository. You can use these hooks to update a website automagically after a push, or take a stupid looking picture of yourself with every commit.

WebHooks?

Now there are those webhooks. Principle they work the same as normal hooks. With every push a script is run. Until now, in my case, those scripts where simple BaSh-scripts. But those webhooks are working a bit differnt. You don't create a BaSh-script for every repository, you just tell GitLab what URL to open.
With every push, this URL will be opened and the relevant data will be submitted as JSON-string.

The big advantage is, you can execute different scripts by adding additional URLs.
The disadvantage is, you cannot use BaSh-Scripts anymore, because those normally aren't reachable via an URL.

The solution

So I looked around on the web and found a PHP-Script which seems to fit my needs.
The script evaluate the JSON and updates the corresponding branch. It even creates a folder for branches which didn't exist before.

So, whenever I push something to my master-branch, the URL (PHP-script) will be opened and the directory "master" will be updated or created if it doesn't exist.

So far, so good.

There are two things, I didn't like.

  1. I have to copy the script for every repository and edit the included Path and URL to the repository.
  2. It might happen, that I am working on branches, which do not need to be transfered to the webserver. Particularly when working on bigger projects there might be various branches which are merged from time to time, but must not be available on the webserver.

My modified solution

So I took the script and thought about, how to improve it. And this is how my solution works:

The PHP-script has to be copied to the server on which the webserver is running. I use a vhost for it, so I have a nice domain for that. The script has to exist once only.

Also I created a config-file. A simple JSON-file which has the following structure:

{
    "repoName": {
        "path": "/path/to/folder",
        "limit": null
    }
}

The name of the repository as to be the exact name as set up in GitLab, because the name will be submitted within the GitLab-JSON and can be referenced that way.

path is the directory in which the subdirectories for each branch will be created. In most cases this will be within document-root.

limit can be null, then all branches will be cloned and updated. If you whish just to update certain branches, you can give limit a comma-separated list of branch-names.

"limit": "master,testing"

You do that for each repository.

In this way you just have to maintain two files. The PHP and the config-file. If you make changes to the PHP you do not have to make those changes several times.

Trouble?

To get the script running, some basic steps have to be done before (creating deploy-key etc.). I will not explain those here, because they are explained in the blogpost of the original script very well.

Attention meridimus was so nice to give us a tip in the comments. In step 7 of the original article, the directory also needs the execution-flag so the known_hosts file can be created. Do it like so:

$ sudo chmod -R 0600 /var/www/.ssh
$ sudo chmod 0700 /var/www/.ssh
$ sudo chown -R www-data:www-data /var/www/.ssh

Download

if you are interessted in the script, you can take a look at GitHub.

Update

I wrote another article about how to automate your deploy-configuration with a simple bash-script.