TP2 – Git avancé 2/2 GitLab CI/CD, Tests et releases automatisés, Intégration et déploiement continu

Dans ce second (et dernier) TP portant sur Git, nous allons étudier les outils de CI/CD (continuous integration/continuous delivery) proposés par GitLab. Globalement, il s’agit d’automatiser différentes tâches qui seraient fastidieuses (et chronophages) à faire “à la main”. Par exemple : tester l’intégration de différents modules de code, construire et mettre à disposition l’exécutable de l’application, déployer un site web en production, etc.

La plupart de ces outils sont aussi disponibles sur les autres plateformes comme GitHub, Bitbucket, etc (avec leurs propres spécificités).

Découverte de GitLab CI/CD et des pipelines

GitLab propose un outil appelé GitLab CI/CD (pour continuous integration/continuous delivery), disponible dans chaque dépôt. Cet outil permet notamment de détecter quand un événement survient sur un dépôt (par exemple, un push sur une branche spécifique…) et de déclencher automatiquement des scripts (appelés jobs) sur différents conteneurs dockers (machines virtuelles) contenant le code du projet. Tous ces jobs sont regroupés dans diverses étapes (appelées stages) et s’exécutent de manière ordonnée ou en parallèle à travers un pipeline.

Les jobs vont donc vous permettre de charger votre projet sur un système Linux virtuel pré-configuré de votre choix (par exemple, un conteneur qui contient java et Maven) et de réaliser des actions dessus (compilation, tests, publication d’un exécutable, et bien d’autres)…

Nous le verrons par la suite, il est possible de conditionner le déclenchement des jobs. Quand un événement survient sur le dépôt (push, création de tag, etc) le pipeline exécute tous les jobs concernés. On peut suivre la progression des tâches en direct et, en cas d’échec (par exemple, un test ne passe pas, le programme ne compile pas…) GitLab prévient en ligne qu’il y a eu des erreurs, avec les détails (il est possible de consulter les logs de la machine virtuelle exécutant chaque job).

Avec ce système, GitLab pourrait détecter automatiquement s’il y a des problèmes. Par exemple, lorsque deux branches sont fusionnées avec succès, mais que le code ne compile plus ou ne passe pas les tests.

Au-delà de ça, les jobs peuvent aussi servir à automatiser certaines tâches comme le déploiement d’un site web (ou autre), la mise en ligne de la documentation, etc.

Le fichier .gitlab-ci.yml

Le pipeline (et les différents jobs) d’un dépôt est défini à travers d’un fichier .gitlab-ci.yml (au format YAML) qui se place à la racine du dépôt.

Voici l’allure générale d’un tel fichier et des options courantes qu’on peut utiliser :

stages:
  - stage1
  - stage2

job1:
  stage: stage1
  image: nom_image_docker
  script:
    - ...
    - ...
  artifacts:
    paths:
      - ...
  dependencies:
    - ...
  rules:
    - if: ...

job2:
  stage: stage1
  image: nom_image_docker
  ...

job3:
  stage: stage2
  image: nom_image_docker
  ...
  rules:
    - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'   

Comme vous pouvez le constater, le fichier de configuration du pipeline commence par définir des stages. Les différents stages s’exécutent dans l’ordre, les uns après les autres. Un job est lié à un stage. Tous les jobs d’un stage s’exécutent en parallèle. Dans l’exemple ci-dessus, il y a deux stages et trois jobs. Les deux premiers jobs sont liés au stage1 et s’exécutent donc en parallèle. Le troisième job appartient au stage2 et ne s’exécutera que quand stage1 sera terminé, donc quand job1 et job2 seront terminés. Si un job d’un stage échoue, le stage suivant ne sera pas réalisé.

Revenons maintenant sur la configuration d’un job et intéressons-nous à ses options (certaines sont obligatoires, d’autres non) :

Il existe beaucoup d’autres options que nous n’aborderons pas dans ce TP, mais que vous pouvez retrouver ici.

GitLab fournit également diverses variables prédéfinies accessibles dans tous les jobs. Ces variables permettent de récupérer et exploiter des informations sur l’événement ayant déclenché le pipeline (message de commit, nom du tag, nom de la branche, etc). Par exemple $CI_COMMIT_BRANCH contient le nom de la branche sur laquelle est effectué le push, $CI_DEFAULT_BRANCH contient le nom de la branche par défaut (main, master) ou autre, etc. Ces variables sont préfixées d’un $. On peut retrouver la liste des variables prédéfinies sur cette page.

Exemple

Voici un exemple un peu plus concret :

stages:
  - test
  - deploy

test:
  stage: test
  image: php:8.4
  script:
    - php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" && \
      php -r "if (hash_file('sha384', 'composer-setup.php') === 'dac665fdc30fdd8ec78b38b9800061b4150413ff2e3b6f88543c636f7cd84f6db9189d43a81e5503cda447da73c7e5b6') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" && \
      php composer-setup.php && \
      php -r "unlink('composer-setup.php');" && \
      mv composer.phar /usr/local/bin/composer
    - composer install
    - echo "Lancement des tests unitaires"
    - php -d xdebug.mode=coverage ./vendor/bin/phpunit

deploy:
  stage: deploy
  image: alpine:latest
  script:
    - rm -rf .git
    - rm .gitlab-ci.yml
    - commande pour uploader les fichier vers un serveur (ftp par exemple...)
    - connexion ssh au serveur pour exécuter divers commandes de déploiement...
  rules:
    - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'

Ce pipeline contient deux stages qui contiennent chacun un job. Comme il n’y a qu’un job par stage, on préfère nommer chaque job comme le stage dans lequel il intervient (mais c’est n’est pas obligatoire, bien entendu).

Le premier job test :

Le deuxième job deploy :

Premiers pas

Vous allez maintenant créer votre premier pipeline (très simple) sur le projet d’éditeur de texte du TP précédent. Normalement, vous aviez travaillé à deux sur le même projet à la fin de ce TP, donc techniquement, un des deux membres du binôme a un projet plus avancé. Ici, vous travaillerez seul sur votre propre projet, mais ce n’est pas grave s’il manque les dernières fonctionnalités des exercices réalisés en binôme (si c’est le cas et que cela vous gêne vraiment, vous pouvez faire un fork du dépôt de votre collègue…).

  1. En local, ouvrez votre projet d’éditeur de texte puis placez-vous sur la branche development et assurez-vous d’être à jour avec le dépôt distant (git pull origin).

  2. À la racine du dépôt, créez un fichier .gitlab-ci.yml.

  3. À l’aide de ce fichier, créez le pipeline qui exécute un stage nommé hello qui contient un seul job (du nom que vous voulez) qui s’exécute sur l’image alpine:latest et affiche un message (de votre choix) en console. Ce job doit seulement s’exécuter sur la branche development.

  4. Créez un commit pour ajouter ce fichier puis poussez-le sur le dépôt distant.

  5. Rendez-vous sur la page de votre projet sur GitLab https://gitlabinfo.iutmontp.univ-montp2.fr/qualite-de-developpement-semestre-3/editeur-de-texte/etu/votrelogin/editeur-de-texte puis, à gauche, dans le menu BuildPipelines.

  6. Dans ce nouveau menu, vous devriez voir votre pipeline en train de s’exécuter (soit en cours, soit terminée selon votre vitesse et les performances du serveur). Si le pipeline a échoué, c’est que vous vous êtes trompés à un endroit, il faudra alors corriger et recommencer (nouveau commit, nouveau push). Si tout est bon (en attente ou terminé), cliquez sur le status du pipeline pour ouvrir une nouvelle fenêtre.

  7. Dans la nouvelle fenêtre, vous pouvez observer chaque job du pipeline (un seul dans votre cas). Cliquez sur votre job afin d’ouvrir les logs de la machine virtuelle, et vérifiez que votre message s’affiche bien à la fin de l’exécution.

  8. En local, créez et déplacez-vous vers une nouvelle branche test_rapide depuis la branche development. Ajoutez ensuite un fichier bidon (par exemple, un fichier texte vide) puis faites un commit et poussez la nouvelle branche. Rendez-vous dans le menu des pipelines et observez que (normalement) rien ne se produit. Si toutefois un pipeline s’exécute quand même, cela signifie que vous n’avez pas bien rédigé la condition de déclenchement sur le job de votre pipeline ! Si tel est le cas, revenez sur development, supprimez test_rapide, corrigez, poussez le fichier de configuration et recommencez.

  9. Revenez sur la branche development puis supprimez la branche test_rapide (en local et à distance).

Automatisation des tests sur GitLab

Vous allez maintenant améliorer votre pipeline afin de lui permettre de vérifier que votre programme compile bien puis pour qu’elle exécute les tests unitaires sur votre application. Mais tout d’abord… il vous faut des tests unitaires ! (comment, vous n’avez pas écrit de tests unitaires depuis le début ?!)

  1. Si ce n’est pas déjà fait, placez-vous dans votre branche development.

  2. Si le dossier de tests src/test/java n’existe pas encore (car vous n’avez écrit aucun test), alors il faudra le créer. Depuis IntelliJ le plus simple est de générer une classe de test, ce qui va provoquer la création du répértoire de tests : ouvrir la classe Document → clic droit sur la déclaration de la classe public class DocumentGenerateTest… . Après avoir donné le nom à votre classe de test, disons DocumentTest, le dossier src/test/java la contenant va être généré. De plus, DocumentTest va être placée dans le même paquetage que la classe testée Document (d’après la convention standard). Si vous voulez créer le répertoire de tests avant d’y ajouter les classes de tests, alors c’est un peu plus lent : cliquer droit sur le répertoire srcNewDirectory → Choisissez test/java → Créez un paquetage fr.iut.editeur.document dans src/test/ → à l’intérieur, créez la classe DocumentTest.

    Par convention, la couleur verte indique qu’il s’agit du répertoire contenant le code source des tests.

  3. Écrire quelques méthodes pour tester les méthodes de la classe Document. Si vous ne vous rappelez plus comment faire, jetez un œil à vos cours de Dev-Objets de l’an dernier ! Voici un squelette de cette classe :

  package fr.iut.editeur.document;

  import org.junit.jupiter.api.Test;

  import static org.junit.jupiter.api.Assertions.*;

  public class DocumentTest {

      @Test
      public void testMethode() {
          assertXXX(...)
      }

  }
  1. Pour exécuter les tests, IntelliJ vous permet de le faire simplement, en cliquant sur le bouton de lancement, à côté de la déclaration de la classe.

Maintenant que vous avez des tests unitaires prêts et fonctionnels, nous allons faire en sorte que GitLab vérifie que votre programme compile bien puis exécute les tests après n’importe quelle mise à jour sur le dépôt.

Dans votre pipeline, vous allez diviser le travail en deux stages et deux jobs :

  1. Un premier stage (associé à un job) qui teste la compilation.

  2. Un deuxième stage (associé à un autre job, s’exécutant après le stage de compilation) qui lance les tests unitaires.

Pour cela, vous aurez besoin des ressources suivantes :

Cela peut sembler lourd de séparer cela en deux stages/jobs, mais cela nous permet de former un enchaînement logique bien divisé : si nous avions tout regroupé dans un seul job, en cas d’échec, il aurait été plus difficile de dire ce qui ne va pas (compilation, tests, les deux ?). Ici, on a l’information immédiatement grâce aux noms des stages/jobs. De plus, avec cette organisation, si le stage de compilation ne passe pas, le stage des tests unitaires n’est pas réalisé.

  1. Dans votre fichier .gitlab-ci.yml, supprimez ce que vous aviez fait lors de l’exercice précédent puis définissez les deux stages et les deux jobs demandés. Pour rappel, ils doivent s’exécuter dans tous les cas, donc il n’y a pas de conditions à préciser. Le premier job teste la compilation, le deuxième lance les tests unitaires.

  2. Faites un commit et un push sur votre branche development. Sur GitLab, rendez-vous sur votre dépôt et retournez dans l’onglet des pipelines. Vous devriez voir votre pipeline en cours d’exécution. Cliquez sur son statut pour ouvrir les détails puis inspectez chaque job. Normalement, tout devrait passer.

  3. Maintenant, faites en sorte de modifier légèrement votre code pour qu’il ne compile plus. Faites un commit et un push puis vérifiez que le premier job de votre pipeline échoue bien et que le second n’est pas exécuté. Remettez votre code en ordre.

  4. Pour finir, modifiez légèrement la classe Document pour qu’un ou plusieurs tests ne passent plus. Attention, le programme doit compiler ! Faites un commit et un push puis vérifiez que le premier job de votre pipeline passe, mais pas le second. Enfin, remettez tout en ordre.

Remarque : Dans cet exemple, l’image utilisée pour les deux stages est la même. Ainsi, pour éviter la duplication dans le fichier .gitlab-ci.yml, on aurait pu indiquer image: maven:3.9.5-eclipse-temurin-21 sur la première ligne de ce fichier, avant le mot-clé stages. Cela signifie que c’est l’image par défaut pour tous les stages et donc on peut omettre la déclaration de l’image dans chacun des jobs.

Automatisation des releases

Releases et tags

GitLab permet de publier des releases de notre application, c’est-à-dire publier une version fonctionnelle du logiciel dans un espace de notre dépôt en ligne, avec les exécutables et les ressources nécessaires.

Sur Git il est possible d’associer un commit à un tag. Un tag est une étiquette nommée. Généralement, on associe une release à un tag. Il est aussi possible de faire un checkout directement sur un tag !

Par convention, les tags s’utilisent donc pour indiquer la version d’un programme sous la forme vX.Y.Z. Ainsi, par exemple v0.0.1, v1.0.0, etc. X désigne les mises à jour majeures (le logiciel change quasi-complétement), Y les mises à jour intermédiaires (ajout de nouvelles fonctionnalités, par exemple après un sprint) et Z les mises à jour mineures (fixes de bugs par exemple).

Pour créer un tag, on utilise simplement la commande :

git tag vX.Y.Z

Cela aura pour effet d’associer le dernier commit à ce tag. Pour indiquer au dépôt distant que le tag a été créé, il faut le pousser. Par exemple :

git push origin v0.0.1

Pour supprimer un tag en local, on utilise l’option -d avec la commande tag :

git tag -d vX.Y.Z

Et pour le supprimer sur le dépôt distant :

git push -d origin v0.0.1

Release automatique de l’application d’édition de texte

Nous allons faire en sorte que, dès qu’un tag est push sur le dépôt distant, le code de l’application soit build en un exécutable java .jar et qu’une release contenant notre exécutable soit publiée. Ainsi, dès qu’une nouvelle version est prête, il suffit de créer un tag et GitLab se charge alors du reste.

Dans une release, il est possible d’inclure des liens vers des fichiers. Par défaut, le code source de l’application est mis à disposition. Dans notre cas, nous allons seulement ajouter un lien de téléchargement vers l’exécutable .jar de l’application, mais dans l’absolu, il est tout à fait possible d’inclure d’autres fichiers.

Nous allons répartir le travail en deux stages/jobs :

  1. Premier job : construire l’exécutable de l’application et l’exporter pour le prochain stage :
    • Le script lance la construction de l’exécutable grâce à une commande maven, tout en précisant la version de l’application (qu’on obtient grâce au nom du tag).
    • Il déplace ensuite l’exécutable produit dans le dossier courant.
    • Enfin, on utilise le système d’artifacts pour exporter le fichier jar vers le prochain stage.
  2. Deuxième job : publier une release contenant l’exécutable :
    • On utilise le système d’artifacts pour exporter encore une fois le fichier jar (qu’on a reçu du précédent stage/job) de manière définitive (pour qu’il ne soit pas supprimé à l’issue de l’exécution du pipeline).
    • On utilise la directive release (que nous allons bientôt voir) pour publier la release en y attachant le lien pointant sur l’artifact correspondant à notre exécutable .jar.

Pour pouvoir mettre tout cela en place, nous allons avoir besoin de nous attarder sur différentes options qu’il est possible de définir dans les jobs :

stages:
  - exemple1

exemple1:
  stage: exemple1
  image: ...
  variables:
    NOM_VAR_1: valeur
    NOM_VAR_2: bis_$NOM_VAR_1 #contient bis_valeur
  script:
    - commande1 $NOM_VAR_1
    - commande2 $NOM_VAR_2
    - etc...
  artifacts:
    paths:
      - "chemin/fichier1.xxx"
      - "chemin/fichier2.xxx"
      - "chemin/dossier1/"
    expire_in: ...
  rules:
    - if: '$CI_COMMIT_TAG'

Expliquons tout cela :

Nous allons procéder par étape et vous allez d’abord commencer par implémenter le job de build sans la release. Nous pourrons ainsi voir si l’exécutable est bien produit et exporté. Voici ce dont vous aurez besoin :

Allez, il est temps de mettre en application !

  1. Dans votre fichier .gitlab-ci.yml, ajoutez un nouveau stage build à la suite et un job associé (avec le même nom) qui :
    • Produit le jar de l’application avec le bon libellé de version.
    • L’exporte comme artifact avec une durée de vie d’une heure.
    • S’exécute seulement quand un tag est poussé.
  2. Faites un commit et un push sur votre branche development. Sur GitLab, rendez-vous sur votre dépôt et retournez dans l’onglet des pipelines. Normalement, les deux premiers jobs doivent bien s’exécuter, mais pas le dernier (car se déclenche seulement quand on pousse un tag).

  3. Créez un tag nommé v1.0.0 puis, poussez-le sur le dépôt distant.

  4. Sur la page de gestion des pipelines, observez le déroulement des jobs, et vérifiez que le job build s’exécute bien à la fin. À l’issue de l’exécution, rendez-vous dans le menu accessible via le panneau latéral gauche BuildArtifacts et vérifiez que votre fichier .jar est bien accessible en déroulant les fichiers associés au job build. Vérifiez également que son nom est correct (EditeurDeTexte-1.0.0.jar).

  5. S’il y a une erreur quelque part, vous devrez bien penser à pousser vos modifications sur le dépôt distant puis à créer et pousser un nouveau tag pour re-tester (ou supprimer celui-ci en local et à distance puis le pousser de nouveau). La version en suffixe de l’exécutable jar doit correspondre au tag.

Tout fonctionne jusqu’ici ? Parfait ! Il ne nous reste donc plus qu’une dernière étape : faire en sorte que notre pipeline exporte de manière définitive l’exécutable, crée une release et y attache le lien de téléchargement du fichier.

Voyons comment faire cela :

stages:
  - build
  - release

#job qui build et exporte l'exécutable dans un artifact
build:
  ...

release:
  stage: release
  image: registry.gitlab.com/gitlab-org/release-cli:latest
  dependencies:
    - build
  artifacts:
    paths:
      - "chemin/fichier1.xxx"
      - "chemin/fichier2.xxx"
    expire_in: never
  script:
    - echo "Publication de la release X.Y.Z..."
  release:
    name: 'Release X.Y.Z'
    description: "Version X.Y.Z de l'application"
    tag_name: '$CI_COMMIT_TAG$'
    ref: '$CI_COMMIT_TAG'
    assets:
      links:
        - name: "fichier1.xxx"
          url: "$CI_JOB_URL/artifacts/raw/fichier1.xxx"
        - name: "fichier2.xxx"
          url: "$CI_JOB_URL/artifacts/raw/fichier2.xxx"
  rules:
    - if: '$CI_COMMIT_TAG'

Attardons-nous sur tout cela :

Votre but est donc de créer un stage et un job associé qui fait suite au job de build, récupère ses artifacts (ici, on aura seulement le fichier EditeurDeTexte-X.Y.Z.jar), l’exporte via les artifacts et publie la release. Voici quelques conseils pour votre prochaine mission :

  1. Dans votre fichier .gitlab-ci.yml, ajoutez un nouveau stage release à la suite et un job associé (avec le même nom) qui :
    • Exporte l’exécutable jar récupéré du job build comme artifact avec une durée de vie infinie (pas d’expiration).
    • Crée une release avec un lien de téléchargement vers cet exécutable.
    • S’exécute seulement quand un tag est poussé.
  2. Faites un commit et un push sur votre branche development.

  3. Créez un tag nommé v1.1.0 (ou autre, tant que ça respecte le format vX.Y.Z) puis, poussez-le sur le dépôt distant.

  4. Sur la page de gestion des pipelines, observez le déroulement des jobs, et vérifiez que le job release s’exécute bien à la fin.

  5. Enfin, si tout s’est bien passé, rendez-vous dans le menu DeployReleases au niveau du panneau latéral gauche. Vous devriez alors voir votre release! Vérifiez que l’exécutable .jar peut bien être téléchargé.

  6. En local, rendez-vous sur master et fusionnez la branche development. Poussez les changements sur le dépôt distant (sur la branche master donc).

Félicitations, vous avez automatisé le processus de release de votre application ! Dorénavant, dès qu’un tag est créé et poussé, une release sera créée et publié. On peut souligner le fait qu’il n’est pas nécessairement obligatoire de passer par le système d’artifact pour publier un fichier dans une release. On peut spécifier n’importe quel lien. On pourrait donc imaginer un job qui upload les fichiers désirés sur un serveur externe et on utiliserait alors ces liens dans la release.

Déploiement d’un site web PHP

Pour terminer, nous allons créer un nouveau projet de site web, qui ne contiendra qu’une page simple, et qui sera automatiquement déployé sur le serveur web de l’IUT après chaque push sur la branche principale du dépôt. Cet exercice est intéressant, car il va nous permettre de voir comment utiliser des informations sensibles (nom d’utilisateur, mot de passe) de manière sécurisée au travers d’un pipeline.

Globalement, on peut déployer le site web avec un seul job simple :

stages:
  - deploy

deploy:
  stage: deploy
  image: alpine:latest
  script:
    - apk add --no-cache openssh lftp 
    - rm -rf .git
    - rm .gitlab-ci.yml
    - mkdir ~/.ssh
    - ssh-keyscan -p numero_port_serveur adresse_serveur >> ~/.ssh/known_hosts
    - lftp sftp://nom_utilisateur:$mot_de_passe@$adresse_serveur:numero_port_serveur -e "mirror -R -e ./ /chemin/destination ; quit"

Ce job va :

Peut-être que vous êtes choqué de voir mot_de_passe, nom_utilisateur et peut-être même adresse_serveur écrits en clair dans ce fichier, et vous avez raison ! Tous les utilisateurs ayant accès au dépôt (même en lecture) peuvent lire le fichier de .gitlab-ci.yml. Il est donc totalement exclu d’y placer des informations sensibles ! Alors comment faire ?

GitLab permet d’associer des variables CI/CD à notre dépôt (que seuls les gestionnaires du dépôt peuvent éditer) et d’y faire référence dans nos jobs. Ainsi, à la lecture, selon le niveau de sécurité associé à la variable, personne ne pourra voir le contenu réel de ces données, mais lors de l’exécution, la bonne valeur sera utilisée. De plus, il est possible de configurer le degré de visibilité de ces variables pour faire en sorte qu’elles ne puissent pas être lues dans les logs ni dans l’interface de gestion après avoir été crées (on peut toutefois les supprimer).

Pour créer une variable CI/CD à partir de la page du dépôt, on se rend dans SettingsCI/CD dans le panneau latéral gauche. Ensuite, il faut se rendre dans la section Variables puis Project variables. L’ensemble des variables disponibles sont listées dans la section CI/CD Variables (vous en avez 0 pour le moment). Pour ajouter une nouvelle variable, il suffit alors d’appuyer sur le bouton Add variable à droite.

Lorsqu’on crée une variable, on doit préciser :

Ensuite, pour l’utiliser dans un job, on y fait référence en préfixant sa clé (key) par un $. Par exemple :

stages:
  - exemple

exemple:
  stage: exemple
  image: alpine:latest
  script:
    - connection -u $USER_NAME -p $PASSWORD

USER_NAME et PASSWORD seraient deux variables CI/CD créées dans le dépôt (avec une visibilité “Masked and hidden”).

Bref, avec tout ça, vous êtes prêt à construire votre pipeline !

Concernant les informations pour se connecter au serveur FTP de l’IUT :

  1. Téléchargez le fichier index.php et placez-le dans un nouveau dossier de projet. Il s’agit d’une simple page web affichant “Hello world”.

  2. Initialisez le dépôt Git ce projet en local, puis sur GitLab, créez un nouveau dépôt vierge (privé) dans votre namespace qualite-de-developpement-semestre-3/etu/votrelogin et associez-le à votre dépôt local.

  3. Sur votre dépôt GitLab (de ce nouveau projet), créez quatre nouvelles variables CI/CD secrètes :
    • FTP_HOST : ftpinfo.iutmontp.univ-montp2.fr (adresse du serveur ftp du département informatique de l’IUT)
    • FTP_PORT : 22 (on pourrait éventuellement ne pas mettre le port dans une variable…mais cela renforce la sécurité)
    • FTP_USERNAME et FTP_PASSWORD : votre login et votre mot de passe du département informatique (les mêmes que vous utilisez pour vous connecter à GitLab normalement).
  4. Créez un fichier .gitlab-ci.yml à la racine de votre projet.

  5. Configurez votre pipeline afin d’ajouter un stage (et un job associé) deploy qui se connecte au serveur FTP du département informatique de l’IUT puis publie les fichiers du projet dans le dossier ./public_html/hello_world_site/ (sur le serveur distant). Inspirez-vous des commandes de script données précédemment. Bien sûr, il faudra remplacer les éléments nom_utilisateur, mot_de_passe, adresse_serveur, et numero_port_serveur par vos variables secrètes…

  6. Faites en sorte que ce job ne se déclenche que quand on fait un push sur la branche par défaut (il y a un exemple incluant cette condition au début du TP).

  7. Faites un commit puis poussez le projet sur le dépôt distant. Suivez le déroulement de l’exécution du pipeline. Si tout se passe bien, alors, le site a été déployé et vous pouvez y accéder sur le serveur web de l’IUT : https://webinfo.iutmontp.univ-montp2.fr/~login/hello_world_site/ (en remplaçant login, bien entendu).

  8. Dans votre dépôt local, ajoutez la ligne de code suivante dans le fichier index.php :

     echo "<p>Nous sommes le <strong>{$date->format('j F Y')}</strong> et il est <strong>{$date->format('H:i')}</strong></p>";
    
  9. Poussez cette modification sur le dépôt distant, patientez et vérifiez que votre site a bien été mis à jour à l’issue de l’exécution du pipeline !

Vous pouvez maintenant déployer vos projets web sur leur serveur de destination avec un simple push sur une branche !

Conclusion

À travers ce dernier TP, vous avez donc appris à vous servir de certaines fonctionnalités plus poussées de la plateforme GitLab.

Comme vous l’avez constaté, les techniques de CI/CD présentent beaucoup d’avantages dans le cadre du développement d’un projet. Dans ce TP, nous avons étudié seulement quelques exemples, mais il est possible de faire bien plus ! Vous êtes donc fortement invité à plus amplement explorer et utiliser ces outils afin d’automatiser certaines tâches de vos futurs projets, notamment dans le cadre de vos SAEs qui seront (pour la plupart) hébergées sur le serveur GitLab du département.