GitLab CI Basics
GitLab CI/CD is the automation engine built directly into GitLab, so a project's source code, issue tracker, and pipeline definitions all live in one place. Every pipeline is described declaratively in a YAML file named .gitlab-ci.yml that sits at the repository root. When GitLab detects a push, merge request, tag, schedule, or API trigger, it reads this file, resolves the pipeline into stages and jobs, and hands the work off to one or more GitLab Runners — the agent processes that actually execute the shell commands. Because the pipeline definition is versioned alongside the code, changes to the build process go through the same review and rollback mechanisms as any other code change.
Cricket analogy: Like a franchise keeping its playing strategy, squad list, and match rules all in one official team dossier instead of scattered notebooks — when selectors update the strategy document, it goes through the same team-management review as any other squad decision, and the support staff execute exactly what's written.
Stages and Jobs
A pipeline is composed of stages, and each stage contains one or more jobs. Stages run sequentially by default — build must finish before test starts, and test must finish before deploy starts — while jobs within the same stage run in parallel across available runners. Each job is a YAML key with a script array of shell commands plus optional keys like stage, image, rules, needs, and artifacts. If a project never defines a stages keyword, GitLab falls back to the implicit default of build, test, deploy.
Cricket analogy: Like a Test match's day running sequentially through sessions — morning finishes before lunch, lunch before the afternoon — while within one session the physio and analyst work in parallel; without a custom plan, a team just follows the standard three-session default.
stages:
- build
- test
- deploy
build-job:
stage: build
image: node:20-alpine
script:
- npm ci
- npm run build
artifacts:
paths:
- dist/
unit-tests:
stage: test
image: node:20-alpine
script:
- npm ci
- npm run test -- --ci
deploy-staging:
stage: deploy
image: alpine:3.19
script:
- echo "Deploying $CI_COMMIT_SHORT_SHA to staging"
- ./scripts/deploy.sh staging
environment:
name: staging
rules:
- if: '$CI_COMMIT_BRANCH == "main"'
Runners and Executors
A GitLab Runner is a lightweight process that polls GitLab (or receives dispatch over a persistent connection) for jobs it is eligible to run, then executes them using a chosen executor — Docker, Shell, Kubernetes, or VirtualBox among others. Runners can be shared across an entire GitLab instance, scoped to a group, or registered as project-specific. Tags on a runner (e.g. docker, gpu, linux-arm64) are matched against tags: declared on a job, giving teams fine-grained control over which infrastructure executes which work without changing the pipeline logic itself.
Cricket analogy: Like a substitute fielder waiting on the boundary ready to be called in for a specific role — some subs are certified only for fielding while others can bowl or keep wicket — and a captain tags which sub is eligible for which specific situation without rewriting the game plan.
Think of .gitlab-ci.yml as a recipe and the Runner as the kitchen: the recipe never changes based on which kitchen cooks it, but you can route specific dishes (jobs) to specific kitchens (runners) using tags.
A common early mistake is assuming jobs share a filesystem across stages. Each job runs in a fresh, isolated environment; anything produced in one job (like compiled output) must be explicitly passed forward using artifacts, or it disappears when the job's container is torn down.
Rules and Conditional Execution
The rules keyword controls whether a job runs, is skipped, or runs manually, based on conditions like the branch name, whether it's a merge request pipeline, or the value of a variable. rules superseded the older only/except syntax because it supports ordered evaluation and combinable conditions, letting one job serve multiple triggering scenarios cleanly — for example, running automatically on main but requiring a manual click for other branches.
Cricket analogy: Like a modern DRS protocol evaluating conditions in order — field decision, evidence quality, reviews remaining — replacing an older, blunter rule that just said reviews allowed or not, letting one system handle both a caught-behind and an lbw appeal.
- Pipelines are defined in
.gitlab-ci.ymland are read on every trigger (push, MR, tag, schedule, API). - Stages run sequentially; jobs within a stage run in parallel by default.
- Runners execute jobs using an executor (Docker, Shell, Kubernetes, etc.) and can be filtered with tags.
- Each job runs in an isolated environment — use
artifactsto pass files between stages. rulesis the modern, flexible way to control conditional job execution, replacingonly/except.- The default implicit stages are
build,test, anddeployifstagesis not declared.
Practice what you learned
1. Where is a GitLab CI/CD pipeline defined by default?
2. By default, how do jobs within the same stage execute?
3. What component actually executes the shell commands defined in a job's `script`?
4. How do you pass a compiled output file from a `build` job to a later `deploy` job?
5. What is the primary advantage of `rules` over the legacy `only`/`except` keywords?
Was this page helpful?
You May Also Like
CircleCI Fundamentals
Core concepts of CircleCI — the config.yml structure, orbs, workflows, and executors — for teams evaluating or already using the platform.
Azure Pipelines Overview
How Azure Pipelines organizes CI/CD around YAML pipelines, agent pools, and stages, and where it fits within the broader Azure DevOps suite.
The CI/CD Tooling Landscape
A survey of the major CI/CD platforms — GitHub Actions, GitLab CI, Jenkins, CircleCI, and Azure Pipelines — and how their hosting model, configuration approach, and ecosystem differ.
Anatomy of a CI/CD Pipeline
A CI/CD pipeline is a series of automated stages — source, build, test, package, deploy — that a code change flows through, each acting as a quality gate before the next.
Related Reading
Related Study Notes in DevOps
Browse all study notesNginx Study Notes
DevOps · 30 topics
DevOpsAnsible Study Notes
DevOps · 30 topics
DevOpsAdvanced Kubernetes Study Notes
Kubernetes · 30 topics
DevOpsAdvanced Bash Scripting Study Notes
Bash · 30 topics
DevOpsApache Kafka Study Notes
Kafka · 30 topics
DevOpsDocker & Kubernetes Study Notes
YAML · 40 topics