Basic Structure of .gitlab-ci.yml
YAML
# .gitlab-ci.yml
stages:
- test
- build
- deploy
variables:
NODE_VERSION: "20"
IMAGE_NAME: $CI_REGISTRY_IMAGE
# Job definitions
lint:
stage: test
image: node:20-alpine
script:
- npm ci
- npm run lint
test:
stage: test
image: node:20-alpine
script:
- npm ci
- npm test
coverage: '/Liness*:s*(d+.d+)%/'
artifacts:
reports:
coverage_report:
coverage_format: cobertura
path: coverage/cobertura-coverage.xmlStage and Job Flow
YAML
stages:
- test # run in parallel
- build # after test completes
- staging # after build completes
- production # after manual approval
build-image:
stage: build
image: docker:24
services:
- docker:24-dind
script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker build -t $IMAGE_NAME:$CI_COMMIT_SHORT_SHA .
- docker push $IMAGE_NAME:$CI_COMMIT_SHORT_SHA
only:
- main
- developEnvironment-Specific Deployment
YAML
deploy-staging:
stage: staging
environment:
name: staging
url: https://staging.example.com
script:
- kubectl set image deployment/myapp myapp=$IMAGE_NAME:$CI_COMMIT_SHORT_SHA
only:
- develop
deploy-production:
stage: production
environment:
name: production
url: https://example.com
script:
- kubectl set image deployment/myapp myapp=$IMAGE_NAME:$CI_COMMIT_TAG
when: manual # requires manual approval
only:
- tagsCache and Artifacts
YAML
# Cache — reused across jobs (e.g. node_modules)
cache:
key: $CI_COMMIT_REF_SLUG
paths:
- node_modules/
- .npm/
# Artifacts — pass files between jobs + available for download
build:
script:
- npm run build
artifacts:
paths:
- dist/
expire_in: 1 week # retention period
# Using artifacts
deploy:
dependencies:
- build
script:
- ls dist/ # artifacts from the build job are availableConditional Execution — rules
YAML
test:
script: npm test
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
- if: '$CI_COMMIT_BRANCH == "main"'
- if: '$CI_COMMIT_TAG'
when: never # do not run on tags
# Run only when files change
backend-test:
script: npm test
rules:
- changes:
- src/**/*
- package.jsonRegistering a GitLab Runner
Bash
# Install Runner (Ubuntu)
curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh | sudo bash
sudo apt install -y gitlab-runner
# GitLab project → Settings → CI/CD → Runners — copy the token
sudo gitlab-runner register --url https://gitlab.com --registration-token YOUR_TOKEN --executor docker --docker-image alpine:latest --description "my-runner"
# Check status
sudo gitlab-runner status
sudo gitlab-runner listKey Built-in Environment Variables
| Variable | Value |
|---|---|
$CI_COMMIT_SHA | Full commit hash |
$CI_COMMIT_SHORT_SHA | Short commit hash |
$CI_COMMIT_BRANCH | Branch name |
$CI_COMMIT_TAG | Tag name |
$CI_REGISTRY_IMAGE | Project container registry |
$CI_ENVIRONMENT_NAME | Deployment environment name |
$CI_PIPELINE_SOURCE | Trigger source (push, schedule, etc.) |
Editorial note
AI tools may assist drafting. Check the evidence in each guide for whether commands were run and which environment was used. Confirm the current docs for your version before applying instructions, and email us about errors. email us
Topic-related official docs (auto-linked · not per-claim sources)Docker documentation ↗Git documentation ↗
Questions & answers
Ask a question about this guide. We'll review and reply.