Le déploiement en production doit être un acte délibéré, validé et traçable — pas un effet de bord d’un git push. GitLab propose quatre mécanismes de contrôle : branches protégées, tags protégés, environnements protégés et deployment freezes. Ce guide vous montre comment configurer chaque couche pour que seules les bonnes personnes puissent déployer le bon code au bon moment.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »À la fin de ce guide, vous saurez :
- Protéger une branche pour contrôler qui peut push et merge
- Protéger les tags pour sécuriser les releases
- Créer un environnement protégé avec approbation obligatoire
- Configurer un deployment freeze pour bloquer les déploiements planifiés
- Appliquer des push rules pour renforcer les conventions
Dans quel contexte ?
Section intitulée « Dans quel contexte ? »Les mécanismes de protection de branches et d’environnements sont nécessaires dès que :
- Votre pipeline déploie automatiquement vers un environnement (staging, production)
- Plusieurs développeurs contribuent au même projet et les MR ne sont pas systématiquement revues
- Vous devez prouver à un auditeur que le déploiement en production suit un processus de validation
- Des périodes de gel de déploiement (release freeze, vacances, événements commerciaux) doivent être respectées
- Vous publiez des releases via des tags et devez empêcher la création de tags par n’importe qui
Branches protégées
Section intitulée « Branches protégées »Le problème par défaut
Section intitulée « Le problème par défaut »Sur un projet GitLab, un Maintainer peut pousser directement sur main sans passer par une MR. Un Developer peut merger une MR sans approbation. Il n’y a aucune barrière entre le code écrit et le code déployé.
Configurer une branche protégée
Section intitulée « Configurer une branche protégée »-
Accéder aux paramètres
Settings → Repository → Protected branches.
-
Protéger
mainParamètre Valeur recommandée Justification Branch mainBranche de production Allowed to merge Maintainers Seuls les maintainers mergent vers main Allowed to push and merge No one Personne ne push directement Allowed to force push Non Un force push réécrit l’historique -
Vérifier la protection
Fenêtre de terminal # Via l'API GitLabcurl --header "PRIVATE-TOKEN: $GITLAB_TOKEN" \"$GITLAB_URL/api/v4/projects/$PROJECT_ID/protected_branches"Résultat attendu :
[{"name": "main","push_access_levels": [{"access_level": 0}],"merge_access_levels": [{"access_level": 40}],"allow_force_push": false}]access_level: 0= No one,40= Maintainers.
Protéger par pattern
Section intitulée « Protéger par pattern »Vous pouvez protéger plusieurs branches avec un wildcard :
# Protéger toutes les branches release/*curl --request POST \ --header "PRIVATE-TOKEN: $GITLAB_TOKEN" \ "$GITLAB_URL/api/v4/projects/$PROJECT_ID/protected_branches" \ --data "name=release/*&push_access_level=0&merge_access_level=40"Patterns courants :
| Pattern | Usage |
|---|---|
main | Branche de production |
release/* | Branches de release |
hotfix/* | Correctifs urgents |
*-stable | Branches LTS |
Via l’API : automatiser la protection
Section intitulée « Via l’API : automatiser la protection »Pour appliquer la même politique sur tous les projets d’un groupe :
#!/usr/bin/env bash# protect-branches.sh — Appliquer la politique de branches sur un groupe
GROUP_ID="${1:?Usage: $0 <group_id>}"
# Récupérer tous les projets du groupeproject_ids=$(curl -s --header "PRIVATE-TOKEN: $GITLAB_TOKEN" \ "$GITLAB_URL/api/v4/groups/$GROUP_ID/projects?per_page=100" \ | jq -r '.[].id')
for pid in $project_ids; do echo "Protection de main pour le projet $pid" curl -s --request POST \ --header "PRIVATE-TOKEN: $GITLAB_TOKEN" \ "$GITLAB_URL/api/v4/projects/$pid/protected_branches" \ --data "name=main&push_access_level=0&merge_access_level=40&allow_force_push=false" \ | jq '{name, push_access_levels, merge_access_levels}'doneTags protégés
Section intitulée « Tags protégés »Pourquoi protéger les tags
Section intitulée « Pourquoi protéger les tags »Un tag déclenche souvent un pipeline de release. Si n’importe quel Developer peut créer un tag v2.0.0, il peut déclencher un build et un déploiement non autorisé.
Configurer des tags protégés
Section intitulée « Configurer des tags protégés »-
Accéder aux paramètres
Settings → Repository → Protected tags.
-
Protéger le pattern de tags
Paramètre Valeur recommandée Tag pattern v*Allowed to create Maintainers -
Vérifier via l’API
Fenêtre de terminal curl --header "PRIVATE-TOKEN: $GITLAB_TOKEN" \"$GITLAB_URL/api/v4/projects/$PROJECT_ID/protected_tags"Résultat attendu :
[{"name": "v*","create_access_levels": [{"access_level": 40}]}]
Environnements protégés
Section intitulée « Environnements protégés »Le mécanisme
Section intitulée « Le mécanisme »Un environnement protégé requiert une approbation explicite avant que le déploiement ne s’exécute. Le pipeline atteint le job de déploiement, puis se met en pause jusqu’à ce qu’un approbateur valide.
Configurer un environnement protégé
Section intitulée « Configurer un environnement protégé »-
Déclarer l’environnement dans le pipeline
.gitlab-ci.yml deploy-production:stage: deployscript:- kubectl apply -f manifests/environment:name: productionurl: https://app.example.comrules:- if: $CI_COMMIT_BRANCH == "main"resource_group: production -
Protéger l’environnement
Settings → CI/CD → Environments → production → Edit → Protected environment.
Paramètre Valeur recommandée Allowed to deploy Maintainers Required approvals 1 (minimum) Approvers Utilisateurs ou groupes spécifiques -
Vérifier le comportement
Poussez un commit sur
main. Le pipeline doit atteindre le jobdeploy-production, afficher le statut blocked et attendre l’approbation dans l’interface.
Approbation multi-niveaux
Section intitulée « Approbation multi-niveaux »Pour les environnements critiques, vous pouvez exiger plusieurs approbateurs et séparer les rôles :
# staging : déploiement automatique, pas d'approbation# pre-production : 1 approbation (lead technique)# production : 2 approbations (lead technique + SRE)Configurez via l’API :
# Mettre à jour les approbations requisescurl --request PUT \ --header "PRIVATE-TOKEN: $GITLAB_TOKEN" \ "$GITLAB_URL/api/v4/projects/$PROJECT_ID/protected_environments/production" \ --data "required_approval_count=2"Tier d’environnement
Section intitulée « Tier d’environnement »GitLab attribue un tier à chaque environnement qui détermine son ordre d’affichage et ses comportements par défaut :
| Tier | Environnements typiques | Auto-stop par défaut |
|---|---|---|
| production | production | Non |
| staging | staging, pre-prod | Non |
| testing | test, qa | Oui (24h) |
| development | dev, review/* | Oui (24h) |
| other | — | Oui (24h) |
deploy-staging: environment: name: staging deployment_tier: stagingDeployment freezes
Section intitulée « Deployment freezes »Le mécanisme
Section intitulée « Le mécanisme »Un deployment freeze bloque tous les déploiements vers un environnement pendant une période définie. Les pipelines continuent de s’exécuter, mais les jobs de déploiement sont bloqués.
Configurer un freeze
Section intitulée « Configurer un freeze »-
Via l’interface
Settings → CI/CD → Deploy freezes → Add deploy freeze.
Paramètre Exemple Freeze start 0 18 * * 5(vendredi 18h)Freeze end 0 9 * * 1(lundi 9h)Timezone Europe/Paris -
Via l’API
Fenêtre de terminal curl --request POST \--header "PRIVATE-TOKEN: $GITLAB_TOKEN" \"$GITLAB_URL/api/v4/projects/$PROJECT_ID/freeze_periods" \--data "freeze_start=0 18 * * 5&freeze_end=0 9 * * 1&cron_timezone=Europe/Paris" -
Vérifier les périodes actives
Fenêtre de terminal curl --header "PRIVATE-TOKEN: $GITLAB_TOKEN" \"$GITLAB_URL/api/v4/projects/$PROJECT_ID/freeze_periods"
Patterns de freeze courants
Section intitulée « Patterns de freeze courants »| Période | Cron start | Cron end | Usage |
|---|---|---|---|
| Week-end | 0 18 * * 5 | 0 9 * * 1 | Pas de déploiement le week-end |
| Nuit | 0 20 * * * | 0 7 * * * | Pas de déploiement la nuit |
| Black Friday | 0 0 25 11 * | 0 0 2 12 * | Gel e-commerce fin novembre |
| Fin de trimestre | 0 0 28 3,6,9,12 * | 0 0 2 4,7,10,1 * | Gel comptable |
Push rules
Section intitulée « Push rules »Compléter la protection des branches
Section intitulée « Compléter la protection des branches »Les push rules ajoutent des vérifications au moment du push, avant que le pipeline ne se déclenche :
Settings → Repository → Push rules.
| Règle | Valeur recommandée | Effet |
|---|---|---|
| Reject unsigned commits | ✅ | Exige des commits signés GPG |
| Commit message regex | ^(feat|fix|docs|chore|refactor|test)(\(.+\))?: .+ | Force Conventional Commits |
| Branch name regex | ^(main|release\/.*|feature\/.*|hotfix\/.*)$ | Limite les noms de branches |
| File name regex (deny) | \.(exe|dll|msi|pkg)$ | Bloque les binaires |
| Maximum file size (MB) | 10 | Empêche les gros fichiers |
Via l’API
Section intitulée « Via l’API »curl --request PUT \ --header "PRIVATE-TOKEN: $GITLAB_TOKEN" \ "$GITLAB_URL/api/v4/projects/$PROJECT_ID/push_rule" \ --data "reject_unsigned_commits=true" \ --data "commit_message_regex=^(feat|fix|docs|chore|refactor|test)(\(.%2B\))?: .%2B" \ --data "max_file_size=10"Checklist de protection
Section intitulée « Checklist de protection »| Contrôle | Commande de vérification | Attendu |
|---|---|---|
main protégée | curl .../protected_branches | push_access_levels: [{access_level: 0}] |
| Force push interdit | idem | allow_force_push: false |
Tags v* protégés | curl .../protected_tags | create_access_levels: [{access_level: 40}] |
| Env production protégé | UI → Environments | Badge “protected” visible |
| Approbation requise | UI → Environment settings | ≥ 1 required approval |
| Freeze week-end actif | curl .../freeze_periods | Période vendredi-lundi |
| Push rules actives | curl .../push_rule | Règles configurées |
Dépannage
Section intitulée « Dépannage »| Symptôme | Cause probable | Correction |
|---|---|---|
Developer peut push sur main | main non protégée | Settings → Repository → Protected branches → ajouter main |
| Pipeline deploy sans approbation | Environnement non protégé | Settings → CI/CD → Environments → Edit → cocher Protected |
| Variable protégée non injectée | Pipeline sur branche/tag non protégé | Vérifier que la branche ou le tag est dans la liste des éléments protégés |
Tag v1.0.0 créé par un Developer | Tags non protégés | Settings → Repository → Protected tags → ajouter v* |
| Deploy pendant un freeze | Job sans règle $CI_DEPLOY_FREEZE | Ajouter rules: - if: $CI_DEPLOY_FREEZE / when: never au job |
403 Forbidden sur l’API protected_branches | Token sans scope api | Recréer le token avec le scope api et le role Maintainer |
| Push rejeté : “commit not signed” | reject_unsigned_commits activé sans GPG configuré | Configurer GPG sur le poste développeur ou désactiver temporairement la règle |
À retenir
Section intitulée « À retenir »Le contrôle de déploiement dans GitLab repose sur quatre couches complémentaires :
- Branches protégées : le verrou de base. Personne ne push directement sur
main, seuls les Maintainers mergent. Sans ça, tout le reste est contournable. - Tags protégés : le contrôle des releases. Si vos pipelines de release se déclenchent sur tag, protégez le pattern
v*pour que seuls les Maintainers puissent taguer. - Environnements protégés : la porte de production. Le pipeline se met en pause, un humain valide, le déploiement continue. C’est la différence entre “ça s’est déployé” et “on a décidé de déployer”.
- Deployment freezes : le contrôle temporel. Les périodes sensibles (week-end, gel commercial, maintenance) sont protégées par configuration, pas par une convention orale.
- Push rules : la dernière ligne. Commits signés, conventions de nommage, taille de fichiers — ces vérifications bloquent les erreurs avant qu’elles n’atteignent le pipeline.
- Protected branches — GitLab Docs
- Protected tags — GitLab Docs
- Protected environments — GitLab Docs
- Deployment safety — Deployment freeze — GitLab Docs
- Push rules — GitLab Docs
- CI/CD variables — Protected variables — GitLab Docs
Testez vos connaissances
Section intitulée « Testez vos connaissances »Contrôle de connaissances
Validez vos connaissances avec ce quiz interactif
Informations
- Le chronomètre démarre au clic sur Démarrer
- Questions à choix multiples, vrai/faux et réponses courtes
- Vous pouvez naviguer entre les questions
- Les résultats détaillés sont affichés à la fin
Lance le quiz et démarre le chronomètre
Vérification
(0/0)Profil de compétences
Quoi faire maintenant
Ressources pour progresser
Des indices pour retenter votre chance ?
Nouveau quiz complet avec des questions aléatoires
Retravailler uniquement les questions ratées
Retour à la liste des certifications