mdbook avec >GitLab CI

Ce site est écrit en CommonMark, la gestion de version est fait avec Git et le rendu HTML est fait avec mdbook, qui génère un site GitLab Pages static qui est aussi déployé via un FTP chez mon hébergeur.

La description du build est presque entièrement gérée par le fichier .gitLab-ci.yml dans la racine du projet. C'est le fichier qui configure les Jobs exécutés par GitLab CI.

Voici son contenu actuel (disponible comme l'intégralité des sources du site sur GitLab

stages:
    - deploy

pages:
  stage: deploy
  environment:
    name: site public
    url: https://www.tregan.fr
  image: rust:latest
  variables:
    CARGO_HOME: $CI_PROJECT_DIR/cargo
  before_script:
    - export PATH="$PATH:$CARGO_HOME/bin"
    - mdbook --version || cargo install --debug mdbook
    - apt-get update -qy
    - apt-get install -y lftp
  script:
    - mdbook build -d public
    - lftp -e "open $FTP_SERVER; user $FTP_USERNAME $FTP_PASSWORD; mirror -R public/ $FTP_DEST_DIR; bye"
  only:
    - master
  artifacts:
    paths:
      - public
  cache:
    paths:
      - $CARGO_HOME/bin

Voici à quoi servent chaque ligne :

stages:
    - deploy

On définit une liste ordonnée de stages. Un stage permet de regrouper un ensemble de jobs (définis juste après) qui pourront s'exécuter en parallèle. Une fois l'ensemble des jobs d'un stage finis, le stage suivant est traité. Nous n'avons pas de jobs parallélisables et définissons donc un seul stage. On aurait pu sauter cette étape, puisqu'en l'absence de définition il y a une liste par défaut (.pre, build, test, deployet .post).

pages:
  stage: deploy

On définit ensuite un Job appelé pages. Ce nom de job spécial fait que s'il existe un répertoire nomé public et que l'on a définit un artéfact pointant sur ce répertoire, son contenu sera publié sur github pages

  environment:
    name: site public
    url: https://www.tregan.fr

Ce job déploie mon site public, visible à l'adresse https://www.tregan.fr. En donnant un nom et une URL à GitLab CI, celui-ci permettra de voir tous les déploiements qui ont été effectués en se rendant sur la page GitLab du projet, dans opérations -> Environments. L'URL permet de se rendre sur le site en cliquant sur la première icone de la ligne du tableau (Open live environment). D'autres options permettent de préciser à GitLab CI comment démarrer, stopper ou redémarrer un environnement et il devient possible de le faire depuis cette page.

  image: rust:latest

le build sera construit à partir de l'image Docker rust:latest qui fournit un environnement de compilation Rust à jour.

  variables:
    CARGO_HOME: $CI_PROJECT_DIR/cargo

On définit une variable qui donne le nom de chemin de Cargo sur cette image.

  before_script:
    - export PATH="$PATH:$CARGO_HOME/bin"
    - mdbook --version || cargo install --debug mdbook
    - apt-get update -qy
    - apt-get install -y lftp

Avant le build:

  • On ajoute le répertoire de Cargo au Path
  • Si mdbook n'est pas installé, on l'installe avec Cargo.1
  • On installe lftp (qui servira a uploader les fichier sur le serveur FTP du serveur Web, inutile si on déploie uniquement sur GitLab Pages)
  script:
    - mdbook build -d public
    - lftp -e "open $FTP_SERVER; user $FTP_USERNAME $FTP_PASSWORD; mirror -R public/ $FTP_DEST_DIR; bye"

La phase de build elle même :

  • On génère le HTML du livre avec mdbook, en s'assurant de mettre la sortie dans public/
  • On envoie avec LFTP le contenu du répertoire public. Les variables suivantes sont définies dans le projet GitLab, dans settings -> CI/CD -> Variables (expand) -> Add Variable , en s'assurant des les mettres en protected (gestion des droits) et masked (effacement des logs quand c'est possible)
    • FTP_SERVER : Adresse du serveur FTP (e.g. ftp.monsite.fr)
    • FTP_USERNAME : Nom du compte FTP (e.g. webmaster)
    • FTP_PASSWORD : Mot de passe du compte FTP (e.g. a3eRrttyf35WxCvBdRy44fS)
    • FTP_DEST_DIR : Chemin du FTP dans lequel copier les fichiers (e.g. www/)
  only:
    - master

On n'effectue le build que si le code a été poussé sur la branche master

  artifacts:
    paths:
      - public

On précise qu'il y a un livrable constitué du contenu du répertoire public. Cela permettra de récupérer le livrable sur la ligne du pipeline correspondant à l'éxecution du job sur la page GitLab du projet dans CI/CD -> Pipelines, mais aussi ce confirmer qu'on veut une mise en ligne sur GitLab Pages dans le cas spécial du job nommé pages. Les artifacts servent aussi à passer le résultat d'un stage au stage suivant, mais nous ne l'utilisons pas ici.

  cache:
    paths:
      - $CARGO_HOME/bin

Enfin, on précise que le répertoire $CARGO_HOME/bin et son contenu peuvent être conservés d'une execution de job à l'autre. Si c'est le cas, la ligne du before_script mdbook --version || cargo install --debug mdbook verra mdbook --version retourner 0 et n'exécutera pas le cargo install -- debug mdbook


1

On pourrait se content de télécharger une version pour l'architecture utilisée pour éviter de télécharger et compiler mdbook et ses dépendances. Cependant, recompiler assure la compatibilité du script quelle que soit l'architecture, et dans les lignes suivantes nous ferons en sorte que le binaire de mdbook soit mis en cache, ce qui est possible puisque nous sommes dans la phase before_script