Faire une CI LaTeX avec GitLab

ci
intégration continue
git
GitLab
LaTeX
french
français
Auteur·rice
Affiliation

Louis Lacoste

MIA Paris-Saclay, INRAE, AgroParisTech, Université Paris-Saclay

Date de publication

23 septembre 2025

Modifié

12 juin 2026

La CI finale

Voici le contenu d’un de mes fichier .gitlab-ci.yaml

Important

Si vous voyez des incohérences, contactez-moi par mail : louis.lacoste@agroparistech.fr

variables:
  # Version de git utilisée
  GIT_VERSION: v2.30.1

  # Branche cible pour les PDF (modifiable via CI/CD variables)
  PDF_BRANCH: "pdf"

  FILE_NAMES: 2024-2025-rapport-csi 2024-2025-presentation-csi

build_tex:
  stage: build
  image: danteev/texlive:latest # texlive plus inkscape and others
  script:
    - |
      for FILE_NAME in $FILE_NAMES
      do
        echo "Compiling ${FILE_NAME}"
        pdflatex --shell-escape ${FILE_NAME}.tex
        if test -f ${FILE_NAME}.bcf; then
          echo "Found ${FILE_NAME}.bcf, running biber"
          biber ${FILE_NAME}
        fi
        pdflatex --shell-escape ${FILE_NAME}.tex
      done
  after_script:
    - |
      for FILE_NAME in $FILE_NAMES
      do
        echo "============================================"
        cat ${FILE_NAME}.log
        echo "============================================"
      done

  artifacts:
    paths:
      - "*.pdf"
deploy:
  stage: deploy
  image:
    name: alpine/git:${GIT_VERSION}
    entrypoint: [""]

  before_script:
    # Clone le repo dans un dossier temporaire
    - git clone "https://${GITLAB_USERNAME}:${GITLAB_TOKEN}@${CI_SERVER_HOST}/${CI_PROJECT_PATH}.git" "${CI_COMMIT_SHA}"

    # Configure l’identité git
    - git config --global user.email "${GIT_USER_EMAIL:-$GITLAB_USER_EMAIL}"
    - git config --global user.name "${GIT_USER_NAME:-$GITLAB_USER_NAME}"

  script:
    # Déplace les PDFs compilés dans le repo cloné
    - mv *.pdf "${CI_COMMIT_SHA}/"
    - cd "${CI_COMMIT_SHA}"

    # Crée une branche orpheline (vierge, sans historique ni fichiers)
    - git checkout --orphan "${PDF_BRANCH}"
    - git reset --hard

    # Ajoute uniquement les PDF
    - git add -f *.pdf

    # Vérifie s’il y a des changements et push
    - |
      CHANGES=$(git status --porcelain | wc -l)
      if [ "$CHANGES" -gt "0" ]; then
        git commit -m "${COMMIT_MESSAGE:-Updating PDF files}"
        git push --force origin "${PDF_BRANCH}" -o ci.skip
      else
        echo "No PDF changes to commit"
      fi

Détaillons ce qu’il s’y passe !

Les variables

La section variables ci-dessous sert à définir des variables auxquelles nous ferons référence plus tard.

variables:
  # Version de git utilisée
  GIT_VERSION: v2.30.1

  # Branche cible pour les PDF (modifiable via CI/CD variables)
  PDF_BRANCH: "pdf"

  FILE_NAMES: 2024-2025-rapport-csi 2024-2025-presentation-csi
  • GIT_VERSION : spécifie la version de git à utiliser pour l’image Docker que l’on va récupérer.
  • PDF_BRANCH : indique le nom de la branche sur laquelle nos PDF seront publiés.
  • FILE_NAMES : déclare la liste des noms de fichiers (sans les extensions). Au format yaml donc des chaînes de caractères sans guillemets séparés par des espaces

Les étapes

La phase de compilation build_tex

Nous allons détailler l’étape build_tex :

build_tex:
  stage: build
  image: danteev/texlive:latest # texlive plus inkscape and others
  script:
    - |
      for FILE_NAME in $FILE_NAMES
      do
        echo "Compiling ${FILE_NAME}"
        pdflatex --shell-escape ${FILE_NAME}.tex
        if test -f ${FILE_NAME}.bcf; then
          echo "Found ${FILE_NAME}.bcf, running biber"
          biber ${FILE_NAME}
        fi
        pdflatex --shell-escape ${FILE_NAME}.tex
      done
  after_script:
    - |
      for FILE_NAME in $FILE_NAMES
      do
        echo "============================================"
        cat ${FILE_NAME}.log
        echo "============================================"
      done

  artifacts:
    paths:
      - "*.pdf"

On déclare tout d’abord le stage: build pour qualifier l’étape que l’on réalise ici. Il y en a 3 possibles : build, test, deploy (documentation GitLab). Ici nous choisissons build puisqu’il s’agit de la compilation de notre projet.

À la suite nous chargeons une image docker qui contient les outils texlive.

Et enfin la directive script définit en bash l’enchaînement d’étapes que nous réalisons pour compiler le projet.

Exécution conditionnelle de biber

Noter que nous n’avons pas mis d’extensions dans FILE_NAMES afin de pouvoir détecter ici les fichiers bcf caractéristiques de la bibliographie.

Finalement, nous utilisons la directive after_script pour afficher dans les journaux de la CI les fichiers de logs des compilations.

Enfin artifacts spécifie que les artéfacts que l’on veut conserver de la CI sont tous les PDF à la racine du dépôt

La phase de déploiement deploy

deploy:
  stage: deploy
  image:
    name: alpine/git:${GIT_VERSION}
    entrypoint: [""]

  before_script:
    # Clone le repo dans un dossier temporaire
    - git clone "https://${GITLAB_USERNAME}:${GITLAB_TOKEN}@${CI_SERVER_HOST}/${CI_PROJECT_PATH}.git" "${CI_COMMIT_SHA}"

    # Configure l’identité git
    - git config --global user.email "${GIT_USER_EMAIL:-$GITLAB_USER_EMAIL}"
    - git config --global user.name "${GIT_USER_NAME:-$GITLAB_USER_NAME}"

  script:
    # Déplace les PDFs compilés dans le repo cloné
    - mv *.pdf "${CI_COMMIT_SHA}/"
    - cd "${CI_COMMIT_SHA}"

    # Crée une branche orpheline (vierge, sans historique ni fichiers)
    - git checkout --orphan "${PDF_BRANCH}"
    - git reset --hard

    # Ajoute uniquement les PDF
    - git add -f *.pdf

    # Vérifie s’il y a des changements et push
    - |
      CHANGES=$(git status --porcelain | wc -l)
      if [ "$CHANGES" -gt "0" ]; then
        git commit -m "${COMMIT_MESSAGE:-Updating PDF files}"
        git push --force origin "${PDF_BRANCH}" -o ci.skip
      else
        echo "No PDF changes to commit"
      fi

Finalement nous déployons nos PDF. Pour cela on charge une image légère Alpine Linux avec la version Git sélectionnée dans les variables.

Avec la directive before_script on clone le dépôt.

Pour créer le token GitLab

Notez dans le git clone que nous employons une variable GITLAB_TOKEN, celle-ci est a créer au préalable et à déclarer dans le dépôt.

Pour cela :

  1. Rendez-vous dans les paramètre de votre dépôt.

Dans les menus de gauche, déplier “Settings” et rendez-vous dans “Access tokens”
  1. Ici ajoutez un nouveau token.

Cliquer sur “Add new token”
  1. En configurant les permissions read_repository et write_repository afin de pouvoir cloner et pousser nos fichiers. Puis cliquer sur “Create project access token”.

  1. Votre token est maintenant affiché, copiez le car il ne sera pas raffiché après.

  2. Rendez-vous maintenant dans CI/CD settings.

  1. Créer maintenant la variable en cliquant sur “Add variable”, nommez la GITLAB_TOKEN, dans “value” ajoutez le token copié.

La suite du script déplace les PDF dans le dépôt cloné, crée la branche de publication et ajoute les pdf.

Vous avez normalement maintenant une CI de compilation et publication de PDF ! Maintenant vous pouvez faire référence dans votre README.md à vos PDF en saisissant un lien du type :

https://mongitlab.com/monnomutilisateur/mondepot/-/raw/monpdf.pdf

qui permet d’afficher directement dans le navigateur le produit de la compilation. 😄