5 min to read
GitLab CI/CD Pipeline Configuration Guide
Understanding GitLab CI/CD workflow and .gitlab-ci.yml configuration

Overview
Let’s explore GitLab CI/CD workflow and learn how to write .gitlab-ci.yml
files for automated pipelines. For GitLab and GitLab Runner installation, please refer to our previous posts:
What is GitLab CI/CD?
GitLab CI/CD (Continuous Integration/Continuous Deployment) is a built-in feature that automates the process of building, testing, and deploying applications.
It helps ensure code quality and stability by running tests and validations for every code change, minimizing human error and improving development efficiency.
How GitLab CI/CD Works
Core Components:
-
Configuration
Uses `.gitlab-ci.yml` file in repository root to define jobs, stages, and rules. -
Pipeline
Triggered by commits or merge requests, follows stages defined in configuration, and can be manual or scheduled. -
Jobs
Individual tasks within pipelines that run in containers or runners to build, test, or deploy actions. -
Stages
Pipeline phases (e.g., build, test, deploy). Jobs in the same stage run in parallel, and stages run sequentially. -
Runners
Agents that execute jobs. They can run on various platforms and be shared or specific to projects. -
Artifacts & Caching
Store build outputs, share between jobs, and cache dependencies for efficient execution.
GitLab Predefined Variables
Common predefined variables used in pipelines:
CI_COMMIT_REF_NAME # Branch name being built
CI_COMMIT_SHORT_SHA # First 8 characters of commit SHA
CI_REGISTRY # GitLab Container Registry address
CI_PROJECT_DIR # Full path where repository is cloned
CI_REGISTRY_USER # GitLab registry user
CI_REGISTRY_PASSWORD # GitLab registry password
Pipeline Examples
1. Basic Pipeline
stages:
- build
- test
- deploy
image: alpine
build_a:
stage: build
script:
- echo "This job builds something."
test_a:
stage: test
script:
- echo "This job tests something."
deploy_a:
stage: deploy
script:
- echo "This job deploys something."
environment: production
2. DAG (Directed Acyclic Graph) Pipeline
stages:
- build
- test
- deploy
build_a:
stage: build
script:
- echo "Building component A"
test_a:
stage: test
needs: [build_a]
script:
- echo "Testing component A"
deploy_a:
stage: deploy
needs: [test_a]
script:
- echo "Deploying component A"
3. Parent-Child Pipeline
# Root .gitlab-ci.yml
stages:
- triggers
trigger_a:
stage: triggers
trigger:
include: a/.gitlab-ci.yml
rules:
- changes:
- a/*
# a/.gitlab-ci.yml
stages:
- build
- deploy
build_a:
stage: build
script:
- echo "Building service A"
deploy_a:
stage: deploy
script:
- echo "Deploying service A"
Practical Example
Here’s a real-world example with build and deploy stages:
stages:
- build
- deploy
variables:
BRANCH:
value: "dev1"
description: "Select branch: dev1 or dev2"
NAMESPACE:
value: "dev1"
description: "Select namespace: dev1 or dev2"
SERVICE:
value: "game"
description: "Select service type"
CI_REGISTRY_IMAGE: $CI_REGISTRY/$SERVICE
BUILD_TAG: $BRANCH-$CI_COMMIT_SHORT_SHA
IMAGE_URL: '${CI_REGISTRY_IMAGE}:${BUILD_TAG}'
.build_image: &build_image
stage: build
image:
name: gcr.io/kaniko-project/executor:debug
entrypoint: [""]
script:
- /kaniko/executor
--context $CI_PROJECT_DIR
--dockerfile $CI_PROJECT_DIR/$SERVICE.Dockerfile
--destination $IMAGE_URL
--build-arg NODE_ENV=$BRANCH
.deploy_job: &deploy_job
stage: deploy
image: dtzar/helm-kubectl
script:
- kubectl set image deployment $SERVICE-$NAMESPACE
app=$IMAGE_URL -n $NAMESPACE
build_image:
<<: *build_image
rules:
- if: '($CI_PIPELINE_SOURCE == "web")'
- if: '($CI_PIPELINE_SOURCE == "trigger")'
tags:
- build-runner
deploy_job:
<<: *deploy_job
rules:
- if: '($CI_PIPELINE_SOURCE == "web")'
- if: '($CI_PIPELINE_SOURCE == "trigger")'
tags:
- deploy-runner
Advanced Pipeline Features
1. Change-Based Triggers
.change_files: &change_files
changes:
- apps/**/*
- config/*
- libs/**/*
- *.Dockerfile
- .gitlab-ci.yml
build_image:
rules:
- if: '($CI_PIPELINE_SOURCE == "push")'
<<: *change_files
2. Cross-Project Triggers
build_job:
after_script:
- curl -X POST
-F token=${TRIGGER_TOKEN}
-F ref=${CI_COMMIT_REF_NAME}
-F variables[project_id]=${CI_PROJECT_ID}
http://gitlab.example.com/api/v4/projects/100/trigger/pipeline
Comments