Gitlab CI/CD

Gitlab CI/CD

Here at H&E Inventions we have our own instance of GitLab and we rely a lot on Gitlab CI, we have runners on multiple platforms to cover

GitLab CI is a very powerful system for continuous integration. It has a lot of different features, and with every new release, new features and extensions are released.

What is Continuous Integration

Continuous Integration is a development practice which has submitted code tested against a number of processes, allowing teams to detect problems early. By integrating regularly, you can detect errors quickly, and locate them more easily.

These could include

  • Test code against standards and/or conventions
  • Run any/all project tests
  • Track changes in code test coverage
  • Track changes in code quality/complexity
  • Test new/changes features/code in conjunction with all the code base
  • Test new/changes features/code in a live environment

Because you’re integrating so frequently, there is significantly less back-tracking to discover where things went wrong, so you can spend more time building features.

Continuous Integration is cheap. Not integrating continuously is expensive. If you don’t follow a continuous approach, you’ll have longer periods between integrations. This makes it exponentially more difficult to find and fix problems. Such integration problems can easily knock a project off-schedule, or cause it to fail altogether.

Continuous Integration brings multiple benefits to your organization:

  • Increase visibility enabling greater communication
  • Catch issues early and nip them in the bud
  • Spend less time debugging and more time adding features
  • Build a solid foundation
  • Stop waiting to find out if your code’s going to work
  • Reduce integration problems allowing you to deliver software more rapidly


Every time a developer changes some code they save their changes to a branch. They can then push that branch to GitLab, so other developers can review the code before being merged.

If the repository contains a configuration file .gitlab-ci.yml which sets out a number of stages and jobs. These jobs are executed by a runner. A runner is basically a script running on a machine (a dedicated server or a local PC, Mac, Raspberry Pi) that executes instructions listed in the .gitlab-ci.yml file, and reports the result back to GitLab itself, which will show in it’s graphical interface.

When a developer has finished implementing a new feature or a bugfix, they can open a merge request, where other members of the team can comment on the code and on the implementation.


Every commit that is pushed to GitLab generates a pipeline attached to that commit. If multiple commits are pushed together the pipeline will be created for the last one only. A pipeline is a collection of jobs split in different stages.

All the jobs in the same stage run concurrently (if there are enough runners) and the next stage begins only if all the jobs from the previous stage have finished with success.

As soon as a job fails, the entire pipeline fails (with exception if a job is marked as manual, then a failure will not make the pipeline fail).

The stages are just a logical division between batches of jobs, where it doesn’t make sense to execute the next job if the previous failed. We can have a build stage, where all the jobs to build the application are executed, and a deploy stage, where the build application is deployed.


A job is a collection of instructions that a runner has to execute. You can see in real time what the output of the job is, so developers can understand why a job fails.

A job can be automatic, so it starts automatically when a commit is pushed, or manual. A manual job has to be triggered by someone manually. This can be useful, for example, to automate a deploy, but still to deploy only when someone manually approves it. There is a way to limit who can run a job.

A job can also build artifacts that users can download, like it creates an test coverage report or a .ipa file you can upload to the app store.

Other than creating artifacts, a job can be running a series of tests, deploying an to a test or live environment.

Job status are the same as stages status and stages inherit their status from the jobs within that stage.


A job can deploy something to an external server, this could be released to a test server or a tool like for testing, deployed to a live server or the app store.


This was a small introduction to some of the features of GitLab CI, it’s incredibly powerful, and using it in the right way allows all the team to use just one tool to go from planning to deploying.

In H&E Inventions we use it not only for running tests, but also for having automatic versioning of the software and automatic deploys to testing environments. We have automated other jobs as well (building modules/containers and uploading them Docker Registry/PyPi/Nexus ect)