Continuous integration with Drupal 8 and Gitlab CI/CD

Introduction

A release of new versions of programming software is fraught with considerable difficulties - there always may be unexpected errors in the process of deploying a web application to the environment that leads to a non-working application in production. In order to minimize these risks, the methodology of continuous deployment is used. The basis of this methodology is the deployment pipeline, that allows us to automate testing and deployment of the application, thereby increasing the speed of the deployment and reducing the risks in a process of releasing a new version.

If you are using the Gitlab platform for your project, it already has a built-in CI/CD support. Together with free private repositories, a bug tracker, and other features, it makes the cloud-based service useful not only for storing code but also for testing and deploying. 

In this article, we will look at the configuration of the pipeline using Gitlab, configure necessary files, learn how to run building of the application and unit tests on a separate docker image, as well as automatically send the built application to a staging or production server. And all of this we can do just using a couple of lines in the configuration file! Sounds interesting? Let's start!

Configuring GitLab continuous delivery

First of all, you need 3 things to start using Gitlab CI: 

1. The working instance of gitlab or gitlab.com.
2. The configuration file with the description of the pipeline .gitlab-ci.yml in the root directory of your project.
3. The configured gitlab task runner, which executes the commands described in the pipeline.

Gitlab Runner is the project that is used for execution of jobs described in the .gitlab-ci.yml file and also it communicates with Gitlab using its own API.

In addition to installing an own runner on a custom hosting, you can use ready shared runners hosted on Digital Ocean. To do this, on a Gitlab project page go to settings-CI/CD-runner settings-enable shared runners in the settings of your project. There you can also find the documentation on installing your own runner on a dedicated server.

After we've finished with the runner, let's take a closer look at the deployment process. The pipeline of Gitlab consists of several stages, by default it is build, test, and deploy, each of them consists of 1 or more ci jobs. Jobs in Gitlab are independent tasks that can be performed in parallel. After completing all the jobs at one stage, the runner starts to execute the next stage.

Build and test stage

Let's create the .gitlab-ci.yml file in the root of the project and specify our custom stages: 

For the build stage, we create a build job that installs our Drupal 8 project vendor dependencies using Сomposer and launch our custom tests.

To do this, we need to specify a Docker image for the Gitlab runner, for the brevity we will use the tetraweb/php image which already contains the installed PHP and Node.js in this example.
 

We can also specify several jobs with different versions of PHP and test our application for different versions.

In the before_script: section which is performed before the main script execution, we install Composer and necessary packages.
 

Now after we have installed Сomposer, in the script section we run the building of our project.

After the successful completion of the job, we can attach resulting files to it, this is called an artifact.

For the artifact, we can specify its name, duration of storage and other settings, as well as a list of files to be added.

{CI_COMMIT_SHA} is a built-in placeholder, in the future, we will also be able to define our own constants.
 

In case we want to run the job only for commits from a specific branch, you can specify it in the section directive ‘only’.
 

In the end, our config file will look like this:
 

If we want to run a unit test for the built application, let’s add the following line to the end of the script directive:
 

--testsuite = unit flag indicates that we are running unit tests only, which do not require the installed Drupal.

So, after pushing the configuration file into the master branch of your repository, go to the CI/CD-pipelines at the project page and you will see that our task runner automatically began to perform the pipeline. If we do not want to run it automatically, we can add the following directive.
 

If the job is finished without errors, we can download the resulting artifact.
 

Continuous integration with Drupal 8 and Gitlab CI/CD

Deploy stage

Okay, we've installed dependencies for our application and have run out some of the unit tests, let's try to deploy it into the stage environment, for example, for the user acceptance testing.

We need to create a new deploy_stage job, which is related to the stage deploy, that we declared above.

First of all, we need to create a variable inside of Gitlab where we will store a private ssh key for access to our server. Go to the settings-CI/CD-secret variables and enter necessary values. 
 

Continuous integration with Drupal 8 and Gitlab CI/CD_3

In this script, we've installed the ssh-agent on the Docker container and disabled StrictHostKeyChecking in the ssh configs in the before_script block. After that, we can log in to the stage environment server via the ssh. 

There are several ways to copy project files to the server, in this case, we copy them to the tmp folder via SCP, then we replace the folders and move the config file settings.env.php to the working directory. We also created a backup of a database, ran import of the Drupal config files and database updates.

Afterword

In this article, we've learned how to use Gitlab CI/CD in our project and wrote some config file. Of course, for the real project, you will want to add more stages and jobs, this is just a very basic example how to use this service. I hope you will start using a continuous delivery approach in your project and make your deploy process easier. 

You might also like