Structure .gitlab-ci.yml
stages :
- build
- test
- deploy
variables :
NODE_VERSION : "20"
build :
stage : build
image : node:${NODE_VERSION}-alpine
script :
- npm ci
- npm run build
artifacts :
paths :
- dist/
expire_in : 1 hour
test :
stage : test
image : node:${NODE_VERSION}-alpine
script :
- npm ci
- npm test
coverage : '/Lines\s*:\s*(\d+\.\d+)%/'
deploy :
stage : deploy
script :
- ./deploy.sh
environment :
name : production
url : https://app.example.com
rules :
- if : $CI_COMMIT_BRANCH == "main"
Stages & Jobs
Dépendances entre jobs
stages :
- build
- test
- deploy
build-app :
stage : build
script : npm run build
unit-tests :
stage : test
needs : [ "build-app" ] # DAG — n'attend que build-app
script : npm run test:unit
integration-tests :
stage : test
needs : [ "build-app" ]
script : npm run test:integration
allow_failure : true # Ne bloque pas le pipeline
Jobs manuels
deploy-prod :
stage : deploy
script : ./deploy.sh prod
when : manual # Déclenché manuellement
allow_failure : false
Runners
Type Utilisation Shared Fournis par GitLab.com, partagés entre projets Specific Dédiés à un projet ou groupe Group Partagés au niveau d'un groupe GitLab
Sélection par tags
build :
tags :
- docker
- linux
script : make build
Enregistrer un runner
$ gitlab-runner register --url https://gitlab.com --token glrt-xxxx --executor docker --docker-image alpine:latest
Variables
Variables prédéfinies
Variable Description CI_COMMIT_BRANCHBranche du commit CI_COMMIT_SHASHA complet du commit CI_PIPELINE_IDID du pipeline CI_PROJECT_NAMENom du projet CI_MERGE_REQUEST_IIDIID de la merge request CI_REGISTRY_IMAGEURL de l'image du registre
Variables personnalisées
variables :
DEPLOY_ENV : "staging"
DB_HOST : "db.example.com"
job :
variables :
LOCAL_VAR : "valeur locale"
script :
- echo $DEPLOY_ENV
- echo $LOCAL_VAR
Variables protégées et masquées : configurer dans Settings > CI/CD > Variables .
Cache & Artifacts
Cache (réutilisé entre pipelines)
build :
cache :
key :
files :
- package-lock.json
paths :
- node_modules/
policy : pull-push # pull, push, ou pull-push
script :
- npm ci
- npm run build
Artifacts (transmis entre jobs)
build :
artifacts :
paths :
- dist/
- coverage/
expire_in : 1 week
reports :
junit : junit.xml
coverage_report :
coverage_format : cobertura
path : coverage/cobertura.xml
Rules & Conditions
deploy-staging :
script : ./deploy.sh staging
rules :
- if : $CI_COMMIT_BRANCH == "develop"
when : always
- if : $CI_MERGE_REQUEST_IID
when : manual
- when : never
tests :
script : npm test
rules :
- changes : # Seulement si ces fichiers changent
- src/**/*
- tests/**/*
- exists : # Seulement si ce fichier existe
- Dockerfile
Workflow rules (niveau pipeline)
workflow :
rules :
- if : $CI_PIPELINE_SOURCE == "merge_request_event"
- if : $CI_COMMIT_BRANCH == "main"
- if : $CI_COMMIT_TAG
Environnements
deploy-review :
stage : deploy
script : ./deploy-review.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.sh
environment :
name : review/$CI_COMMIT_REF_SLUG
action : stop
when : manual
Templates & Includes
Include
include :
- local : '.gitlab/ci/build.yml'
- project : 'group/shared-ci'
ref : main
file : '/templates/deploy.yml'
- remote : 'https://example.com/ci-template.yml'
- template : 'Security/SAST.gitlab-ci.yml'
Extends & Ancres YAML
.base-deploy :
image : alpine:latest
before_script :
- apk add --no-cache curl
script :
- ./deploy.sh $DEPLOY_ENV
deploy-staging :
extends : .base-deploy
variables :
DEPLOY_ENV : staging
environment :
name : staging
deploy-prod :
extends : .base-deploy
variables :
DEPLOY_ENV : production
environment :
name : production
when : manual
Registre de conteneurs
Build et push
build-image :
image : docker:24
services :
- docker:24-dind
variables :
DOCKER_TLS_CERTDIR : "/certs"
script :
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA .
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
Avec Kaniko (sans Docker-in-Docker)
build-image :
image :
name : gcr.io/kaniko-project/executor:v1.23.0-debug
entrypoint : [ "" ]
script :
- >-
/kaniko/executor
--context $CI_PROJECT_DIR
--dockerfile Dockerfile
--destination $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
Bonnes pratiques
Pratique Détail DRY Utiliser extends et include pour factoriser DAG Préférer needs à l'ordre séquentiel des stages Cache Clé basée sur le lockfile pour invalidation précise Rules Préférer rules à only/except (déprécié) Artifacts Toujours définir expire_in pour éviter le stockage infini Sécurité Activer SAST/DAST via les templates GitLab Variables Masquer et protéger les secrets dans les settings