Triggering Jenkins to make a new build in Drupal 8

Recently we’ve set up automated deployments for our new Drupal 8 projects. We’ve set up a new server with a jenkins-instance, we added bitbucket integration so that a new push to origin/* triggers the jenkins server to make a new build.

How do we go about it?

We’re using a fork of drupal-composer for all of our projects, so they all have the same layout. They all have a root folder that looks like this:

web/
vendor/
scripts/
 - build.sh
 - deploy-qa.sh
 - deploy-prod.sh
composer.json
composer.lock
 

Changing the way projects are built to suit their specific needs

Our build-script is probably the easiest out of all scripts but it’s also the one that’s does the actual transforming from the codebase into a working website. We’ve set up jenkins so that it executes ./scripts/build.sh, which mean we can change the way projects are built to suit the project’s specific needs.

After the build-script has run, jenkins will execute deploy-qa or deploy-prod depending on the target environment.

We’ve set it up with the scripts in the project repository so that we can keep our jenkins setup very simple.
 

Sneek preview of the basic script

This is what the basic build-script looks like.

#!/usr/bin/env bash
# Install all dependencies.
composer install --dev;
# Build all theme dependencies and assets.
cd web/themes/custom/project_foundation;
npm install;
gulp bower;
gulp build;
cd -;

# run phpunit
./vendor/bin/phpunit -c web/core web/modules/custom

# install composer dependencies again without dev dependencies for smaller build
# result
composer install --no-dev;

You can see that we’re going into the project_foundation folder, this is a sub-theme of zurb_foundation, it’s not called project_foundation in our actual projects though, the install-script replaces "project" with the name of the actual project, so for a website “foo”, this’ll be foo_foundation.

We’re currently not running PHPCS on this to check for coding standards in our custom projects, but that’s on the todo-list, I was hoping to see https://www.drupal.org/node/2744463 land in 8.2, but it looks like that’ll be 8.3+ so we’re going to be integrating that ourselves in the coming weeks.

Our deploy scripts both work in pretty much the same way, I won’t be pasting code here, but it’s pretty easy to figure out. First off, we’re bundling all the results into a tar-ball, then moving that file the other server trough scp. On the remote server, we’re unpacking the results into a site.new folder, then moving the current site folder to site.old before moving site.new into site. This means that we always have 2 checkouts of files in the server and we can switch back to the previous version really easy.

Customers following along in real time

After that, we move into site; import configuration and clear caches. And just like that, the new version of the site is online.

Currently our builds take about 2 minutes to finish, with the bulk of the time spent on npm install / gulp build. That time doesn’t really matter though, we deploy 5-10 times a day, depending on how many people are working on a project and our customers can follow along with the progress on their sites in real-time.