GitLab-CI für LaTeX

Continuous Integration für LaTeX mit GitLab

Einleitung

Wir arbeiten sehr viel mit LaTeX. Unsere LaTeX-Dokumente verwalten wir, genauso wie unseren Source Code, mit Git, im speziellen mit GitLab. Damit die generierten PDF-Dateien auch ohne aktive LaTeX-Installation immer verfügbar sind, haben wir eine CD-Pipeline mit GitLab CI/CD eingerichtet.

Die einfache Variante

Im einfachsten Fall, handelt es sich um ein einzelnes Dokument in einem Repository, das kompiliert und bereitgestellt werden soll.

.
├── .gitlab-ci.yml
├── main.tex
├── main.tex

Es muss nur eine Datei mit dem Namen .gitlab-ci.yml im Root-Directory des Git-Repositories mit folgendem Inhalt erstellt werden:

image: blang/latex

build:
  script:
    - pdflatex -interaction nonstopmode main.tex
  artifacts:
    paths:
      - "main.pdf"

Das war’s schon. Jetzt wird mit jedem Commit eine neue Version des Dokumentes kompiliert. Falls das verwendete Dokument anders heißt, muss main.tex und main.pdf natürlich ersetzt werden. Um jeweils die neueste Version der PDF abzurufen, bietet GitLab spezielle Links an. Der Link ist wie folgt aufgebaut:

https://gitlab.com/<namespace>/<project>/-/jobs/artifacts/<ref>/raw/<path_to_file>?job=<job_name>

ref ist hier der Branch-Name. Um die neueste PDF-Datei ./main.pdf aus dem Repository devsaur/example-repo im master-Branch herunterzuladen, würde also folgender Link ausreichen:

https://gitlab.com/devsaur/example-repo/-/jobs/artifacts/master/raw/main.pdf?job=build

Diesen Link kann man nun mit dem Titel Aktuelle PDF in die README.md packen, sodass jeder immer einen aktuellen Build zur Verfügung hat.

Mehrere LaTeX-Projekte in einem Repository

Wenn in einem Repository mehrere LaTeX-Projekte verwaltet werden, muss eine andere Lösung her! Wir wollen nicht jedes mal unsere .gitlab-ci.yml anpassen, wenn ein weiteres Projekt hinzukommt. Stattdessen soll jeder Unterordner, in dem eine Makefile liegt, als ein Projekt behandelt werden. Unsere Ordnerstruktur sieht dann wie folgt aus (unwichtige Dateien ausgeblendet):

.
├── projekt1
│   ├── main.pdf
│   ├── main.tex
│   └── Makefile
├── projekt2
│   ├── main.pdf
│   ├── main.tex
│   └── Makefile
├── projekt3
│   ├── main.pdf
│   ├── main.tex
│   ├── Makefile
├── .gitlab-ci.yml

Jedes der LaTeX-Unterprojekte sollte eine Makefile haben. Das ist ohnehin sehr zu empfehlen, denn durch eine Makefile wissen andere immer genau, wie sie ein Projekt zu kompilieren haben. Wir verwenden folgende Makefile für unsere Projekte:

TEX = pdflatex -interaction nonstopmode

PAPER = main.tex

all: $(PAPER)
	$(TEX) $(PAPER)
	$(TEX) $(PAPER)

view: $(PAPER)
	open $(PAPER)

spell::
	ispell *.tex

clean::
	rm -fv *.aux *.log *.bbl *.blg *.toc *.out *.lot *.lof $(PAPER).pdf $(SUPP).pdf $(BUNDLE)

Die .gitlab-ci.yml sieht nun so aus (vorausgesetzt, dass alle Unterprojekte eine Datei mit dem Namen main.pdf ausgeben):

image: blang/latex

build:
  script:
    - find . -type f -name Makefile -execdir make all \;
  artifacts:
    paths:
      - "*/main.pdf"

Wir hoffen wir konnten helfen! Sollte etwas unklar geblieben sein, freuen wir uns über eine Rückmeldung an blog@devsaur.de!

Lukas Mertens
Geschäftsführer

24.03.2020