1. Gitlab

1.2. Concepts

Top to bottom:

  • Pipelines

  • Stages

  • Jobs

1.2.1. Jobs

Warning
The above link doesn’t cover needs or dependencies in a job. See needs vs dependencies for a few explanations and further reading on the topic.

Smallest thing to run in the server. Even though it may not seem so if we think that each job can run N commands. However, this commands are bundled together in a "script" entry, like so:

some example job:
  script:
    - touch this
    - ./run/that.sh

The two commands are actually just one script.

1.2.2. Stages

Owns zero or more jobs, which will run in parallel (e.g. builds for different architectures).

Unless one overrides it, the defaults are:

stages:
  - build
  - test
  - deploy

One stage will only be executed if all the jobs from the previous one did not fail, or if are allowed to fail (marking the job with allow_failure: true).

1.2.3. Pipelines

They group stages and jobs. They are the top level component of the CI, and the whole definition of the pipeline is the .gitlab-ci.yml file.

1.3. How jobs depend on each other

Pipelines can exist in different forms, based on stages (simpler) or a bit more involved with the use of needs to buiild a Directed Acyclic Graph.

Contains a very simple example in which a text file is "built", tested and packaged, so it’s very similar to a C++ app workflow with a lot of simplicity. And it uses stages and needs. It is in the examples below.

1.4. How to share repetitive code

One job can "inherit" from another using extends. For example:

build-linux-special:
  extends: build-linux-normal
  # Set on the build environment. The build system has to make use of it.
  variables:
    APP_SPECIAL_BUILD: '1'

Alternatively, one can create a "hidden job" by starting it with a dot, then reuse it:

.common-boilerplate:
  image: this:that
  artifacts:
    paths:
      - appimage
    expire_in: 1 week
  script:
    - ./packaging.sh


package-linux-normal:
  extends: .common-boilerplate

package-linux-special:
  extends: .common-boilerplate
  after_script:
    - ./but-do-something-special.sh

1.5. Samples

The root keys are almost whatever you like and are typically the job definitions (which have only a few limitations in their name due to the keys meaning something special, like image).

build-job:
  stage: build
  script:
    - echo "Hello, $GITLAB_USER_LOGIN!"

test-job1:
  stage: test
  script:
    - echo "This job tests something"

This is a good example of a fairly complete

image: alpine

stages:
  - compile
  - test
  - package

compile:
  stage: compile
  before_script:
      - echo "Hello  " | tr -d "\n" > file1.txt
      - echo "world" > file2.txt
  script: cat file1.txt file2.txt > compiled.txt
  artifacts:
    paths:
    - compiled.txt
    expire_in: 20 minutes

test:
  stage: test
  script: cat compiled.txt | grep -q 'Hello world'

pack-gz:
  stage: package
  script: cat compiled.txt | gzip > packaged.gz
  needs: ["test"]
  artifacts:
    paths:
    - packaged.gz

pack-iso:
  stage: package
  before_script:
  - echo "ipv6" >> /etc/modules
  - apk update
  - apk add xorriso
  script:
  - mkisofs -o ./packaged.iso ./compiled.txt
  needs: ["test"]
  artifacts:
    paths:
    - packaged.iso