GitLab is more than a git repository. It comes with the powerful CI/CD runner that you can use for free, or even self host. In this post we are going to get familiar with it, and setup the most basic pipeline.
In order to add GitLab CI/CD to you project, all you need to do is to add
.gitlab-ci.yml file to the root of your project. This file contains all the pipeline configuration and tasks. Once you add this file to your repository, and push it upstream, GitLab will detect the configuration, and it will execute it.
The GitLab script is, in general, comprised of two sections: stages, and jobs. A collection of jobs composes a pipeline. Stages define stages of the pipeline.
We will use a simple Python program to show how to build a pipeline. First make a git project:
mkdir example-project cd example-project git init touch add.py test_add.py .gitlab-ci.yml python3 -m venv env . env/bin/activate pip install flake8 pip freeze > requirements.txt
And write some Python code:
# add.py def add(*args): return sum(args) # test_add.py import unittest from add import add class AddTestCase(unittest.TestCase): def test_add_two(self): self.assertEqual(add(1, 2), 3) def test_add_positive_and_negative(self): self.assertEqual(add(-1, 1), 0) def test_add_many(self): self.assertEqual(add(1, 2, 3), 6)
Now we have enough elements to build a pipeline with several stages. We have flake8 to lint our program, unit tests to test our function, and let’s say that we were asked to tar this script and consider that a build.
.gitlab-ci.yml and define pipeline stages:
stages: - lint - test - build
The basic anatomy of a job is the following:
title: # a title of the job - any string you want stage: test # stage must correspond to one of the predefined stages image: python:latest # docker image to be used for this job before_script: # preparations you need to make before doing the actual job - ... script: # the actual steps of the job - ... after_script: # if you need to do some cleanups - ... artifacts: # persist files from the pipeline paths: - dir
Before we start writing our first job, we have to identify that there are some common elements between them. Namely, we have to install dependencies with pip. Luckily, we can write
before_script as a global config, and it will be executed before each job in the
before_script: - pip install -r requirements.txt
Now, let’s write our first job:
lint: stage: lint image: python:latest script: - flake8 .
It’s very simple! The GitLab runner will pull the latest Python Docker image from the Docker Hub, and execute contents of
script in it. We will write other jobs in a similar fashion:
test: stage: test image: python:latest script: - python -m unittest test_add build: stage: build image: alpine:latest before_script: - mkdir dist script: - tar cvzf dist/add.tar add.py artifacts: paths: - dist
Notice that in the build job we have overridden global
before_script with a new script that is specific to the task. Moreover, we have saved the tar as a pipeline artifact so we can use it later.
Commit your changes and push this repo to your GitLab account. Go to the CI/CD tab of your project, and watch your pipeline passing. This is essentially it, a basic example that shows you how to start working with GitLab CI today!