This post provides some guidelines on how to set up a .gitlab-ci.yml definition file.
Tools
We assume that the reader already has some knowledge of the following tools:
- gitlab/ci interactions via
gitlab-runner gitlab-ci.ymlconcepts and syntaxgitlab.inria.frUI (CI initialization, pipelines, jobs, artifacts, gitlab-pages, etc.)pixiusage
Using the include/extend directives of gitlab-ci.yml
In order to simplify the .gitlab-ci.yml content and ease its debugging, we use the following techniques:
- Use
includein the.gitlab-ci.ymlfile: this allows you to share instructions between different git/gitlab projects or different jobs. You can think of these as “macros”. Example:
include:
- ".gitlab-ci/pages.yml"
- ".gitlab-ci/build_conda.yml"
- ".gitlab-ci/memcheck.yml"
These instructions will include the jobs/instructions from the files in the current git repository.
- Of course, you can also include files defined in another repository. The given repository should be accessible from the current repository, e.g., by being in the same group or being public:
include:
- project: 'dtk/dtk-ci'
file: 'pixi-common.yaml'
ref: main
This block will include all job definitions available in the file pixi-common.yaml from the git@gitlab.inria.fr:dtk/dtk-ci repository. All repositories in the dtk group will have access to this file.
- Use the
extenddirective: this allows you to use a job defined previously, potentially modifying it if necessary:
Example: let’s suppose that pixi-common.yaml contains the following definition:
.build_unix:
script:
- echo "=== Running on $HOSTNAME"
- mkdir build
- cd build
- pixi run cmake ..
- pixi run cmake --build . --config Release --parallel
- pixi run cmake --build . --config Release --parallel --target install
You can extend it this way:
include:
- project: 'dtk/dtk-ci'
file: 'pixi-common.yaml'
ref: main
build-unix:
extends: .build_unix
needs: []
parallel:
matrix:
- os_version: [osx-x86_64, osx-arm64, linux-x86_64, linux-aarch64]
tags:
- ${os_version}
For all 4 OS/architectures, the same commands will be used to build/install the software. And this will be the full content of your .gitlab-ci.yml file !!!
Remarks:
- By (our) convention, macro names start with
. - You can cascade
extends, but you cannot cascadescriptsin an extends chain (a workaround is to usebefore-script, but it also has its limits. See thepixi-common.yamlfile if you want an example).
Using pixi tasks
Defining pixi tasks in the pixi.toml provides several improvements:
- You can define dependencies between tasks (task
buildmust run before tasktest, taskinstallmust run beforebuild, etc.) - You (when developing) and gitlab-runner will use the same commands (e.g.,
pixi run build) - It will simplify the content of the
.gitlab-ci.ymlfile: onlypixi run somethinginstead of a list of commands - It may also simplify the README.md and documentation
Example:
[tasks]
configure = "cmake -G Ninja -S . -B build -DCMAKE_BUILD_TYPE=Release"
build = { cmd = "cmake --build ./build --target install", depends-on = ["configure"] }
The pixi version of .gitlab-ci.yml will contain:
script:
- pixi run build
In a “previous” conda version, the file would have been:
script:
- source /Users/ci/Miniconda3/etc/profile.d/conda.sh
- conda create -y -n $CI_PROJECT_NAME
- mamba env update -f pkg/env/$CI_PROJECT_NAME.yaml
- conda activate $CI_PROJECT_NAME
- mkdir build
- cd build
- cmake .. -DCMAKE_BUILD_TYPE=Release
- make