Maximize Page
Tech & DevOps HubEspace Tech & DevOps: Explorez le monde du Dev, du Cloud et des outils DevOps à travers nos articles et discussions Explore the world of development, the cloud and DevOps tools

Création automatique de merge requests et pipeline de promotion

Date de l'article:08-07-2026
CI/CD Gitlab automate
Dans cet article, je mets en place la standardisation des merge requests et l'automatisation de la promotion du code entre les branches. Nous fluidifions ainsi le workflow, tout en conservant des étapes de validation claires.
Combien de temps perd-on chaque semaine à configurer manuellement des Merge Requests (MR), à copier-coller des descriptions ou à relancer manuellement des pipelines pour promouvoir du code d'un environnement à un autre ? Pour éliminer ces frictions, nous allons structurer notre démarche autour de trois piliers DevOps:
Pilotez par les templates: Mettre en place un modèle de Merge Request obligatoire pour forcer la standardisation des descriptions, des checklists de test et des critères de validation.
Automatisez la promotion: Configuration pour automatiser le passage du code validé entre les branches stables à l'aide de triggers et de règles de CI/CD, sans intervention humaine manuelle.
Conservez le contrôle visuel: Structurer les approbations requises (Merge Request Approvals) pour que l'automatisation ne se fasse jamais au détriment de la sécurité et de la relecture.

Standardiser via le template de Merge Request
Avant de coder l'automatisation, il est indispensable de structurer ce que va contenir notre demande de fusion.
Dans GitLab, la fusion automatique (Auto-merge) permet de fusionner une demande de fusion (Merge Request ou "MR") dès que toutes les conditions et vérifications (pipelines, approbations, conflits) sont validées, éliminant ainsi le besoin d'une action manuelle finale. GitLab Docs: merge_requests/auto_merge

L'objectif n'est pas d'automatiser toutes les Merge Requests:
La première validation reste volontairement manuelle (feature → develop)
Tandis que les promotions entre environnements deviennent automatiques dès que le pipeline     à validé le code.
À chaque push, le comportement sera le suivant:
feature/*   → develop  (manuel, via MR)
develop     → staging  (MR automatique + auto-merge)
staging     → main     (MR automatique, fusion manuelle)
main        → rien
Procédons par étapes:
2. Préparer et faire fonctionner la création automatique des Merge Requests
3. Ajouter ensuite les vérifications, les conditions et l'auto-merge
Cela permettra de valider chaque étape, avant d'ajouter la suivante
Même si cela peut être sujet à changement, on détermine déjà ce que le script fera
push [develop]: Existe-t-il déjà une MR ?
                ├── oui
                │    → ne rien faire
                │    → afficher les infos de la MR existante
                └── non
                  │
                  ▼
          Créer la Merge Request 

Ajout du modèle de Merge Request par défaut
Pour standardiser la première validation (humaine) du flux (feature/* → develop), nous utilisons un gabarit de description. En plaçant ce fichier à un emplacement précis, GitLab le détectera automatiquement comme modèle par défaut.
## Description

-
## Related issue
Closes #

## Type of change
- [ ] Feature
- [ ] Bugfix
- [ ] Refactoring
- [ ] Documentation
- [ ] CI/CD
- [ ] Security

## Tests
- [ ] Unit tests
- [ ] Integration tests
- [ ] Functional tests
- [ ] Performance tests
- [ ] Smoke tests

## CI
- [ ] Maven Build
- [ ] SonarQube
- [ ] Semgrep
- [ ] Trivy FS
- [ ] Trivy Image
- [ ] Docker Hub

## Checklist
- [ ] Documentation updated
- [ ] No secrets committed
- [ ] Breaking change documented
- [ ] Ready for review
Vous pouvez bien sûr adapter le modèle à vos besoins, voici le mien pour le projet Flashcards et sa CICD

Pour que GitLab détecte les modèles
il faut utiliser un répertoire spécifique:
.gitlab/merge_request_templates/Default.md
Les modèles s'écrivent au format Markdown et se configurent directement dans le projet
Chaque fichier créé dans ce répertoire deviendra une option sélectionnable dans le menu déroulant lors de la création d'une MR
GitLab peut utiliser Default.md comme modèle de description par défaut pour les Merge Requests créées dans le projet.
En l'adaptant au mieux à nos besoins, il nous sera d'une aide précieuse pour cibler le sujet de la MR, en rapport avec ce que l'on merge.

Pour ce template, le processus sera:
|→ New push sur feature → Ouverture de la MR 
|→ template proposé automatiquement + validation de la Merge Request
|→ On ajoute le descriptif   
|→ On coche les cases adéquates   
|→ Le pipeline se met en route 
|→ On merge si tout est vert (approbations)
Le modèle est disponible dans le menu de création des Merge Requests, il est défini comme modèle par défaut dans la configuration du projet.

Préparation au pipeline
Pour permettre au pipeline d'ouvrir des Merge Requests, nous devons lui attribuer une identité technique, créer le fichier pipeline et l'inclure dans la CI.
1. Créer le token Depuis le projet Settings → Access Tokens
Nom:	gitlab-ci-bot
Expiration: 1 an
Scopes: 	api
	        write_repository
        	read_repository
Il générera alors un glpat token
gitlab-ci-bot : glpat-xxxxxxxxxxxxxxxxxx
2. L'enregistrer dans une variable
Depuis le Projet Settings → CI/CD → Variables
Clé Protected Masked Valeur
GITLAB_TOKEN glpat-xxxxxxxxxxxxxxxx
Le token reste limité au projet et possède uniquement les permissions nécessaires
Créer le fichier pipeline
1. Créer le fichier auto-promote.yml
.gitlab/
├── jobs/
│   └── auto-promote.yml

2. L'inclure dans le fichier .gitlab-ci.yml et y ajouter le stage release
stages:
  # ...  stages existants
  - release  
include:
  - local: '.gitlab/jobs/auto-promote.yml'
Le stage "release" dédié à l'auto-promote sert à automatiser entièrement la création d'une "release" dès qu'un pipeline réussit les tests sur la branche.

Le script de création automatique de MR
On commence par écrire la logique de base, voyons les premiers points essentiels:
Le pipeline doit être le dernier job des pipelines (stage release)
Le pipeline ne pourra se lancer qu'entre "develop" et "staging" et, entre "staging" et "main"
Les étapes sont écrites dans l'ordre de création, vous pouvez retrouver le script en entier depuis le projet Gitlab
On utilise une image "Alpine" qui est suffisante pour cette tâche
L'échec du job est considéré comme bloquant pour le pipeline
auto-promote:
  stage: release
  image: alpine:3.22
  allow_failure: false
  rules:
    - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "develop"'
    - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "staging"'
    - when: never
  before_script:
    - apk add --no-cache curl jq
Les rules déterminent les conditions ou le job
    "auto-promote" est ajouté au pipelines
Le job est exécuté uniquement lorsqu'un pipeline est déclenché par un push sur les branches develop ou staging.
Dans toutes les autres situations, la règle finale (when: never) empêche le job d'être ajouté au pipeline.

→ Avant d'éxécuter les scripts, on installe "curl" pour pouvoir envoyer nos requêtes et "jq" pour les affiner.
  script:
    - |
      set -e

      case "$CI_COMMIT_BRANCH" in
        develop)
          TARGET_BRANCH="staging"
          MR_LABELS="automated,promote,staging"
          ENABLE_AUTO_MERGE="true"
          ;;

        staging)
          TARGET_BRANCH="main"
          MR_LABELS="automated,release,production"
          ENABLE_AUTO_MERGE="false"
          ;;

        *)
          echo "No promotion required."
          exit 0
          ;;
      esac
      
      echo "=========================================="
      echo "Automatic promotion"
      echo "Source : ${CI_COMMIT_BRANCH}"
      echo "Target : ${TARGET_BRANCH}"
      echo "=========================================="
      
      PROJECT_ID="$CI_PROJECT_ID"

      curl --request POST \
      --header "PRIVATE-TOKEN: $GITLAB_TOKEN" \
      --header "Content-Type: application/json" \
      --data "{
        \"source_branch\":\"$CI_COMMIT_BRANCH\",
        \"target_branch\":\"$TARGET_BRANCH\",
        \"title\":\"Promote $CI_COMMIT_BRANCH → $TARGET_BRANCH\",
        \"remove_source_branch\":false,
        \"squash\":false
        }" \
        "$CI_API_V4_URL/projects/$PROJECT_ID/merge_requests"

La partie "script"
Avec set -e (errexit), on interrompt l'exécution du script dès qu'une commande échoue
On fait la différence entre les environnements, develop et staging avec la variable "CI_COMMIT_BRANCH" qui contient le nom de la branche Git en cours de compilation.
On lui définit:
La cible à atteindre avec TARGET_BRANCH:
Si on a poussé sur develop, la cible sera staging. Quand staging aura poussé, la cible sera main.
Les labels (MR_LABELS) correspondant aux cibles et à la MR (automated, promote)
ENABLE_AUTO_MERGE = true/false que l'on définit bien suivant notre stratégie: auto-merge uniquement entre [develop] et [staging]. Autrement, il ne doit rien faire (No promotion required)

$CI_PROJECT_ID représente l'ID du projet
On envoie une requête "POST" avec le GITLAB_TOKEN pour envoyer la demande de Merge Request(MR)
Le choix entre un "squash" et un "merge commit" dépend de la façon dont on veut voir l'historique du projet:
Avec squash=false, on indique que les commits de la branche source ne doivent pas être automatiquement regroupés lors de la fusion. Cela permet de conserver l'historique des commits tel qu'il existe sur la branche source.
CI_API_V4_URL est une variable GitLab CI/CD prédéfinie qui contient l'URL racine de l'API GitLab v4 (https://gitlab.com/api/v4)
À ce stade, le pipeline fonctionne déjà: il envoie bien une MR, avec le titre "Promote develop → Staging"
Ajoutons un corps de message, juste en dessous de PROJECT_ID
      DESCRIPTION=$(cat <<EOF
      ## Automatic Promotion

      **Source branch:** ${CI_COMMIT_BRANCH}

      **Target branch:** ${TARGET_BRANCH}

      **Commit short-SHA:** ${CI_COMMIT_SHORT_SHA}

      **Pipeline:** ${CI_PIPELINE_URL}

      **Author:** ${CI_COMMIT_AUTHOR}

      ---
      Generated automatically by GitLab CI.
    EOF
    )
    echo "=========================================="
    echo "Automatic promotion"
    echo "Source : ${CI_COMMIT_BRANCH}"
    echo "Target : ${TARGET_BRANCH}"
    echo "=========================================="
Attention au contenu du message (Markdown), les espaces sont essentiels.


On déplace la requête POST plus bas. Ainsi que le bloc message:
"echo "Automatic promotion"..."

On avait déjà la source et la cible (Target),
on ajoute juste quelques informations supplémentaires:
${CI_COMMIT_SHORT_SHA} affiche le short SHA du commit
${CI_PIPELINE_URL} contient l'URL du pipeline
${CI_COMMIT_AUTHOR} est l'auteur du commit qui a déclenché le pipeline

Gitlab CI favorise et encourage nettement l'utilisation des variables prédéfinies
On y ajoute la vérification et la gestion d'erreur:
    echo "Checking for existing merge request..."

    EXISTING_MR=$(curl --silent --show-error --fail-with-body \
      --header "PRIVATE-TOKEN: $GITLAB_TOKEN" \
      "$CI_API_V4_URL/projects/$PROJECT_ID/merge_requests?state=opened&source_branch=$CI_COMMIT_BRANCH&target_branch=$TARGET_BRANCH")

    if ! echo "$EXISTING_MR" | jq -e 'type == "array"' >/dev/null; then
      echo "ERROR: GitLab API did not return a merge request array."
      exit 1
    fi 
Avec EXISTING_MR, on demande à l'API de retourner les Merge Requests ouvertes (source_branch / target_branch).
À ce stade, la réponse peut contenir zéro, une ou plusieurs Merge Requests. Le script compte ensuite les éléments retournés afin de déterminer s'il existe déjà une MR à réutiliser.
S'il en trouve une, le job sera failed, il faudra aller voir soit les logs, soit dans les MR pour voir s'il n'y en a pas une d'ouverte.
Cela évite d'avoir plusieurs Merge Request ouvertes
Vérifier si une Merge Request ouverte existe déjà
  COUNT=$(echo "$EXISTING_MR" | jq 'length')

  if [ "$COUNT" -gt 0 ]; then
    STATUS="Existing Merge Request"
    MR_IID=$(echo "$EXISTING_MR" | jq -r '.[0].iid')
    MR_URL=$(echo "$EXISTING_MR" | jq -r '.[0].web_url')
  else
    STATUS="Merge Request created"
et y ajouter ses informations dans l'affichage:
    echo "=========================================="
    echo "Status        : ${STATUS}"
    echo "Source        : ${CI_COMMIT_BRANCH}"
    echo "Target        : ${TARGET_BRANCH}"
    echo "MR            : !${MR_IID}"
    echo "URL           : ${MR_URL}"
    echo "=========================================="
Si une MR ouverte correspondant au couple "source_branch/target_branch" est trouvée → le script la réutilise au lieu d'en créer une nouvelle.
Le script récupère alors son numéro interne (iid) et son URL afin de poursuivre son traitement.
#output
==========================================
Status  : Existing Merge Request
Source  : develop
Target  : staging
MR      : !42
URL     : https://gitlab.com/user/projet/-/merge_requests/42
==========================================
C'est beaucoup plus pratique pour comprendre ce qui se passe.
Dans le cas contraire (else), une nouvelle Merge Request sera créée
(STATUS="Merge Request created")
On crée la Merge Request avec la requête POST:
    RESPONSE=$(curl --silent --show-error --fail-with-body \
      --request POST \
      --header "PRIVATE-TOKEN: $GITLAB_TOKEN" \
      --data-urlencode "source_branch=${CI_COMMIT_BRANCH}" \
      --data-urlencode "target_branch=${TARGET_BRANCH}" \
      --data-urlencode "title=Promote ${CI_COMMIT_BRANCH} → ${TARGET_BRANCH} (${CI_COMMIT_SHORT_SHA})" \
      --data-urlencode "description=${DESCRIPTION}" \
      --data-urlencode "labels=${MR_LABELS}" \
      --data "remove_source_branch=false" \
      --data "squash=false" \
      "$CI_API_V4_URL/projects/$PROJECT_ID/merge_requests")

    if ! echo "$RESPONSE" | jq -e '.iid' >/dev/null; then
      echo "ERROR: Failed to create merge request."
      exit 1
    fi
    
    MR_IID=$(echo "$RESPONSE" | jq -r '.iid')
    MR_URL=$(echo "$RESPONSE" | jq -r '.web_url')
  fi
Mettons la commande curl créée précédemment, dans une variable "RESPONSE" afin de pouvoir la réutiliser facilement.
Nous avions CI_COMMIT_BRANCH, TARGET_BRANCH et PROJECT_ID, modifions légèrement le titre:
title=Promote ${CI_COMMIT_BRANCH} → ${TARGET_BRANCH} (${CI_COMMIT_SHORT_SHA})
affichera par exemple: "Promote develop → staging (cdf8795b)" dans la MR
On ajoute également les labels et la description (corps du message)

On lui demande également que:
S'il n'arrive pas à trouver l'ID de la MR, il affichera le message:
"Failed to create merge request"
Dans tous les autres cas, il affichera l'ID de la MR ainsi que son URL
On n'oublie pas de fermer la condition avec fi

Résultats
automated → créée par le pipeline
promote   → promotion entre environnements
staging   → destination
Avec "remove_source_branch = false", on empêche la suppression de la branche source, après sa fusion.
Bien que l'on ai toujours la possibilité, (dans la MR manuelle de "feature" à develop) de cocher la case Delete source Branch
Description et labels qui apparaissent dans le corps du message
Automatic Promotion
Source branch: develop
Target branch: staging
Commit short-SHA: cdf8795b
Pipeline: https://gitlab.com/val7304/flashcards/-/pipelines/2732419157
Author: Valérie Hermans valerie_hermans@outlook.com
------------------------------------------------  
Generated automatically by GitLab CI.
Activity  **** added
automated promote staging
Simple MR

Depuis les logs du job "auto-promote"
auto-promote
Passed    Started 1 minute ago by
$ case "$CI_COMMIT_BRANCH" in Source : develop Target : staging % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 2172 100 2010 100 162 2934 236 --:--:-- --:--:-- --:--:-- 3170
{"id":504836435,"iid":6,"project_id":40456472,"title":"Promote develop → staging", "description":null,"state":"opened","created_at":"2026-07-08T11:03:29.379Z", "updated_at":"2026-07-08T11:03:29.379Z", //...

Ajout du merge automatique
À ce stade, la MR existe, mais elle n'est pas fusionnée automatiquement. Pour faire cela dans GitLab, on va effectuer plusieurs vérifications
1. Configurer les conditions de fusion
Dans GitLab, on configure les conditions qui doivent être remplies avant qu'une Merge Request puisse être fusionnée automatiquement. On active l'option "Merge when pipeline succeeds" si les conditions sont remplies.
Projet Settings → Merge requests
Cocher:
Merge checks
These checks must pass before merge requests can be merged.
  Pipelines must succeed
Merge requests can't be merged if the latest pipeline did not succeed or is still running
      Skipped pipelines are considered successful
        Introduces the risk of merging changes that do not pass the pipeline.
 All threads must be resolved
2. Vérifier et/ou ajouter la protection de branche
On l'avait déjà configuré pour [staging], on peut protéger [develop] à présent.
Depuis le Projet Settings → Repository → Branches rules
Allowed to merge: Developers and Maintainers
Allowed to push and merge: No one
3. Vérifier le token et/ou l'utilisateur
L'auto-merge fonctionne très bien avec des branches protégées, mais il faut que l'utilisateur (ou le token) ait le droit de fusionner.
Pour que l'appel suivant fonctionne, le token doit avoir le scope: api

Une fois toutes les vérifications effectuées, on peut apporter les changements dans le script ; on ajoute, juste en dessous de la condition :
  echo "=========================================="
  echo "Project       : ${CI_PROJECT_PATH}"
  echo "Status        : ${STATUS}"
  echo "Source Branch : ${CI_COMMIT_BRANCH}"
  echo "Target Branch : ${TARGET_BRANCH}"
  echo "Commit        : ${CI_COMMIT_SHORT_SHA}"
  echo "MR            : !${MR_IID}"
  echo "URL           : ${MR_URL}"
  echo "Pipeline      : ${CI_PIPELINE_URL}"
  echo "Auto-merge    : ${ENABLE_AUTO_MERGE}"
  echo "=========================================="

  if [ "$ENABLE_AUTO_MERGE" != "true" ]; then
    echo "Auto-merge: disabled"
    echo "Manual merge is required for ${CI_COMMIT_BRANCH} → ${TARGET_BRANCH}."
    exit 0
  fi
  echo "Checking merge request status before enabling auto-merge..."

  MAX_ATTEMPTS=24
  ATTEMPT=1

  while [ "$ATTEMPT" -le "$MAX_ATTEMPTS" ]; do
    MR_DETAILS=$(curl --silent --show-error --fail-with-body \
      --header "PRIVATE-TOKEN: $GITLAB_TOKEN" \
      "$CI_API_V4_URL/projects/$PROJECT_ID/merge_requests/$MR_IID?with_merge_status_recheck=true")

    MERGE_STATUS=$(echo "$MR_DETAILS" | jq -r '.detailed_merge_status // empty')
    echo "Attempt ${ATTEMPT}/${MAX_ATTEMPTS}: ${MERGE_STATUS}"

    case "$MERGE_STATUS" in
      checking|unchecked|approvals_syncing)
        echo "GitLab is still preparing the merge request."
        sleep 10
        ATTEMPT=$((ATTEMPT + 1))
        ;;
      ci_still_running|ci_must_pass|can_be_merged)
        echo "Pipeline may still be running; enabling auto-merge."
        break
        ;;
      not_approved|blocked_status|conflict|cannot_be_merged|not_open)
        echo "ERROR: Merge request cannot be auto-merged."
        exit 1
        ;;
      *)
        echo "ERROR: Unknown merge request status: ${MERGE_STATUS}"
        exit 1
        ;;
    esac
  done
  if [ "$ATTEMPT" -gt "$MAX_ATTEMPTS" ]; then
    echo "ERROR: Merge request !${MR_IID} is still being prepared."
    exit 1
  fi
  echo "Enabling auto-merge for !${MR_IID}..."
Avec STATUS, on indique de quel type de MR il s'agit:
"Existing" ou "Created"
Les valeurs retournées sont "variables" suivant les branches, la MR, existante ou non et l'auto-merge activé ou non

On avait déjà défini ENABLE_AUTO_MERGE à "true" ou "false", on l'utilise maintenant dans une condition:
Si c'est "false",
il est désactivé, il affiche alors le message "disabled", on lui indique alors de merger la branche manuellement (de staging vers main)
Si c'est "true", il poursuit le script en vérifiant le status
echo "Checking merge request status before enabling auto-merge..."

Le script interroge GitLab afin de connaître l'état de la Merge Request (et avant de demander l'activation de l'auto-merge)
La variable "detailed_merge_status" permet de distinguer les situations dans lesquelles GitLab est encore en train de calculer l'état de la Merge Request, de celle qui peut poursuivre le traitement.
Tant que le statut indique que la vérification est encore en cours, le script attend quelques secondes puis effectue une nouvelle vérification.
Lorsqu'un statut compatible est trouvé, le script peut passer à l'étape suivante: demander à GitLab d'activer l'auto-merge.
Si un statut n'est pas reconnu, l'auto-merge ne sera pas activé

Dans les logs:
On affiche le compteur n/24, le status des évenements en cours jusqu'a ce que la MR soit crée, on affiche les informations en cours ...
Si le temps d'attente dépasse le compteur, il affichera le message: "ERROR: Merge request !45 is still being prepared" et le pipeline s'arrêtera
S'il passe la condition, on autorise l'auto-merge:
"Enabling auto-merge for !47..."
  AUTO_MERGE_RESPONSE_FILE="$(mktemp)"

  HTTP_STATUS=$(curl --silent --show-error \
    --output "$AUTO_MERGE_RESPONSE_FILE" \
    --write-out "%{http_code}" \
    --request PUT \
    --header "PRIVATE-TOKEN: $GITLAB_TOKEN" \
    --data-urlencode "auto_merge=true" \
    --data-urlencode "sha=${CI_COMMIT_SHA}" \
    "$CI_API_V4_URL/projects/$PROJECT_ID/merge_requests/$MR_IID/merge" || true)

  if [ "$HTTP_STATUS" != "200" ]; then
    echo "ERROR: Failed to enable auto-merge (HTTP ${HTTP_STATUS})"
    exit 1
  fi

  AUTO_MERGE_ENABLED=$(jq -r '((.merge_when_pipeline_succeeds //
    false) or (.auto_merge //
    false))' "$AUTO_MERGE_RESPONSE_FILE")

  if [ "$AUTO_MERGE_ENABLED" = "true" ]; then
    echo "Auto-merge: enabled"
  else
    echo "ERROR: GitLab returned HTTP 200 but auto-merge is not enabled"
    exit 1
  fi

  rm -f "$AUTO_MERGE_RESPONSE_FILE"
Continuons, en modifiant l'état de la Merge Request existante:
Cette partie détaille comment modifier la MR existante (requête PUT) pour lui activer l'auto-merge
Nous sommes à présent dans la situation ou:
S'il passe la condition, on autorise l'auto-merge:
      Enabling auto-merge for !47..."
AUTO_MERGE_RESPONSE_FILE crée un fichier temporaire et stocke son chemin absolu dans la variable (d'environnement ou locale)
Cette variable sert généralement à enregistrer les réponses automatiques, les logs ou les configurations d'un processus de fusion de code (merge), de base de données ou de paquets logiciels.
On envoie ensuite une requête API qui va activer l'auto-merge sur la MR à l'aide de l'option auto_merge=true. La MR sera alors fusionnée automatiquement lorsque les conditions requises seront satisfaites.
La réponse de GitLab ($AUTO_MERGE_RESPONSE_FILE) dépend de l'état actuel de la Merge Request au moment où le script s'exécute.
Un code HTTP 200 indique que GitLab a accepté la requête. Le script effectue une seconde vérification: Il analyse la réponse JSON retournée par GitLab afin de confirmer que l'auto-merge est activé.
Si la réponse confirme l'activation, le job affiche: "Auto-merge: enabled"
Dans le cas contraire, le job considère que l'activation n'a pas abouti et termine en erreur.

Détail de la requête PUT pour HTTP_STATUS
En effet, il nous fallait modifier une MR existante pour pouvoir activer l'auto-merge dessus. Voici les paramètres de la requête Curl:
--silent --show-error masque la barre de progression, affiche un message d'erreur si la requête échoue
--output "$AUTO_MERGE_RESPONSE_FILE" redirige la réponse dans le fichier temporaire (au lieu du terminal)
--write-out "%{http_code}" extrait uniquement le code d'état HTTP
--request PUT est la méthode requise pour modifier l'état d'une MR
--header "PRIVATE-TOKEN: $GITLAB_TOKEN" est l'authentification de la requête avec le jeton d'accès
--data-urlencode "auto_merge=true" active la fusion automatique (la MR fusionnera dès que la CI sera verte)
--data-urlencode "sha=${CI_COMMIT_SHA}" transmet le commit sur lequel l'auto-merge doit être configuré. Si un autre commit a été poussé entre-temps, GitLab rejettera la demande
Détail des réponses Gitlab possible:
Selon les situations, voici comment le script pourrait réagir en recevant le code de réponse de GitLab:
HTTP 200 OK
   GitLab a accepté la demande d'activation de l'auto-merge.

Un code HTTP différent de 200 indique que GitLab n'a pas accepté la demande.
Le script arrête alors le job et affiche le code HTTP retourné:
HTTP: 406 Not Acceptable Le SHA ne correspond pas
HTTP: 405 Method Not Allowed
   La MR n'est pas fusionnable (vérifier les permissions)
HTTP: 401 Unauthorized Le jeton d'accès est invalide

Chaque code renvoie un json explicite avec le code erreur et son explication:
exemple:
{
  "error": "invalid_token",
  "error_description": "Token was revoked or is invalid."
}
|| true empêche l'éventuel échec de la commande Curl et de provoquer ainsi l'arrêt immédiat du script.
Cela permet de récupérer le code HTTP dans HTTP_STATUS et de gérer explicitement l'erreur juste après.

Résultats finaux par situation (depuis les logs)
de Promote develop → staging
auto-merge: develop to staging
---------------------------------
Automatic promotion
Source : develop
Target : staging
Project: val7304/flashcards
==========================================
Checking for existing merge request...
==========================================
Project       : val7304/flashcards
Status        : Merge Request created
Source Branch : develop
Target Branch : staging
Commit        : cdf8795b
MR            : !227
URL          : https://gitlab.com/val7304/flashcards/-/merge_requests/227
Pipeline     : https://gitlab.com/val7304/flashcards/-/pipelines/xxxxxxxx
Auto-merge    : true
==========================================
Checking merge request status before enabling auto-merge...
Attempt 1/24: checking
GitLab is still preparing the merge request.
Attempt 2/24: ci_still_running
#debug detail status automerge
Pipeline may still be running; enabling auto-merge.
Enabling auto-merge for !227...
HTTP status: 200
GitLab response:
{
  "id": 518641251,
  "iid": 227,
  "project_id": 40456472,
  "title": "Promote develop → staging (cdf8795b)",
//..
  "user": {
    "can_merge": true
  }
} 
Auto-merge: enabled
de staging à main:
OK: 13.9 MiB in 27 packages
$ case "$CI_COMMIT_BRANCH" in 
==========================================
Project       : val7304/flashcards
Status        : Merge Request created
Source Branch : staging
Target Branch : main
Commit        : 4b3a22c0
MR            : !187
URL       : https://gitlab.com/val7304/flashcards/-/merge_requests/187
Pipeline     : https://gitlab.com/val7304/flashcards/-/pipelines/...
==========================================
Auto-merge    : disabled
Reason        : Production promotion requires manual validation.
Le déroulement est donc le suivant :
Push sur develop  →  Pipeline develop 
                            │
                            ▼
                    auto-promote
                            ├── crée (ou retrouve) la MR
                            ├── active "Merge when pipeline succeeds"
                            ▼
                    MR ouverte
                            │
                            ▼
                    Pipeline de la MR / staging
                            │
                            ▼
                    Tous les checks passent
                            │
                            ▼
                    GitLab fusionne automatiquement
                            │
                            ▼
                    Commit:
                    "Merge branch 'develop' into 'staging'"
                    Created by gitlab-ci-bot
La fusion n'aura lieu que lorsque le pipeline associé à cette Merge Request sera entièrement vert.

Cas où la MR existe déja
Suite à un bug par exemple, il peut arriver le cas où le merge request existe déja. Dans ce cas, le job s'arrête avec le status failed
La façon la plus simple de procéder est soit d'aller voir ses logs et de cliquer ensuite sur son URL, soit d'aller dans les MR et de vérifier s'il y en a une déjà ouverte.
Checking for existing merge request...
//...
URL           : https://gitlab.com/val7304/flashcards/-/merge_requests/381
Pipeline      : https://gitlab.com/val7304/flashcards/-/pipelines/2874550766
Auto-merge    : true
.. ERROR: Job failed: exit code 1
Même si l'auto merge est activé, la MR ne pourra pas se merger automatiquement.
Il faudra ouvrir la merge request et le stage "release" devra être rejoué (Run again ):
une fois relancé et s'il n'y a pas d'erreur:
on aura à nouveau les options de merge que l'on a configuré, c'est à dire: auto-merge entre develop et staging, merge manuel entre staging et main

La Merge Request
La promotion automatique entre develop et staging

Vue des pipelines
Vue de toute la chaine Gitlab flow: de la feature jusqu'à la branche "main":
Autopromotion release pipeline
Avec le stage "release", le job "auto-promote" s'ajoute en fin de pipeline pour la branche develop:
Autopromotion release job pipeline develop
Et la branche staging:
Autopromotion release job pipeline staging
Améliorations possibles
Ajout d'assigné(s)
Ajouter l'assigné via son ID numérique (recommandé) C'est la méthode la plus directe si l'on connaît l'ID de l'utilisateur GitLab (ex: 42).
1. Définissez l'utilisateur:
ASSIGNEE_ID="123456" ou plusieurs ASSIGNEE_ID[]="123456"
2. Ajouter l'argument --data-urlencode "assignee_ids[]=ID_UTILISATEUR"
à la commande PUT (HTTP_STATUS) du Curl
Ajout de "Reviewers"
Pour l'instant je suis seule, mais je pourrais avoir: reviewers=[]
Je ferai alors simplement: --data "reviewer_ids[]=12345"
ou plusieurs:
--data "reviewer_ids[]=123"
--data "reviewer_ids[]=456"

Également depuis la commande PUT (HTTP_STATUS)
Auto-suppression des branches [Feature]
Concerne uniquement les branche de feature/*
feature/* → Merge  → suppression automatique de la branche
Nous avons déjà: Enable "Delete source branch" option by default
et la possibilité de cocher ou décocher la case donc je ne le ferai pas, du moins pas de suite.

Dans l'API on utilise: should_remove_source_branch=true
Mais comme les promotions concernent develop et staging, il est hors de question de les mettre ici.
Cependant ce serait tout a fait possible pour une MR de type feature/* qui s'enverrait directement vers develop

Dans l'article suivant, nous verrons comment factoriser les pipelines en utilisant les variables de templates ce qui va grandement retrécir nos jobs (ouf!)

Laissez-moi un commentaire

En postant un commentaire anonyme, vous adhérez automatiquement aux conditions d'utilisation du site.