Skip to main content
Technology & EngineeringCicd Services186 lines

Gitlab CI

Build and maintain GitLab CI/CD pipelines with stages, artifacts, environments,

Quick Summary26 lines
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 lines
Paste into your CLAUDE.md or agent config

GitLab 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/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

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 include templates
  • Automating release workflows triggered by semantic version tags

Install this skill directly: skilldb add cicd-services-skills

Get CLI access →