GitLab CI/CD Pipelines
GitLab CI/CD is defined in .gitlab-ci.yml at the root of the repository. It is one of the most feature-complete CI/CD systems available, with DAG pipelines, environments, review apps, and artifact management built in.
.gitlab-ci.yml Anatomy
stages:
- build
- test
- deploy
variables:
NODE_ENV: production
default:
image: node:20
before_script:
- npm ci
build:
stage: build
script:
- npm run build
artifacts:
paths:
- dist/
expire_in: 1 hour
test:
stage: test
script:
- npm test
coverage: '/Statements.*?([d.]+)%/'
deploy_staging:
stage: deploy
script:
- ./deploy.sh staging
environment:
name: staging
url: https://staging.example.com
only:
- mainJob Keywords
# Run on specific branches/tags
only:
- main
- /^release-.*/
# Modern alternative: rules (more flexible)
rules:
- if: '$CI_COMMIT_BRANCH == "main"'
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
when: manual
# Dependencies between jobs
needs: # DAG — run as soon as dependency is done (skip stage order)
- job: build
dependencies: # Download artifacts from specific jobs
- build
# Retry on failure
retry:
max: 2
when: runner_system_failure
# Timeout per job
timeout: 30 minutesPipeline Types
Branch pipelines: run on every push to a branch
Merge request pipelines: run when MR is created/updated (source: merge_request_event)
Merged results pipelines: test MR as if already merged with target branch
Merge trains: pipeline tests queued MRs sequentially before merging
Scheduled pipelines: cron-based, configured in CI/CD → Schedules
Triggered pipelines: via API, web hook, or another pipeline (trigger keyword)
Parent-child pipelines: trigger: include — split huge .gitlab-ci.yml across files
Runners
# GitLab-hosted runners: available on gitlab.com (SaaS), use tags to target
# Self-managed: install runner on your own infrastructure
# Register a runner
gitlab-runner register --url https://gitlab.com --token <token> --executor docker --docker-image alpine
# Runner tags — match runner to jobs
build_app:
tags:
- docker
- linuxArtifacts & Caching
# Artifacts: pass files between jobs or download after pipeline
artifacts:
paths:
- build/
reports:
junit: test-results.xml
coverage_report:
coverage_format: cobertura
path: coverage/cobertura-coverage.xml
expire_in: 7 days
# Cache: speed up jobs by reusing node_modules, pip packages, etc.
cache:
key:
files:
- package-lock.json
paths:
- node_modules/Environments & Review Apps
Environments track deployments — visible in Deployments → Environments
Review Apps: auto-create a temporary environment for every MR (dynamic environments)
Stop review app: define a stop job with action: stop and trigger on MR close
Protected environments: only specific roles can deploy to production
Deployment freezes: CI/CD → Deployment freezes — block deploys during maintenance windows
Predefined CI Variables
$CI_COMMIT_SHA # full commit SHA
$CI_COMMIT_SHORT_SHA # first 8 chars
$CI_COMMIT_BRANCH # branch name
$CI_COMMIT_TAG # tag name (if pipeline is for a tag)
$CI_PIPELINE_ID # unique pipeline ID
$CI_JOB_NAME # current job name
$CI_PROJECT_ID # project numeric ID
$CI_REGISTRY # GitLab container registry URL
$CI_REGISTRY_IMAGE # full image path
$CI_ENVIRONMENT_NAME # set when job has environment:Keep your own version of these notes — editable, searchable, and organised by your stack.
Start free