My mental model for gitlab-ci
Wednesday Mar 31, 2021 | Series Mental ModelsMental models always help me remember how different things work. While they’re just approximations of a (black box) system, they generally describe some internal workings on an abstract level to explain observed behaviour.
After having run into issues with gitlab-ci and spending quite some time trying to debug them I’ve developed the following mental model to help me with future issues.
Disclaimer: This model may or may not be accurate, as I have not looked at the gitlab internals to verify if it is actually implemented this way, but it has helped me come to conclusions and solutions a lot faster.
In short my mental model consists of 3 parts:
- Pipeline definition
- Pipeline instance
- Containers all the way down
Pipeline definition
Let’s start with the gitlab-ci.yml
file. This is the definition of your pipeline. It describes what an instance of the pipeline should or could do. This definition or configuration if you will, is tied to versioning just like any file in your git repository.
Pipeline instance
Triggering a pipeline creates an instance from the definition of the pipeline. This instance is tied to a specific version of your repository. Often this version is the just the last commit on a branch, like main. There are different ways to trigger a pipeline, simply through a commit, opening a merge request or by tagging a certain commit for example.
This ties the commit to the pipeline. This also means that if you change your pipeline you need to trigger a new instance because re-running the old instance will use the definition tied to the commit that triggered that old instance of the pipeline. In short you are still on the old version of your pipeline instead of the fix you just committed and pushed.
Containers all the way down… with some scripts
Lastly every part of your pipeline runs in a container. A common way to run these containers is on kubernetes. Which in itself means it has all the up- and downsides of running there. Running docker in docker will require a certain setup and configuration. If your kubernetes cluster is in flux a lot (e.g. nodes often get killed) you may experience unstable builds unrelated to your code changes. And so on.
To further simplify a gitlab pipeline. You could see every step in your pipeline as a bash script that is run in a container. It is up to you how complicated that script is and if the container that is used has all the tools it needs to execute that script.
Any addtional input is usually passed into the step through the git repo or artifacts (if it is the output of a previous step). Just like the contents of the git repo, the artifacts are tied to the pipeline instance.