Skip to content

Exercice preparation324 (MR + tag + API)

C'est l'exercice "Merge request, tag et API GitLab" du cours. Le cours précise que c'est la même instance (VM) qu'à l'évaluation finale, donc à savoir refaire sans réfléchir.

L'environnement

GitLab http://192.168.177.129
Doc GitLab (locale) http://192.168.177.129:4000
Outil Git Bash
Runner exécuteur shell (Bash sous Linux), tag shell, git et curl installés
Projet preparation324, vide (sans README initial)
Tag demandé v0.0.1
Messages de commit tous en conventional commits, merge commit compris

Comme le runner est en mode shell, image: ne sert à rien ici. Et sans tags: [shell], le job reste bloqué en pending (voir runners).

Ce qui doit se passer

Événement Pipeline créée ? Jobs
push de la branche exercice (sans MR) non —
MR exercice vers main oui bonjour-mr uniquement
push sur main après la fusion non —
push du tag v0.0.1 oui appel-api uniquement

Donc: un workflow:rules qui n'autorise que les MR et les push de tag, et des rules: dans chaque job pour qu'un seul des deux tourne dans chaque pipeline.

1. Le projet et le dépôt local

Dans GitLab: New project > Create blank project, nom preparation324, décocher "Initialize repository with a README".

mkdir preparation324 && cd preparation324
git init --initial-branch=main
git config --local user.name "mon nom"
git config --local user.email "moi@mail.com"

# copier l'URL depuis GitLab (bouton Clone, HTTP)
git remote add origin http://192.168.177.129/<namespace>/preparation324.git

printf '# Préparation CI/CD\nMon premier exercice avec GitLab (VM).\n' > README.md
git add README.md
git commit -m "chore(project): initial commit"
git push --set-upstream origin main

Vérifier dans GitLab (Settings > Repository > Branch defaults) que main est bien la branche par défaut.

2. La branche de travail

git checkout -b exercice

# ajouter la ligne à la FIN du README
echo "Je prépare ma première merge request." >> README.md
git add README.md
git commit -m "docs(readme): ajout de la ligne sur la merge request"

Tip

Si le README n'a pas de retour à la ligne final, echo >> colle la phrase à la dernière ligne. Vérifier avec cat README.md.

Créer .gitlab-ci.yml à la racine:

default:
  tags:
    - shell

workflow:
  rules:
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
    - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_TAG'
    - when: never

stages:
  - preparation

bonjour-mr:
  stage: preparation

  rules:
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'

  script:
    - echo "Bonjour depuis la merge request"

appel-api:
  stage: preparation

  rules:
    - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_TAG'

  script:
    - echo "$CI_COMMIT_TAG"
    - |
      curl --fail-with-body --silent --show-error \
        --request GET \
        --header "JOB-TOKEN: ${CI_JOB_TOKEN}" \
        "${CI_API_V4_URL}/job"
git add .gitlab-ci.yml
git commit -m "ci(pipeline): ajout des jobs bonjour-mr et appel-api"
git push --set-upstream origin exercice

Le push de la branche ne doit pas créer de pipeline (le workflow dit never).

Warning

La config CI doit être dans la branche source avant d'ouvrir la MR, sinon GitLab n'a aucun .gitlab-ci.yml à lire pour la pipeline de MR.

Lecture du yaml

  • default: tags: applique le tag shell à tous les jobs d'un coup.
  • workflow décide si la pipeline existe: MR oui, push de tag oui, tout le reste non. Pour un tag, $CI_PIPELINE_SOURCE vaut push et $CI_COMMIT_TAG est rempli (sur une branche il est vide).
  • Les rules: des jobs filtrent dans la pipeline. Sans elles, les deux jobs tourneraient dans les deux types de pipeline, alors que la consigne demande bonjour-mr seul en MR et appel-api seul sur le tag.
  • Le | permet d'écrire le curl sur plusieurs lignes avec des \.

Le curl

Élément Rôle
${CI_API_V4_URL} URL de base de l'API GitLab (fournie)
/job renvoie les infos du job associé au jeton
JOB-TOKEN: ${CI_JOB_TOKEN} authentification, jeton fourni automatiquement, aucun token perso
--fail-with-body curl échoue (donc le job aussi) si HTTP ≥ 400, mais affiche quand même la réponse
--silent --show-error pas de barre de progression, mais les erreurs restent visibles

Warning

Ne jamais afficher CI_JOB_TOKEN dans les logs, ni le mettre dans le dépôt. Donc pas de echo $CI_JOB_TOKEN, pas de curl -v (il affiche les en-têtes envoyés) et pas de set -x.

3. La merge request

Dans GitLab: créer une MR de exercice vers main. Vérifier:

  • une pipeline démarre avec uniquement bonjour-mr
  • les logs affichent Bonjour depuis la merge request

Pour fusionner, éditer le message du commit de fusion (voir merge requests): celui par défaut (Merge branch 'exercice' into 'main') ne respecte pas conventional commits. Exemple:

feat(ci): ajout des jobs bonjour-mr et appel-api

Après la fusion, aucune pipeline supplémentaire ne doit apparaître sur main.

4. Le tag

git checkout main
git pull                    # récupère la fusion faite dans GitLab
git tag v0.0.1              # sur le commit courant
git push origin v0.0.1      # ou: git push --tags
git log --oneline --graph --all --decorate

Dans GitLab: une pipeline démarre avec uniquement appel-api. Ouvrir les logs et vérifier que le nom du tag et le JSON sont affichés.

5. Lire la réponse JSON

Il faut repérer l'identifiant du job, son nom et la référence git. Exemple abrégé et indicatif (les valeurs changent):

{
  "id": 42,
  "status": "running",
  "stage": "preparation",
  "name": "appel-api",
  "ref": "v0.0.1",
  "tag": true,
  "pipeline": { "...": "..." },
  "commit": { "...": "..." }
}
Question Champ
identifiant du job id
nom du job name
référence git utilisée ref (ici le tag, avec "tag": true)

Les pièges de cet exercice

Symptôme Cause probable
job bloqué en pending tag shell oublié (ou mal écrit)
une pipeline apparaît au push de la branche pas de workflow, ou workflow trop permissif
les deux jobs tournent rules: oubliées dans les jobs
pas de pipeline de MR .gitlab-ci.yml pas poussé sur la branche source avant la MR
une pipeline apparaît sur main après la fusion la règle push du workflow ne vérifie pas $CI_COMMIT_TAG
appel-api en erreur 401 mauvais en-tête (utiliser JOB-TOKEN)
$CI_COMMIT_TAG vide on est dans la pipeline de MR, pas celle du tag
merge commit refusé par le prof message par défaut Merge branch ... non modifié