Skip to content


What is continuous integration?

Continuous integration (CI) is the practice of running an automated pipeline of scripts to build and test a project after every change.

This allows maintainers to identify bugs early in the development cycle, ensuring that all code that is pushed into the main development branch is compliant with the requirements of the project.

Continuous deployment

Continuous deployment (CD) takes this another step further by automating the process of deploying an application to production after every change.

If configured correctly (this is the default), CI pipelines will run for every merge request, meaning the modified code can be build and tested before changes are accepted into the repository.

The fork-branch-merge-request presented earlier can then be augmented to include CI at all stages

GitLab workflow with CI

How to enable CI on GitLab

All Gitlab CI/CD is configured with a YAML-format file called .gitlab-ci.yml in the root of the project repository.


Running a simple script

A basic example could just check that your script runs without failing. Consider the example from

Simple Gitlab-CI configuration

image: python

    - python

Here, a single job called test is configured to run python If that command exits with code 0, the job passes, otherwise it fails.

image: python

We use image: python to declare to GitLab-CI that this job should run inside a python container.

The default is image: docker:latest.

An example of this pipeline running is here:

Building a (python) package

A more complicated example is available on the package branch of the same gitlab-example repository:

Here the full YAML configuration is:

Building and testing a Python package

  - build
  - test

image: python

  stage: build
    - python -m pip install build
    - python -m build --wheel --outdir .
      - "hello_world-*.whl"

  stage: test
          - "3.11"
          - "3.12"
  image: python:${PYTHON_VERSION}
    - build
    - python -m pip install hello_world-*.whl
    - hello-world

Here we define a more complicated pipeline with two stages:

graph TD;
    build-->py311["test: [3.11]"];
    build-->py312["test: [3.12]"];

The build job uses artifacts to store the output of its job (the built wheel) so that it can be used in later jobs.

This configuration also uses parallel:matrix to create multiple test jobs running in different images based on the PYTHON_VERSION variable.

An example of this pipeline running is here:

Other examples

gwdatafind/gwdatafind (python package with automated tests): :

lscsoft/bayeswave (cmake build with binary packaging and tests): :

lscsoft/lalsuite (multi-package, multi-distribution package suite with scheduled nightly jobs): :

emfollow/gwcelery (python package with documentation, tests, and continuous deployment to multiple locations): :

Modular pipelines with CI/CD components

The above simple examples are easy to understand and maintain, however when developing complex applications, or working on multiple independent projects, maintaining high-quality CI/CD pipelines that track the latest best practices can be a daunting task.

To improve this situation, GitLab supports CI/CD components, reusable pipeline configuration units that create parts of the whole pipeline, and can be shared easily across multiple projects.

The IGWN Computing and Software Working Group maintain a suite of CI/CD components that are visible in the IGWN GitLab CI/CD Catalog:

For details, see Components.

GitLab Pages

GitLab supports building static web content with CI and hosting them through Gitlab with an extension called Pages.

An example of this can be seen for this webpage:

For more details, see

Runners and tags

This section has been moved here.

Advanced concepts


MATLAB can be used in Gitlab CI only from a runner machine that can access a license file or a network license manager.

Finding the License server information

The license information for the LIGO-Caltech MATLAB license can be discovered directly from any of the LDAS-CIT login hosts as follows:

cat /ldcg/matlab_r2021b/licenses/network.lic | grep ^SERVER | awk -v RS='\r?\n' '{ print $4 "@" $2 }'

Replace the version as required

The MATLAB version (r2021b in the above command) should be replaced with whatever version is configured in your .gitlab-ci.yml file (see below for an example).

The output of this command should then be stored in a masked or protected CI/CD variable with the name MLM_LICENSE_FILE.

Do not publish the license information

The MLM_LICENSE_FILE must not be configured as a normal (plaintext) CI variable, or the value stored in an unprotected manner in any repository.

Configuring .gitlab-ci.yml

The YAML configuration for a MATLAB job would then look something like this:

  image: mathworks/matlab:r2021b
    - cit
    - matlab -batch test

For more information on the MATLAB docker images, see here.

Multi-project pipelines

GitLab CI allows specifying triggers in one project that will launch a CI/CD pipeline in a downstream project. For example:

  stage: test
  script: make check

  stage: deploy
  trigger: my/otherproject

In this example, after the test job succeeds in the test stage, the downstream job starts. GitLab then creates a downstream pipeline in the my/otherproject project.

This is used in Computing and Software to rebuild downstream Docker containers if the base container is rebuilt, see here.

See Multi-project pipelines in the official GitLab Docs for full details.