Skip to content

GitLab CI Cheat Sheet

Practical reference for writing .gitlab-ci.yml pipelines. Covers pipeline creation rules, job rules, stages, dependencies, variables, artifacts, caching, environments, and reusable configuration patterns.


File Location

.gitlab-ci.yml

Minimal Pipeline

stages: [lint, test, build, deploy]

lint:
  stage: lint
  image: alpine:3.19
  script:
    - echo "lint"

test:
  stage: test
  image: node:20
  script:
    - npm ci
    - npm test

Workflow Rules (Pipeline Creation)

workflow:
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
    - when: never

Job Rules

build:
  stage: build
  script:
    - make build
  rules:
    - if: $CI_COMMIT_TAG
    - if: $CI_COMMIT_BRANCH == "main"
    - when: never

rules:changes

docs:
  stage: test
  script:
    - mkdocs build -s
  rules:
    - changes:
        - docs/**/*
        - mkdocs.yml

Stages and DAG with needs

stages: [build, test, deploy]

build:
  stage: build
  script:
    - make build
  artifacts:
    paths:
      - dist/

test:
  stage: test
  needs: ["build"]
  script:
    - make test

deploy:
  stage: deploy
  needs: ["build", "test"]
  script:
    - ./deploy.sh

Images and Services

integration_tests:
  image: node:20
  services:
    - name: postgres:15
      alias: db
  variables:
    DATABASE_URL: "postgres://postgres:example@db:5432/postgres"
  script:
    - npm ci
    - npm run test:integration

Variables

variables:
  NODE_ENV: test

job_example:
  script:
    - echo $NODE_ENV
  variables:
    NODE_ENV: production

Common predefined variables:

  • CI_COMMIT_BRANCH
  • CI_COMMIT_TAG
  • CI_DEFAULT_BRANCH
  • CI_PIPELINE_SOURCE
  • CI_PROJECT_PATH

Artifacts

build:
  stage: build
  script:
    - npm run build
  artifacts:
    paths:
      - dist/
    expire_in: 7 days

JUnit Report

test:
  stage: test
  script:
    - pytest --junitxml=report.xml
  artifacts:
    reports:
      junit: report.xml

Cache

cache:
  key:
    files:
      - package-lock.json
  paths:
    - .npm/
    - node_modules/

Include External Files

include:
  - local: .gitlab/ci/common.yml
  - project: "my-group/ci-templates"
    file: "/templates/node.yml"
    ref: "v1.2.0"

Reuse with extends

.base:
  image: node:20
  before_script:
    - node --version

test:
  extends: .base
  stage: test
  script:
    - npm ci
    - npm test

Parallel Jobs

e2e:
  stage: test
  image: node:20
  parallel:
    matrix:
      - BROWSER: ["chromium", "firefox"]
        SHARD: ["1/2", "2/2"]
  script:
    - echo "Browser=$BROWSER Shard=$SHARD"

Environments

deploy_prod:
  stage: deploy
  script:
    - ./deploy.sh
  environment:
    name: production
    url: https://example.com
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

Manual deployment:

deploy_staging:
  stage: deploy
  script:
    - ./deploy-staging.sh
  environment:
    name: staging
  when: manual

Concurrency

deploy_prod:
  stage: deploy
  resource_group: production
  script:
    - ./deploy.sh
test:
  stage: test
  interruptible: true
  script:
    - npm test

Child Pipelines

trigger_backend:
  stage: test
  trigger:
    include: backend/.gitlab-ci.yml
    strategy: depend
  rules:
    - changes:
        - backend/**/*

Retry and Allow Failure

flaky_job:
  stage: test
  script:
    - ./sometimes-fails.sh
  retry: 2
  allow_failure: true