Template fait pour du CI/CD avec gitlab, maven
17:08 24 Mar 2026

Back-end

Code complet

variables:
  MAVEN_OPTS: "-Dmvaen.repo.local=$CI_PROJECT_DIR/.m2/repository"

default:
  cache:
    key: $CI_COMMIT_REF_SLUG
    paths:
      - .m2/repository

stages:
  - build
  - test
  - package

job_build:
  image: maven:3-eclipse-temurin-17
  stage: build
  script: mvn clean compile
  artifacts:
    paths:
      - target/
    expire_in: "1 hour"

job_test:
  image: maven:3-eclipse-temurin-17
  stage: test
  script: mvn test

job_package:
  image: maven:3-eclipse-temurin-17
  stage: package
  script: mvn package -DskipTests
  artifacts:
    paths:
      - target/



Etape 0 - Fork du dépôt

Un fork, c'est simplement faire une copie personnelle d'un dépôt Git sur ton compte. Comme ça tu peux travailler dessus sans toucher à l'original.

1. Va sur ce lien : https://githepia.hesge.ch/gestion-de-produit/cicd-backend

fork → depuis projet SSH

Puis dans ton terminal :

git clone 
cd cicd-backend

Maintenant crée le fichier .gitlab-ci.yml à la racine du projet :

touch .gitlab-ci.yml

Puis ouvre-le dans ton éditeur (Neovim ) :

nvim .gitlab-ci.yml

Étape 1 — Préparation : le fichier .gitlab-ci.yml

Selon slides 3 stages pour le backend : build, test, et package.

# .gitlab-ci.yml

variables:
  MAVEN_OPTS: "-Dmaven.repo.local=$CI_PROJECT_DIR/.m2/repository"

default:
  cache:
    key: $CI_COMMIT_REF_SLUG
    paths:
      - .m2/repository

stages:
  - build
  - test
  - package

Ce que ça fait, ligne par ligne :

MAVEN_OPTS indique à Maven d'installer ses dépendances dans le dossier .m2/repository à l'intérieur de ton projet (au lieu du home de l'utilisateur système). C'est nécessaire pour que le cache GitLab puisse les retrouver.

Le cache dans default dit à GitLab de sauvegarder ce dossier .m2/repository entre les exécutions de la pipeline, pour ne pas retélécharger toutes les dépendances Maven à chaque fois

key: $CI_COMMIT_REF_SLUG est une variable automatique de GitLab qui représente le nom de ta branche ça permet d'avoir un cache différent par branche.


"Déclarez la variable suivante : MAVEN_OPTS: "-Dmaven.repo.local=$CI_PROJECT_DIR/.m2/repository""

Et la slide explique pourquoi : ça dit à Maven d'installer ses dépendances dans le dossier .m2/repository à l'intérieur de ton projet plutôt que dans le home système. C'est important parce que GitLab ne peut mettre en cache que des dossiers qui sont à l'intérieur du projet.

$CI_PROJECT_DIR c'est une variable automatique de GitLab qui contient le chemin absolu vers ton projet sur le runner.


slide 18 qui montre un exemple de cache :

default:
  cache:
    (key: $CI_COMMIT_REF_SLUG)
    paths:
      - dependances/

J'ai juste remplacé dependances/ par .m2/repository parce que c'est là que Maven met ses dépendances (comme défini par MAVEN_OPTS).


En résumé, ce qui vient directement des slides :

  • La variable MAVEN_OPTS → slide 24

  • L'idée du cache → slide 24

  • La syntaxe du cache → slide 18

Ce que j'ai adapté moi-même :

  • Le chemin .m2/repository dans le cache (logique depuis MAVEN_OPTS)

  • La key: $CI_COMMIT_REF_SLUG bonne pratique standard OPTIONNEL

Juste un peu plus de précision sur le cache parce que c'est important pour l'exam :

Le cache c'est ce qui permet de ne pas retélécharger les dépendances Maven à chaque pipeline. Sans lui, chaque fois que tu pushes du code, GitLab repart de zéro et retélécharge tout ce qui est très lent.

Donc le lien entre les deux c'est :

  • MAVEN_OPTS dit à Maven "installe tes dépendances dans .m2/repository"

  • Le cache dit à GitLab "sauvegarde ce dossier .m2/repository entre les pipelines"

Les deux travaillent ensemble, l'un sans l'autre ça ne sert à rien.


Etape 2 - Build

La slide 25 dit qu'il faut :

  • Un job dans le stage build

  • Utiliser Maven pour nettoyer et compiler

  • Conserver le dossier target/ pour le stage suivant (test) pendant 1 heure

ajouter la partie job :

job_build:
  image: maven:3-eclipse-temurin-17
  stage: build
  script: mvn clean compile

Maintenant il faut ajouter les artifacts pour conserver le dossier target/ pendant 1 heure. La slide 18 montre la syntaxe des artifacts :

artifacts:
  paths:
    - build/
job_build:
  stage: build
  script: mvn clean compile
  artifacts:
    paths:
      - target/
    expire_in: "1 hour"

Deux choses à retenir :

  • target/ et expire_in sont deux propriétés séparées sous artifacts

  • Tout ce qui est dans le job doit être indenté sous le nom du job

La pipeline s'est lancée, c'est déjà bien ! L'erreur est à la ligne 30 :

mvn: not found

Le problème : l'image Docker utilisée par défaut est alpine (ligne 27), et alpine est un Linux minimaliste qui n'a pas Maven installé.

Il faut spécifier une image qui contient déjà Maven. La slide 20 montre exactement comment faire avec la propriété image dans un job :

job:
  image: maven:3-eclipse-temurin-17
  stage: build
  script: mvn clean compile
  artifacts:
    paths:
      - target/
    expire_in: "1 hour"

Etape 3 - job test

job_test:
  image: maven:3-eclipse-temurin-17
  stage: test
  script: mvn test

Etape 4 - Packaging

On passe au dernier job : le packaging !

La slide 27 dit :

  • Stage package

  • Générer un fichier .jar avec Maven

  • Le rendre téléchargeable depuis l'interface GitLab sans limite de temps

La commande Maven pour générer un .jar c'est mvn package -DskipTests le -DskipTests c'est pour ne pas relancer les tests puisqu'on l'a déjà fait dans le stage précédent.

Le .jar généré sera dans target/ comme les fichiers compilés.

job_package:
  image: maven:3-eclipse-temurin-17
  stage: package
  script: mvn package -DskipTests
  artifacts:
    paths:
      - target/

Etape 5 - README

# CI/CD Backend – Java/Maven

## Description de la pipeline

Cette pipeline GitLab CI/CD automatise le build, les tests et le
packaging d'une application Java avec Maven. Elle est composée de
3 stages qui s'exécutent séquentiellement :

1. **build** : nettoie et compile le code source (`mvn clean compile`)
2. **test** : exécute les tests unitaires (`mvn test`)
3. **package** : génère le fichier `.jar` (`mvn package -DskipTests`)

## Points importants

### MAVEN_OPTS
La variable `MAVEN_OPTS` indique à Maven d'installer ses dépendances
dans le dossier `.m2/repository` à l'intérieur du projet :
`-Dmaven.repo.local=$CI_PROJECT_DIR/.m2/repository`

Sans cette variable, le cache GitLab ne peut pas sauvegarder les
dépendances entre les pipelines, car elles seraient installées dans
un dossier système inaccessible.

### Image Docker
L'image `maven:3-eclipse-temurin-17` est utilisée car l'image par
défaut (alpine) ne contient pas Maven.

### Artifacts
- Le dossier `target/` est conservé 1 heure après le build pour
être utilisé par le stage de test
- Le `.jar` final (stage package) est conservé sans limite de temps
pour être téléchargeable depuis GitLab

Front-end

Code complet

default:
  image: node:lts-slim
  cache:
    key: $CI_COMMIT_REF_SLUG
    paths:
      - node_modules/

stages:
  - build
  - quality

job_build:
  stage: build
  script:
    - npm ci
    - npm run build
  artifacts:
    paths:
      - dist/
    expire_in: "1 hour"

#code du prof 
sonarqube-check:
  stage: quality
  image:
    name: sonarsource/sonar-scanner-cli:10
    entrypoint: [""]
    docker:
      user: root
  variables:
    SONAR_USER_HOME: "${CI_PROJECT_DIR}/.sonar"
    GIT_DEPTH: "0"
  cache:
    key: "${CI_JOB_NAME}"
    paths:
      - .sonar/cache
  before_script:
    - rm /usr/lib/jvm/default-jvm/jre/lib/security/cacerts
    - wget --no-check-certificate -P /usr/lib/jvm/default-jvm/jre/lib/security/ 
    - apk update
    - apk add shadow
    - chsh -s /bin/bash scanner-cli
    - su - scanner-cli
  script:
    - sonar-scanner
  allow_failure: true

Etape 1 - Fork et création du fichier

Même chose qu'au début fork et clone du dépôt frontend :

1. Va sur : https://gitedu.hesge.ch/jeremy.gobet/breakout

2. Clique sur Fork en haut à droite et choisis ton compte personnel.

3. Clone ton fork :

cd ..
git clone 
cd breakout

4. Crée le fichier vide :

touch .gitlab-ci.yml
nvim .gitlab-ci.yml

Etape 2 - Default

La slide 31 dit de mettre ces propriétés par défaut :

  • Une image : node:lts-slim

  • Un cache pour npm

Pour npm, le dossier à mettre en cache c'est node_modules/ c'est l'équivalent du .m2/repository de Maven.

  1. nodes_modules/ → c'est node_modules/ (sans le s après node)

  2. La key est vide — mets $CI_COMMIT_REF_SLUG comme pour le backend OPTIONNEL

Etape 3 - build

Voilà la syntaxe pour plusieurs commandes dans script :

script:
  - npm ci
  - npm run build
artifacts:
  paths:
    - dist/
  expire_in: "1 hour"

Etape 4 - Quality

Maintenant le job de qualité avec Sonar (slide 34). C'est le plus complexe de cette partie.

Voilà ce qu'il faut faire :

1. Va sur https://isc-sonar.edu.hesge.ch/ et connecte-toi avec ton compte GitLab HEPIA.

2. Crée un nouveau projet et appelle-le ton-nom-breakout.

3. Sonar va te donner des instructions pour configurer la pipeline → MARCHE PAS

Déconstruction du code donné par le prof


stage: quality Ce job appartient au stage quality, il s'exécute après le build.


image

image:
  name: sonarsource/sonar-scanner-cli:10
  entrypoint: [""]
  docker:
    user: root

On utilise l'image officielle de Sonar qui contient déjà le scanner. entrypoint: [""] désactive le point d'entrée par défaut de l'image pour que GitLab puisse exécuter ses propres commandes. user: root lance le container en tant qu'administrateur.


variables

variables:
  SONAR_USER_HOME: "${CI_PROJECT_DIR}/.sonar"
  GIT_DEPTH: "0"

SONAR_USER_HOME indique à Sonar où stocker son cache d'analyse. GIT_DEPTH: "0" dit à Git de télécharger toutes les branches du projet Sonar en a besoin pour analyser correctement l'historique du code.


cache

cache:
  key: "${CI_JOB_NAME}"
  paths:
    - .sonar/cache

Même principe que le cache Maven/npm on sauvegarde le cache de Sonar entre les pipelines pour aller plus vite.


before_script

before_script:
  - rm /usr/lib/jvm/default-jvm/jre/lib/security/cacerts
  - wget ... cacerts
  - apk update
  - apk add shadow
  - chsh -s /bin/bash scanner-cli
  - su - scanner-cli

C'est la partie spécifique à HEPIA. En gros :

  • Les deux premières lignes remplacent les certificats SSL par ceux de HEPIA nécessaire pour que le scanner puisse communiquer avec le serveur Sonar de l'école

  • apk update et apk add shadow installent des outils système

  • Les deux dernières lignes changent l'utilisateur qui exécute le scanner


script

script:
  - sonar-scanner

Lance simplement l'analyse du code et envoie les résultats au serveur Sonar.


allow_failure: true Si le job échoue (par exemple si le serveur Sonar est inaccessible), la pipeline continue quand même et est considérée comme réussie. Sans ça, une erreur Sonar bloquerait tout.


Etape 5 - README

# CI/CD Frontend – Breakout/Node

## Description de la pipeline

Cette pipeline GitLab CI/CD automatise le build et l'analyse 
qualité d'une application frontend Node.js. Elle est composée 
de 2 stages qui s'exécutent séquentiellement :

1. **build** : installe les dépendances et compile le projet
2. **quality** : analyse la qualité du code avec SonarQube

## Points importants

### Image par défaut
L'image `node:lts-slim` est utilisée par défaut pour tous les 
jobs — elle contient Node.js et npm préinstallés.

### npm ci vs npm install
On utilise `npm ci` au lieu de `npm install` car il installe 
les dépendances exactement comme définies dans `package-lock.json`, 
ce qui garantit des builds reproductibles.

### Artifacts
Le dossier `dist/` contient les fichiers compilés du projet. 
Il est conservé 1 heure après le build pour être utilisé 
par les jobs suivants.

### SonarQube
Le job Sonar utilise `allow_failure: true` car le serveur 
SonarQube de HEPIA n'est accessible que depuis le réseau 
de l'école. La pipeline continue même si ce job échoue.

Supplémentaire

lint

  
job_lint:
      stage: quality
      script:
          - npm run lint
        allow_failure: true
maven gitlab continuous-integration artificial-intelligence