GitLab CI — Cheat Sheet

Tags: gitlab-ci, devops, cicd, docker, pipelines, yaml

Level: intermediate

TL;DR: Configuration via .gitlab-ci.yml defining stages, jobs, and runner execution rules. Key focus on caching, artifacts, and multi-stage pipeline orchestration.

Key concepts

Configuration is declared declaratively in a root .gitlab-ci.yml file.

Pipelines consist of sequential stages containing independent, parallel jobs.

GitLab Runner executes jobs using executors like Docker, Shell, or Kubernetes.

cache persists dependencies across pipelines to speed up recurring execution.

artifacts pass build outputs between consecutive stages within a single pipeline.

rules determines conditional job execution based on branch, variables, or changes.

needs creates a Directed Acyclic Graph (DAG) skipping stage ordering.

Masked and protected CI/CD variables protect secrets and production credentials.

include modularizes configurations across files, templates, or remote repositories.

Environments enable deployments tracking, rollbacks, and dynamic review apps.

Typical questions and ready answers

Q: What is the fundamental difference between cache and artifacts in GitLab CI?R: Artifacts transfer generated outputs across stages in the same pipeline. Cache speeds up future runs by reusing unchanged dependencies across distinct pipelines.

Q: How do you speed up a large pipeline with long sequential stages?R: I use the needs keyword to establish a DAG, allowing independent jobs to run immediately without waiting for entire stages to finish.

Q: How do you secure deployment keys or access tokens in CI/CD?R: I store them as masked, protected variables in the project settings and restrict deployment jobs strictly to protected branches or manual approvals.

Q: What happens if a job fails in a stage?R: The pipeline halts and subsequent stages are skipped, unless subsequent jobs define when: always or the failing job has allow_failure: true.

Q: How do you handle database migrations safely within a pipeline?R: I define a dedicated pre-deployment job with manual trigger or controlled execution, verifying idempotency and capturing logs as artifacts.

Pitfalls and common mistakes

Confusing cache with artifacts and losing build outputs across stages.

Using only/except syntax instead of the modern and flexible rules clause.

Omitting predefined variable checks, causing jobs to trigger on unrelated branch pushes.

Storing unmasked secrets directly in YAML files instead of CI/CD settings.

Missing cache keys, leading to cache collisions across different branches.

Defining heavyweight Docker images with unneeded packages, slowing runner pull times.

Snippets and commandsYAML

```stages:

  • build
  • test
  • deploy

default:

image: node:20-alpine

cache:

key:

files:

  • package-lock.json

paths:

  • .npm/

build_job:

stage: build

script:

  • npm ci --cache .npm --prefer-offline
  • npm run build

artifacts:

paths:

  • dist/

expire_in: 1 day

test_job:

stage: test

needs: ["build_job"]

script:

  • npm test

deploy_prod:

stage: deploy

script:

  • ./deploy.sh

rules:

  • if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

when: manual

environment:

name: production

url: https://example.com

```

To review

[ ] DAG execution via needs versus standard stage sequencing

[ ] Proper usage of rules:changes with merge request pipelines

[ ] Differences between Docker-in-Docker (dind) and Kaniko for container builds

[ ] Optimization of cache hit rates across feature branches

References

GitLab CI/CD Pipeline Configuration Reference

GitLab Runner Executors Documentation

Jarvis Interviews
Jarvis