Notebook et programmation lettrée
  • Code source
  • Ouvrir une issue
  1. Pratique individuelle
  2. Forge logicielle
  3. CI/CD
  • Pratique individuelle
    • Introduction
      • Présentation
      • Environnement
      • Données
    • Notebook
      • Opt1 - Quarto + R
      • Opt2 - Jupyter + Python
    • Forge logicielle
      • Création dépôt
      • CI/CD
      • .gitignore
  • Pratique collective
    • Présentation
    • Environnement
    • Exercice
  • Pour aller plus loin…
    • CI/CD avancé
    • Environnements virtuels
  1. Pratique individuelle
  2. Forge logicielle
  3. CI/CD

Intégration et déploiement continu

Pour terminer, le fichier HTML généré en local et push sur votre repository GitLab, peut être déployé (mis en ligne) sur le web via une GitLab Pages.

Pour cela nous allons utiliser un Runner Gitlab, c’est à dire un (ou plusieurs) serveurs à qui on va déléguer une partie du travail. Comme déjà abordé dans le cours de Franck P, ce Runner va être le pilier opérationnel qui va permettre la mise en place d’une stratégie CI/CD, propre à la culture DevOps, c’est à dire la jointure entre des équipes de développements logiciel avec des équipes plus aguéris au déploiement, souvent des administrateurs systèmes. C’est une approche interdisciplinaire, qui vise une meilleures coopération des équipes disposant de pratiques et de cultures différentes, qui se concrétise au travers de l’automatisation des processus.

En théorie tout le monde est gagnant :

  • la qualité du code est meilleure (robustesse, portabilité, stabilité)
  • le déploiement est simplifié pour les développeurs, pour les utilisateurs
  • les équipes sont soulagées par l’automatisation des processus
  • les équipes gagnent en autonomie, en compétences et en responsabilité

En soit, ces méthodes et ces outils participe des bonnes pratique, et participe grandement de la reproductibilité au sens computationel.

Note

;TLDR : Concrétement, il s’agit de l’automatisation d’une pratique de vérification opérant à chaque modification des sources du logiciel sur la stabilité, la robustesse, les performances, la portabilité, etc.

Note

Quelques définitions pour les plus courageux/seuses :

CI ou /Continuous Intégration/

Martin Fowler, développeur bien connue pour ces livres dans le domaine du développements logiciels, donne la définition suivante de l’Intégration Continue sur son bliki (CI) :

Continuous Integration is a software development practice where each member of a team merges their changes into a codebase together with their colleagues changes at least daily. Each of these integrations is verified by an automated build (including test) to detect integration errors as quickly as possible. Teams find that this approach reduces the risk of delivery delays, reduces the effort of integration, and enables practices that foster a healthy codebase for rapid enhancement with new features.

Gitlab en donne la définition suivante sur la page de son CI/CD :

Continuous integration is the practice of integrating all your code changes into the main branch of a shared source code repository early and often, automatically testing each change when you commit or merge them, and automatically kicking off a build. With continuous integration, errors and security issues can be identified and fixed more easily, and much earlier in the development process.

By merging changes frequently and triggering automatic testing and validation processes, you minimize the possibility of code conflict, even with multiple developers working on the same application. A secondary advantage is that you don’t have to wait long for answers and can, if necessary, fix bugs and security issues while the topic is still fresh in your mind.

Common code validation processes start with a static code analysis that verifies the quality of the code. Once the code passes the static tests, automated CI routines package and compile the code for further automated testing. CI processes should have a version control system that tracks changes so you know the version of the code used.

CD ou /Continuous Delivery/

Pour Martin Fowler, la capacité d’être en /Continuous Delivery/ (CD), est souvent associée à l’Intégration Continue (CI) car :

Continuous Delivery is a software development discipline where you build software in such a way that the software can be released to production at any time.

You’re doing continuous delivery when: 1

  • Your software is deployable throughout its lifecycle
  • Your team prioritizes keeping the software deployable over working on new features
  • Anybody can get fast, automated feedback on the production readiness of their systems any time somebody makes a change to them
  • You can perform push-button deployments of any version of the software to any environment on demand

Une définition équivalente donnée par Gitlab sur la page défié est la suivante :

As the name suggests, continuous delivery (CD) is a software development practice that works in conjunction with continuous integration to automate the application release process. Software developers release updates to code in short but continuous cycles using automation to speed the release. CD includes all the steps in the production cycle - build, test, configure and deploy. The ultimate goal is to get software into users’ hands.

CD can be thought of as an extension of continuous integration, at times referenced together as CICD, which is the practice of integrating code into a shared repository and building/testing each change as soon as possible, automatically, and typically several times a day.

Once continuous integration builds and tests code in a shared repository, continuous delivery takes over during the final stages to ensure software releases are low-risk, consistent, and repeatable.

Tout se fait à partir d’un fichier .gitlab-ci.yaml écrit dans un langage de script yaml, qui doit être initialisé dans le dépôt à automatiser.

Dès lors que ce fichier existe, le CI/CD va pouvoir se mettre en place à partir des instructions/commandes qui sont décrites dans le fichier.

  • Chaque Job est indépendant et peut être executé par un runner disponible.
  • Les Jobs peuvent générer des artifacts qui peuvent être ensuite renvoyé, soit à d’autres Jobs, soit à la forge
  • Le Runner est un serveur, il peut être partagé (shared runners) ou privé (private runners). Il execute le job qu’il aura récupérer.
  • Les Jobs sont organisés en Pipeline, il s’agit d’une série de Jobs qui peuvent être executés sur un ou plusieurs Runners.
  • Le /Stage/ est une des partie du Pipeline, il peut contenir plusieurs Jobs executés en parallèle.
Important

Les Runners ne sont pas activés par défaut sur la forge GridCad.

Il faut se rendre dans la partie Settings > CI/CD > Runners pour activer, en fonction de vos besoins :

  • l’instance runners mutualisé (tout le monde y a accès)
  • un des projects runners (accessible seulement au projet)

Le sujet sera abordé en détail demain par Arnaud L, la containerisation est un élément important dans le CI/CD. Il est en effet possible de faire tourner les scripts dans le contexte d’image Docker, par exemple en indiquant en entête du fichier .gitlab-ci.yaml le mot clef image:xxxx ou xxx est le nom de l’image Docker à employer pour l’execution du script.

Déploiement du notebook

Pour cela, il est nécessaire d’ajouter un fichier de configuration CI/CD .gitlab-ci.yml à la racine du dépôt GitLab. Ce fichier, structuré en YAML, permet d’indiquer une pipeline de jobs qui peut s’enclencher lors d’une action spécifique, par exemple, à chaque nouveau push sur le dépôt GitLab concerné.

Sur la page de votre dépôt GitLab :
1. Cliquez sur Build/Jobs
2. Cliquez sur “Create CI/CD configuration file”, puis sur “Configure pipeline”
3. Copiez-collez le code ci-dessous en écrasant l’existant :

  • R & Quarto
  • Python & Jupyter
pages:
    stage: deploy
    script:
        - mkdir public
        - mv -v img public/
        - mv -v *.html public/
        - mv -v index_files public/
        - echo "Votre document a été déployé à ce lien $CI_PAGES_URL"
    artifacts:
        paths:
        - public
    only:
    - main


Exemple :

Avertissement

Pour que le déploiement fonctionne avec cette pipeline, il est impératif que le fichier HTLM soit nommé index.qmd

stage: deploy
  script:
  - mkdir public
  - cp -R _build/html/* public/
  - echo "Votre document a été déployé à ce lien $CI_PAGES_URL"
  artifacts:
    paths:
    - public
  only:
  - main


  1. Cliquez sur “Commit changes”. Pas besoin de faire un push car le commit est directement réalisé sur la plateforme GitLab.

Le job indiqué dans ce fichier (ici un déploiement) s’éxécute à chaque nouveau push. Si le job s’éxécute correctement, l’icône ✅ apparait :

Vous pouvez cliquer sur cet icône pour visualiser l’exécution des jobs réalisés, ex :

Après quelques secondes, votre notebook compilé sera déployé sur le web via une GitLab page.
L’url d’accès est indiquée dans la section “Deploy > Pages”. Exemple :

  1. Cliquez sur l’URL… 😎


Compilation + déploiement du notebook

Il est également possible d’ajouter un job d’éxécution du notebook, c’est à dire de faire compiler le notebook par la forge GitLab.

Cela permet par exemple, dans le cadre de travaux collaboratifs de ne pas être dépendant des environnements personnels de chacun·e et de tous faire compiler dans un même environnement installé sur la forge GitLab.

Pour cela, il suffit de fournir un fichier .gitlab-ci.yml plus dense, qui installe tout l’environnement (système exploitation, R/python, Quarto, packages…) qui permettront à la forge GitLab de compiler votre notebook Quarto à chaque nouveau push.

C’est un peu comme si vous deviez faire en sorte que votre notebook puisse marcher sur la machine de votre voisin, sauf que dans le cas du Runner sur le gitlab nous partons d’un environnement initial que l’on choisit.

L’environnement d’execution pour R/Quarto et Python/Myst étant différent, le .gitlab-ci.yml est forcément différent.

Important

Toutes les commandes qui sont décrites dans le fichier .yaml vont s’executer sur une copie de votre dépot git, cela n’a pas d’impact sur le dépôt en lui-même. Cette execution se fait dans un environnement isolé et temporaire.

  • R & Quarto
  • Python & Jupyter

Pour avoir quelque chose de clef-en-main, le mieux c’est d’utiliser une image existante, développé et maintenue par la communauté, par exemple Rocker :

Si vous voulez quelque chose de stable sans avoir à gérer les dépendances système (cad. les librairies système qui doivent être installé pour que certain packages R fonctionne), et quitte à ne pas être sur les derniers packages, alors on pourra tenter les images rocker/r-ver basé sur Ubuntu LTS.

Hérité des images r-ver, l’image rocker/geospatial possède la plupart des librairies nécessaires pour faire de la géographie avec R.

Enfin, ces versions sont préconfiguré avec RPSM pour servir des binaires linux des packages ce qui rend l’execution très rapide sur la forge. Pas besoin de compiler les packages. Attention toutefois, cette image pèse quand même un certain poids : 1.55 Gb compressé.

Modifiez le fichier .gitlab-ci.yml en copiant-collant les lignes de code ci-dessous :

image: rocker/geospatial:4.5

before_script:
  - apt-get update && apt-get install -y curl wget git pandoc
  - R -e "install.packages(c('quarto', 'sf', 'tidygeocoder', 'mapview', 'osrm', 'DT'))"
 
pages:
  stage: deploy
  script:
    - rm -rf index_files/ index.html
    - quarto render index.qmd
    - mkdir public
    - mv biblio.bib public/
    - mv -v img public/
    - mv -v *.html public/
    - mv -v index_files public/
    - echo "Votre document a été déployé à ce lien $CI_PAGES_URL"
  artifacts:
    paths:
    - public
  only:
  - main

Une fois ce fichier commit dans votre dépôt, vous pouvez vous rendre sur la page de votre projet Gitlab, et voir ce qui se passe pendant l’execution du CI dans >Project > Build > Jobs

Pour cela cliquez sur le dernier job listés avec un status Running #numerodejob: pages

Note

Si tout se passe bien, le job devrait mettre à peine quelques seconde à s’executer.

Pourquoi ?

Les images de Rocker sont préconfigurés pour récupérer, sous Linux, des binaires précompilés accessibles à la communautés, cela via les serveurs Posit :

  • https://docs.posit.co/rspm/admin/serving-binaries.html
  • https://posit.co/blog/introducing-portable-linux-r-binary-packages/

Sur le plan de la gouvernance du langage R, mais aussi de la reproductibilité à terme des images, ce n’est pas une information anodine.

Il n’existe pas d’image Docker équivalente à celle de Rocker en Python, c’est à dire avec les librairies et les dépendances géospatiales dont nous aurions besoin, donc j’en ai fait une pour ce TP afin de simplifier le déploiement.

image: sreycoyrehourcq/soshs-python-jupyterbookv2:latest

pages:
  stage: deploy
  script:
    - export BASE_URL="$CI_PAGES_URL"
    - jupyter-book build -d --execute --html
    - mkdir public
    - cp -r _build/html/* public
    - echo "Votre document a été déployé à ce lien $CI_PAGES_URL"
  artifacts:
    paths:
    - public
  only:
  - main

Vous pouvez trouver plus d’information également dans la partie Pour aller plus loin.

 

Produit par le GT Notebook avec Quarto - 2025