Un pipeline GitLab CI mal structuré devient vite un goulot d’étranglement — 30 minutes pour voir si un commit passe, des dépendances inexplicables entre jobs, des caches qui ne fonctionnent que parfois. Voici comment construire un pipeline qui reste rapide et maintenable.
Structure de base : stages et jobs
# .gitlab-ci.yml
stages:
- test # validation (lint, tests unitaires)
- build # build de l'image Docker
- security # scanning de sécurité
- deploy-staging
- integration # tests end-to-end
- deploy-prod
variables:
DOCKER_DRIVER: overlay2
IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
Parallélisation : tester en parallèle
# Les jobs dans le même stage tournent en parallèle
test:unit:
stage: test
image: python:3.12-slim
script:
- pip install -r requirements-dev.txt
- pytest tests/unit/ -v --tb=short
test:lint:
stage: test
image: python:3.12-slim
script:
- pip install ruff black
- ruff check .
- black --check .
test:types:
stage: test
image: python:3.12-slim
script:
- pip install mypy
- mypy src/
Ces 3 jobs tournent en parallèle — le stage test prend le temps du plus lent, pas la somme.
Cache : accélérer les jobs répétitifs
# Cache partagé entre pipelines pour les dépendances
.python-cache: &python-cache
cache:
key:
files:
- requirements.txt # invalider si requirements change
paths:
- .cache/pip
policy: pull-push
test:unit:
<<: *python-cache
variables:
PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"
script:
- pip install -r requirements.txt
- pytest tests/unit/
Artefacts : passer des données entre stages
build:docker:
stage: build
script:
- docker build -t $IMAGE_TAG .
- docker push $IMAGE_TAG
- echo $IMAGE_TAG > image-tag.txt
artifacts:
paths:
- image-tag.txt
expire_in: 1 hour
deploy:staging:
stage: deploy-staging
dependencies:
- build:docker
script:
- IMAGE_TAG=$(cat image-tag.txt)
- kubectl set image deployment/api api=$IMAGE_TAG -n staging
Environnements et déploiements
deploy:staging:
stage: deploy-staging
environment:
name: staging
url: https://staging.sphinx-digital.com
script:
- ./scripts/deploy.sh staging $IMAGE_TAG
only:
- main
deploy:production:
stage: deploy-prod
environment:
name: production
url: https://sphinx-digital.com
action: start
script:
- ./scripts/deploy.sh production $IMAGE_TAG
when: manual # déploiement prod : bouton manuel
only:
- main
Rules : remplacer only/except
build:docker:
rules:
- if: '$CI_COMMIT_BRANCH == "main"'
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
- if: '$CI_COMMIT_TAG'
script:
- docker build -t $IMAGE_TAG .
# Job uniquement sur les tags de release
deploy:release:
rules:
- if: '$CI_COMMIT_TAG =~ /^v\d+\.\d+\.\d+$/'
script:
- ./scripts/release.sh $CI_COMMIT_TAG
Notre formation CI/CD couvre GitLab CI en profondeur avec des ateliers sur des projets réels.