comment créer un site statique depuis un repository sur Gitlab"

Damien Belvèze

20250222

Choix de la forge

Mon choix a été de délaisser github, forge propriétaire appartenant à Microsoft et donc aux mains d’un des principaux acteurs technosuprémacistes qui ont prêté allégeance sous une forme ou sous une autre à Donalc Trump J’ai choisi d’utiliser une forge qui fonctionne avec le logiciel libre Gitlab. L’association Framasoft met à disposition son gitlab à toutes celles et ceux qui souhaitent faire l’expérience de gitlab et cherchent un lieu pour héberger leurs projets. Ce gitlab est disponible en ligne sous le nom de framagit

Se créer un compte sur Framagit

Aucune condition requise, si ce n’est disposer d’une adresse mail. Considérer la possibilité de protéger le compte au moyen d’une double-authentification. J’utiliser l’application Twillio (ex-Authy) qui permet de gérer cette authentification de deuxième niveau avec plusieurs outils dont framagit. Une fois qu’on a créé un compte, pour voir ses projets (pour l’instant, il n’y en a pas, une fois authentifié.e, cliquer sur son profil, puis cliquer sur “personal projects”) Créer un projet sans template. On obtient ainsi une adresse de type git@framagit.org:user/project_name.git qui va nous permettre d’envoyer sur Framagit le projet qu’on va d’abord créer en local. S’assurer que ce répertoire est public et accessible à tous.

Créer un projet

En local, par exemple sur son bureau, créer un dossier qui correspondra au projet (par exemple site_statisque) Aller à la racine de ce dossier.

Créer un document en markdown avec le nom index.md ; ce document est nécessaire pour déployer un site web depuis un répertoire sur gitlab. Inscrire quelques information sur ce fichier, par exemple, recopier du texte depuis le présent document.

Ce fichier servira de page d’accueil au futur site, voire de page unique, si le site en plus d’être statique au point de se déployer sur une seule page.

Créer les fichiers et les dossiers périphériques

Si on veut gérer des références bibliographiques, on a besoin de plusieurs fichiers : un fichier .bib qui comporte les références à citer en format bibtex un fichier .csl qui comporte le style bibliographique à utiliser.

Si on veut ajouter un peu de mise en page à son site, on peut à cette fin créer un fichier css que l’on va laisser vierge pour l’instant.

Les images qui iront agrémenter le site, iront dans un dossier qui s’appellera images.

Nous partons du principe ici que vous utilisez Git depuis un terminal pour envoyer les textes écrits en local vers le serveur de Framagit.

Ouvrir un terminal, et Initier un répertoire git au sein de ce dossier Intégrer les images dans l’arbre de git, committer, et relier le contenu de ce répertoire à l’adresse du projet :


git init 
git add * 
git commit -M main 
git remote add main git@framagit.org:user/project_name.git
git push -u --set-upstream main
git push -u origin

Les dossiers locaux vont être envoyés dans la branche principale (“main”) du repository dans gitlab.

créer un pipeline pour l’intégration continue

Notre site sera constitué de pages rédigées en markdown qui seront converties à la volée en pages html, à commencer par la page index.md qui est nécessaire pour le déploiement de ce site. Il nous faut créer le workflow qui rendra cela possible. Pour ce faire, lorsque le projet a été sélectionné sur la forge Gitlab, cliquer sur build puis sur pipeline editor. C’est ici que nous allons éditer le fichier caché .gitlab-ci.yml qui contiendra le workflow de transformation de nos fichiers.

“ci” signifie dans le nom de ce fichier continuous integration ; il s’agit d’un fichier formaté en YAML, il est donc très important que les indentations soient respectées.

Par défaut (ce comportement est modifiable), un workflow est activé à chaque push d’un commit. Le déploiement d’un site statique depuis un ensemble de fichiers dans une forge se fait en envoyant ces fichiers dans un répertoire public

workflow pour le déploiement d’un site à partir de fichiers html

Si on écrivait directement nos pages en html, on pourrait se contenter de ce workflow :

pages:
  stage: deploy #il s'agit de déployer un site à partir de fichiers
  script:
  - mkdir .public # crée le dossier caché .public
  - cp -r * .public # copie tous les dossiers et fichiers du repository dans le fichier caché .public
  - mv .public public # déplace tous les fichiers contenus dans le dossier caché public vers le dossier public
  artifacts: # indique où se trouve le résultat du script
    paths:
    - public 
  only:
  - main # indique que seule la branche *main* est concernée par ce workflow

workflow pour le déploiement d’un site à partir de fichiers en markdown

En ce qui nous concerne, nos pages sont rédigées en makrdown, qui plus est, elles comportent des références bibliographiques en bibtex, possiblement issues de Zotero (via le plugin betterbibtex), donc on a besoin de deux choses supplémentaires : - un outil de conversion à la volée de fichiers écrits en markdown en fichiers html
- un outil permettant de gérer les références bibliographiques

Pandoc et son package citeproc permettent de traiter ces deux actions.

Le workflow s’exécute grâce à des runners qui sont propres à la forge (on peut en changer, mais on va garder le runner par défaut) Ces runners vont appeler des images disponibles en ligne qui vont permettre de mobiliser ces composants sans que nous ayons besoin de les avoir téléchargés sur notre machine en local. Toute l’opération se fait au niveau de la forge.

On peut utiliser des distributions entières de Linux (ubuntu) ou des images de ruby ; en ce qui nous concerne, nous n’avons pas besoin de mobiliser des images de cette nature qui nous permettraient de charger des packages supplémentaires à utiliser dans le script. On a juste besoin de faire intervenir une image qui comporte le code source de pandoc.

Des images de ce type est disponible pour des intégrations continues sous gitlab ou github pages. Nous retenons celle-ci : pandoc-latex disponible depuis l’entrepôt de Fastexitlane qui contient en outre une distribution de Latex qui nous sera utile plus tard pour convertir en même temps les fichiers markdown en pdf.


image: fastexitlane/pandoc-latex #choix de l'image et du répertoire où la trouver

pages:
  stage: deploy #il s'agit toujours de déployer un site à partir de fichiers
  script:
    - mkdir .public # crée comme plus haut le fichier caché .public
    - cp -r * .public # même processus que tout à l'heure
    - for file in .public/*.md; do pandoc "$file" --self-contained --css=style.css --extract-media ./images --bibliography=biblio.bib --csl=nature.csl --citeproc -o "${file%.*}.html"; done # on analyse cette commande plus bas
    - mv .public public # même mouvement que tout à l'heure
  artifacts: # inchangé
    paths:
      - public
  only:
    - main

voici une analyse détaillée de cette commande pandoc :

Le site est désormais déployé, les artifacts résultant de cette conversion sont disponibles en ligne à l’adresse indiquée dans Deploy / Pages. Cette adresse se termine par “frama.io”. Si on la met dans un navigateur, on pourra voir le contenu formaté en html du fichier index.md.

conversion avec un output en plusieurs formats (html et pdf)

Supposons que nous souhaitions à présent convertir les fichiers en markdown en même temps en html et en pdf. Une conversion d’un fichier en pdf avec pandoc requiert LaTeX Il se trouve que l’image que nous utilisons comporte non seulement pandoc mais aussi LateX (pandoc-latex), en l’occurrence, il s’agit d’une version complète de la distribution Texlive

Pour chaîner les deux types de conversion on va utiliser le pipe (|) et ajouter une référence à un package de Texlive pour rendre possible la conversion en LaTex (–pdf-engine=xelatex)

image: fastexitlane/pandoc-latex #choix de l'image et du répertoire où la trouver

pages:
  stage: deploy #il s'agit toujours de déployer un site à partir de fichiers
  script:
    - mkdir .public # crée comme plus haut le fichier caché .public
    - cp -r * .public # même processus que tout à l'heure
    - for file in .public/*.md; do 
        pandoc "$file" --self-contained --css=style.css --extract-media ./images --bibliography=biblio.bib --csl=nature.csl --citeproc -o "${file%.*}.html" | pandoc "$file" --self-contained --css=style.css --extract-media ./images --bibliography=biblio.bib --csl=nature.csl --citeproc --pdf-engine=xelatex -o "${file%.*}.pdf"; done # on analyse cette commande plus bas
    - mv .public public # même mouvement que tout à l'heure
  artifacts: # inchangé
    paths:
      - public
  only:
    - main

Le résultat est visible dans https://…..frama.io/index.pdf

séparer les outputs et réunir les PDF produits de la conversion avec Pandoc dans un dossier distinct

Si maintenant, nous souhaitons que les fichiers en pdf résultant de ces conversions aillent dans un dossier à part (par exemple un dossier intitulé pdf), il ne suffira pas après -o de rajouter pdf au chemin ("pdf/${file%.}.pdf"). Le runner indique une erreur. Il faut créer dans .public un dossier pdf. Cela requiert l’argument -p après mkdir Pour éviter les problèmes de chemins de localisation des pdf, on peut utiliser la fonction basename* En effet sans cette fonction la variable *{file} va comporter également le chemin (pdf/file) et pandoc va tenter de créer un fichier ./public/fichier.pdf dans le répertoire .public/pdf, ce qui empêchera le script de s’exécuter jusqu’au bout. Il faut donc que ${file} ne comporte que le nom de fichier (fichier.pdf) et non le chemin relatif afin que fichier/pdf soit bien créé là où on s’attend à ce qu’il le soit, c’est à dire sous public/pdf/.

Voici le .gitlab-ci.yml revu dans ce sens :


image: fastexitlane/pandoc-latex #choix de l'image et du répertoire où la trouver

pages:
  stage: deploy #il s'agit toujours de déployer un site à partir de fichiers
  script:
    - mkdir -p .public/pdf
    - cp -r * .public # même processus que tout à l'heure
    - for file in .public/*.md; do 
        pandoc "$file" --self-contained --css=style.css --extract-media ./images --bibliography=biblio.bib --csl=nature.csl --citeproc -o "${file%.*}.html"| pandoc "$file" --self-contained --css=style.css --extract-media ./images --bibliography=biblio.bib --csl=nature.csl --citeproc --pdf-engine=xelatex -o ".public/pdf/$(basename "${file%.*}").pdf"; done # on analyse cette commande plus bas
    - mv .public public # même mouvement que tout à l'heure
  artifacts: # inchangé
    paths:
      - public
  only:
    - main

Le résultat sera dorénavant visible dans https://…..frama.io/pdf/index.pdf

On peut également faire plus simple en évitant la double commande pandoc et en redoublant simplement l’argument “output” de pandoc (-o) pour obtenir les deux résultats attendus, le ficher html dans le répertoire public et le fichier pdf dans le répertoire public/pdf :

pandoc "$file" --self-contained --css=style.css --extract-media ./images --bibliography=biblio.bib --csl=nature.csl --citeproc -o "${file%.*}.html"| pandoc "$file" --self-contained --css=style.css --extract-media ./images --bibliography=biblio.bib --csl=nature.csl --citeproc --pdf-engine=xelatex -o ".public/pdf/$(basename "${file%.*}").pdf"; done

Traitement des blocs de code

On peut remarquer que la conversion apporte une coloration syntaxique aux blocs de code, mais tronque pas les lignes des commandes qui y figurent.

Or les lignes qui concernent pandoc sont fort longues et devraient apparaître en entier dans le PDF

Bien sûr, on pourrait disposer verticalement les arguments de pandoc pour raccourcir la longueur de cette ligne de sorte à ce que cette commande ne soit pas tronquée, comme on le fait parfois dans le terminal en utilisant le signe  pour aller à la ligne et montrer que ce retour à la ligne ne précède pas une nouvelle commande mais juste la continuation de la première :


image: fastexitlane/pandoc-latex #choix de l'image et du répertoire où la trouver

pages:
  stage: deploy #il s'agit toujours de déployer un site à partir de fichiers
  script:
    - mkdir -p .public/pdf
    - cp -r * .public # même processus que tout à l'heure
    - |
      for file in .public/*.md; do 
        pandoc -f markdown "$file" --self-contained \
          --css=style.css \
          --extract-media ./images \
          --bibliography=biblio.bib \
          --csl=nature.csl \
          --citeproc \
          --pdf-engine=xelatex \
          -o "${file%.*}.html" \
          -o ".public/pdf/$(basename "${file%.*}").pdf"
      done
  artifacts:
    paths:
      - public
  only:
    - main

Mais ça ne semble pas fonctionner avec la version pandoc-latex que nous utilisons ici

On va utiliser un composant de LaTeX pour gérer cela, le package listings qu’on appelle avec l’argument –listings Cet argument permet d’injecter dans l’entête du fichier (-H) le contenu d’un fichier écrit en LateX qui précise comment le bloc de code doit apparaître. Nous créons ce fichier sous le nom de listings-setup.tex et le mettons à la racine du dossier.

Puis nous ajoutons l’argument listings de la manière suivante :

pandoc "$file" --self-contained --css=style.css --extract-media ./images --bibliography=biblio.bib --csl=nature.csl --citeproc --pdf-engine=xelatex --listings -H listings-setup.tex -o "${file%.*}.html" -o ".public/pdf/$(basename "${file%.*}").pdf"; done # on analyse cette commande plus bas

Lorsqu’on valide la modification du workflow et que celui-ci s’exécute, c’est avec succès. Par ailleurs, le pdf présente bien des blocs de code qui ne sont plus tronqués.

Par contre, 1. il n’y a plus de coloration syntaxique 2. le fichier html n’est plus disponible - il va falloir revenir à la double commande pandoc chaînée avec un pipe

Appliquer un nom de domaine

Références