gitlab-ci-best-practices
Use when optimizing GitLab CI/CD pipelines for performance, reliability, or maintainability. Covers pipeline optimization and organizational patterns.
Installation
Follow the repository instructions for this skill and your agent. Review the files and dependencies before adding it to your workflow.
View source ↗GuidesSkill instructions
GitLab CI - Best Practices
Optimize GitLab CI/CD pipelines for performance, reliability, and maintainability.
Pipeline Optimization
Use DAG with Needs
stages:
- build
- test
- deploy
build:frontend:
stage: build
script: npm run build:frontend
build:backend:
stage: build
script: npm run build:backend
test:frontend:
stage: test
needs: ["build:frontend"]
script: npm run test:frontend
test:backend:
stage: test
needs: ["build:backend"]
script: npm run test:backend
deploy:
stage: deploy
needs: ["test:frontend", "test:backend"]
script: ./deploy.sh
Parallel Execution
test:
parallel:
matrix:
- SUITE: [unit, integration, e2e]
script:
- npm run test:$SUITE
Interruptible Jobs
test:
interruptible: true
script:
- npm test
deploy:production:
interruptible: false # Never cancel
script:
- ./deploy.sh
Configuration Organization
Split Configuration Files
# .gitlab-ci.yml
include:
- local: .gitlab/ci/build.yml
- local: .gitlab/ci/test.yml
- local: .gitlab/ci/deploy.yml
stages:
- build
- test
- deploy
Reusable Templates
.node_template: &node_template
image: node:20-alpine
before_script:
- npm ci
cache:
key: ${CI_COMMIT_REF_SLUG}
paths:
- node_modules/
test:unit:
<<: *node_template
script:
- npm run test:unit
test:lint:
<<: *node_template
script:
- npm run lint
Extends Keyword
.base_job:
image: node:20-alpine
before_script:
- npm ci
test:
extends: .base_job
script:
- npm test
build:
extends: .base_job
script:
- npm run build
Resource Management
Resource Groups
deploy:staging:
resource_group: staging
script:
- ./deploy.sh staging
deploy:production:
resource_group: production
script:
- ./deploy.sh production
Runner Tags
heavy_build:
tags:
- high-memory
- docker
script:
- ./build.sh
Error Handling
Retry Configuration
test:flaky:
retry:
max: 2
when:
- runner_system_failure
- stuck_or_timeout_failure
- script_failure
Allow Failure
test:experimental:
allow_failure: true
script:
- npm run test:experimental
test:experimental:soft:
allow_failure:
exit_codes: [42] # Only allow specific exit code
Security Best Practices
Protected Pipelines
deploy:production:
rules:
- if: $CI_COMMIT_BRANCH == "main"
when: manual
environment:
name: production
Secure Variables
# Use protected and masked variables
deploy:
script:
- echo "$API_KEY" # Masked in logs
rules:
- if: $CI_COMMIT_REF_PROTECTED == "true"
Monitoring & Debugging
Job Logging
test:
script:
- set -x # Enable debug output
- npm test
after_script:
- echo "Job status: $CI_JOB_STATUS"
Pipeline Badges
[](https://gitlab.com/group/project/-/pipelines)
[](https://gitlab.com/group/project/-/pipelines)
Common Anti-Patterns
-
Avoid: Running all jobs in sequence Do: Use
needsfor parallel execution -
Avoid: Downloading all artifacts Do: Use
dependenciesto limit downloads -
Avoid: Rebuilding node_modules every job Do: Use cache with lock file keys
-
Avoid: Hardcoded secrets Do: Use CI/CD variables with protection
-
Avoid: Single monolithic
.gitlab-ci.ymlDo: Split into multiple included files
Examples
Read the usage examples in the source repository.
View source ↗Source history
- Indexed on
- 2026-01-20
- Index updated
- 2026-02-05
- Branch
- main
Index and sync dates describe this directory. View the source repository for code history.
GitHub ↗chat Comments (0)
Sign in to join the discussion and leave a comment.
No comments yet. Be the first to share your thoughts!