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 tagshellà tous les jobs d'un coup.workflowdécide si la pipeline existe: MR oui, push de tag oui, tout le reste non. Pour un tag,$CI_PIPELINE_SOURCEvautpushet$CI_COMMIT_TAGest 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 demandebonjour-mrseul en MR etappel-apiseul sur le tag. - Le
|permet d'écrire lecurlsur 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é |