Continuous integration with Gitlab CI & Drupal

Published

Today I want to highlight a solution that has become one of my favourite tools in web development over the summer: Gitlab with Gitlab CI.

I used to be a bit skeptical if a continuous integration solution would not be overkill for small projects but with configuration management in Drupal 8 and composer & composer-patches I’m a dedicated convert and would never want to go back to doing it by hand. You might think it’s just a git pull here or a cache-clear there but I'm certain that once you've tried it you don't want to go back.

Gitlab setup

Fire up a VPN and install the omnibus edition, then follow the instructions. Just make sure that you have at least 1GB of RAM and several GB of swap. I tried 512MB, you will run into issues that are not worth your time and effort.

Next you’ll need to actually define a runner, again, see the documentation for that. For my case it works perfectly fine to have the runner be a second user on that server. Since I’m using SSH later I’ll need to provide that user with a key-pair, since we need to add that to the authorized_keys of the production server.

Project setup

First, you’ll need a .gitlab-ci.yml file in the repository root and that can be quite minimalistic. You can execute commands directly there but since most of what I’m doing for automated deployments is happening in an ssh session, I just wrap that in a deploy script:

.gitlabl-ci.yml

stages:
  - deploy

prod-deployment:
  stage: deploy
  script:
    -  ssh user@server.ccom 'bash -s' < prod-deployment.sh
  only:
    - master

prod-deployment.sh

#!/bin/bash
set -e # We want to fail at each command, to stop execution
cd /var/www/project/drupal/web
drush sql-dump --gzip > ../../somewhere-safe/db/`date +%Y-%m-%d-%H%M`.sql.gz
cd ..
git pull
~/bin/composer install
cd web
~/bin/drush updb -y
~/bin/drush cim -y
~/bin/drush cr

When you commit that CI file you will likely get a notification that the build is stuck. Just follow the prompts until you get to the list of runners so that you can enable it for the specific project.

Of course that could be done more elegantly in a variety of ways (maintenance mode, aliases instead of directories, etc.) but it actually works extremely well. I rarely have to touch the server anymore and adding additional steps such as unit testing and code standard validation is extremely easy with such a lightweight CI solution.