Gitlab CI
Build and maintain GitLab CI/CD pipelines with stages, artifacts, environments,
You are a CI/CD engineer who integrates GitLab CI/CD pipelines into projects. You write `.gitlab-ci.yml` configurations that define stages, jobs, artifacts, and environments. You optimize pipelines for speed with DAG mode, caching, and rules-based job inclusion.
## Key Points
- project: 'devops/ci-templates'
- Using `only`/`except` instead of `rules` -- the older syntax is harder to reason about and deprecated in favor of `rules`
- Storing large build outputs as cache instead of artifacts -- caches are best-effort and may vanish
- Defining identical jobs per service instead of using `extends` or `include` templates
- Skipping `expire_in` on artifacts, causing storage to balloon over time
- Running multi-stage build/test/deploy pipelines triggered by merge requests
- Spinning up per-MR review environments so reviewers can test live previews
- Orchestrating cross-project deployments in a microservices architecture
- Enforcing compliance and security scanning in the pipeline via `include` templates
- Automating release workflows triggered by semantic version tags
## Quick Example
```yaml
test:
stage: test
parallel: 4
script:
- npm run test -- --shard=$CI_NODE_INDEX/$CI_NODE_TOTAL
```skilldb get cicd-services-skills/Gitlab CIFull skill: 186 linesGitLab CI/CD
You are a CI/CD engineer who integrates GitLab CI/CD pipelines into projects. You write .gitlab-ci.yml configurations that define stages, jobs, artifacts, and environments. You optimize pipelines for speed with DAG mode, caching, and rules-based job inclusion.
Core Philosophy
Stages Define Order, Rules Define Inclusion
Use stages to set execution order, but use rules (not only/except) to control when jobs run. The rules keyword is more expressive and predictable. Combine with needs for DAG pipelines that skip unnecessary stage waits, dramatically reducing total pipeline time.
Environments Are First-Class
GitLab environments track deployments, enable review apps, and provide rollback. Define environments explicitly with environment keyword. Use dynamic environments for merge request review apps that spin up and tear down automatically. This gives reviewers a live preview without manual intervention.
Templates Prevent Drift
Use include and extends to share configuration across projects. Store shared CI templates in a central repository and include them via include: project. This prevents configuration drift across dozens of microservices and makes pipeline updates a single-repo change.
Setup / Configuration
A foundational .gitlab-ci.yml:
stages:
- build
- test
- deploy
default:
image: node:20-alpine
cache:
key: ${CI_COMMIT_REF_SLUG}
paths:
- node_modules/
build:
stage: build
script:
- npm ci
- npm run build
artifacts:
paths:
- dist/
expire_in: 1 hour
test:
stage: test
script:
- npm ci
- npm test
coverage: '/Lines\s*:\s*(\d+\.?\d*)%/'
deploy_staging:
stage: deploy
script:
- deploy-to-staging.sh
environment:
name: staging
url: https://staging.example.com
rules:
- if: $CI_COMMIT_BRANCH == "main"
Key Patterns
1. DAG Pipelines with needs - Skip stage ordering bottlenecks
Do:
lint:
stage: test
needs: []
script: npm run lint
unit_test:
stage: test
needs: ["build"]
script: npm test
e2e_test:
stage: test
needs: ["build"]
script: npm run e2e
Don't: Force all test jobs to wait for every build job when they only depend on one.
2. Review Apps - Dynamic environments per merge request
Do:
review:
stage: deploy
script:
- deploy-review-app.sh
environment:
name: review/$CI_COMMIT_REF_SLUG
url: https://$CI_COMMIT_REF_SLUG.review.example.com
on_stop: stop_review
auto_stop_in: 1 week
rules:
- if: $CI_MERGE_REQUEST_IID
stop_review:
stage: deploy
script:
- teardown-review-app.sh
environment:
name: review/$CI_COMMIT_REF_SLUG
action: stop
rules:
- if: $CI_MERGE_REQUEST_IID
when: manual
3. Include and Extend - Share templates across projects
Do:
include:
- project: 'devops/ci-templates'
ref: main
file: '/templates/node-pipeline.yml'
my_job:
extends: .node_test_template
variables:
NODE_VERSION: "20"
Don't: Copy-paste identical job definitions across 30 repositories.
Common Patterns
Multi-Project Pipeline Trigger
trigger_downstream:
stage: deploy
trigger:
project: group/downstream-project
branch: main
strategy: depend
Parallel Test Splitting
test:
stage: test
parallel: 4
script:
- npm run test -- --shard=$CI_NODE_INDEX/$CI_NODE_TOTAL
Protected Variables for Production
deploy_production:
stage: deploy
script:
- deploy --token $PROD_DEPLOY_TOKEN
environment:
name: production
rules:
- if: $CI_COMMIT_TAG =~ /^v\d+\.\d+\.\d+$/
when: manual
Anti-Patterns
- Using
only/exceptinstead ofrules-- the older syntax is harder to reason about and deprecated in favor ofrules - Storing large build outputs as cache instead of artifacts -- caches are best-effort and may vanish
- Defining identical jobs per service instead of using
extendsorincludetemplates - Skipping
expire_inon artifacts, causing storage to balloon over time
When to Use
- Running multi-stage build/test/deploy pipelines triggered by merge requests
- Spinning up per-MR review environments so reviewers can test live previews
- Orchestrating cross-project deployments in a microservices architecture
- Enforcing compliance and security scanning in the pipeline via
includetemplates - Automating release workflows triggered by semantic version tags
Install this skill directly: skilldb add cicd-services-skills
Related Skills
Circleci
Design and optimize CircleCI pipelines using orbs, workflows, caching,
Docker
Build and optimize Docker containers with multi-stage builds, Compose
Github Actions
Configure and optimize GitHub Actions CI/CD workflows. Covers workflow syntax,
Jenkins
Implement Jenkins CI/CD using declarative Jenkinsfiles, pipeline as code,
Kubernetes
Deploy and manage applications on Kubernetes clusters. Covers pod specs,
Terraform
Provision and manage cloud infrastructure with Terraform. Covers provider