Blog

Wie nutzen wir Gitlab?

01.09.2020 // Gregor Goldbach

Gitlab ist eine webbasierte Plattform für die kontinuierliche Auslieferung von Software. Diese Plattform bietet viele Funktionen, die über die reine Softwareentwicklung und das Deployment hinausgehen. Wir erstellen damit Perl-Distributionen, Docker-Images sowie Dokumentation.

Hauptteil

Gitlab ist eine webbasierte Plattform für die kontinuierliche Auslieferung von Software. Unter anderem integriert es Komponenten wie ein Wiki, ein Ticket-System und die Unterstützung des Versionskontrollsystems Git. Außerdem bietet es eine automatisierte Ausführung von beliebigem Code in Docker-Images an, die von Commits ausgelöst werden können.

Welche Befehle ausgeführt werden, kann man in einer YAML-Datei beschreiben. Dort wird auch beschrieben, welches Docker-Image dafür verwendet werden soll und unter welchen Bedingungen die Befehle ausgeführt werden sollen.

Wie wir bei Perl-Services diese Möglichkeiten nutzen, beschreibe ich in diesem Artikel.

Automatisiertes Erstellen von Perl-Distributionen

Als wir begonnen haben, Gitlab zu evaluieren, haben wir zunächst kleinere Perl-Distributionen als Projekt angelegt und die Git-Repositorys eingebunden. In den YAML-Dateien dieser Projekte haben wir dann konfiguriert, dass nach jedem Commit die Unit-Tests ausgeführt werden und zum Abschluss die Perl-Distribution paketiert werden sollen. Hier ein Auszug aus einem mittlerweile so nicht mehr existenten Projekt:

image: ubuntu:rolling

build:
  script:
    - apt-get update -qq
    - cpanm --installdeps .
    - dzil authordeps | cpanm
    - dzil listdeps | cpanm
    - dzil build

artifacts:
    when: always
    name: "${CI_BUILD_STAGE}_${CI_BUILD_REF_NAME}"
    paths:
      - *.tar.gz

Unser Ansatz war zunächst, Fehler durch Tests zu finden und bei erfolgreichem Testdurchlauf die Perl-Distribution zu erstellen. Die benötigten Abhängigkeiten haben wir mit cpanm installiert. Dabei haben wir festgestellt, dass wir gerne schneller Rückmeldung erhalten würden. Dies führte dann dazu, dass wir die Build-Pipeline optimiert haben.

Verkürzte Durchlaufzeiten erreichen wir einerseits durch eine Anpassung der Befehle, andererseits aber auch dadurch, dass wir ein Docker-Image verwenden, das für diese Distribution optimiert ist und bereits alle Abhängigkeiten enthält.

Was sind die nächsten Schritte? Wir prüfen, ob wir die erfolgreich gebauten Distributionen automatisiert in einen Pinto-Server laden oder auf CPAN veröffentlichen.

Erzeugen von Docker-Images

Im vorherigen Abschnitt habe ich erwähnt, dass wir Docker-Images für die Entwicklung von Perl-Distributionen optimieren. Wir wollen dafür alle Abhängigkeiten einer Perl-Distribution in einem Docker-Image zur Verfügung stellen, damit wir die Durchlaufzeit der Perl-Distribution klein halten und dann schnell Rückmeldung nach einem Commit bekommen.

Wie haben wir dies mit Gitlab erreicht? Wir setzen Dist::Zilla ein und beschreiben Abhängigkeiten über dessen Konfiguration dist.ini und das cpanfile. Im verwendeten Docker-Image werden diese darüber beschriebenen Abhängigkeiten mit cpanm installiert.

Dafür haben wir Gitlab so konfiguriert, dass bei einer Änderung dieser Dateien im Master-Branch der Perl-Distribution das verwendete Docker-Image neu erstellt wird. Hier ein beispielhafter Auszug aus einer Gitlab-Konfiguration:

trigger_image_build:
  stage: trigger
  script:
    - curl --request POST --form "token=$CI_JOB_TOKEN" --form ref=master https://gitlab.com/api/v4/projects/9398220/trigger/pipeline
  only:
    refs:
      - /^master$/
    changes:
      - cpanfile
      - dist.ini

Die Beschreibungen der Abhängigkeiten werden beim Erstellen des Docker-Images aus dem abhängigen Projekt gelesen. Hier ein beispielhafter Auszug aus einem Dockerfile:

RUN cd /home/mydocker/src && \
  git clone https://gitlab-ci-token:${CI_TOKEN}@gitlab.com/perlservices/project.git && \

[...]
  
RUN cd /home/mydocker/src/project && \
   cpanm --skip-satisfied --installdeps . && \
   dzil authordeps --missing | cpanm --skip-satisfied && \
   dzil listdeps | cpanm --skip-satisfied

Die Gitlab-Dokumentation hat uns hier teilweise eher verwirrt als geholfen, aber letzten Endes haben wir ein perfekt abgestimmtes Image erhalten, in dem alle Abhängigkeiten enthalten sind. Dadurch können in dem Projekt, das auf diesem Image basiert, nach einem Commit sofort die Unit-Tests ausgeführt werden können.

Die Durchlaufzeiten sind daher sehr gering und liegen bei einem gehosteten Gitlab-Repository bei etwa drei Minuten. Der Löwenanteil dieser drei Minuten liegt darin begründet, dass wir auf einen freien Gitlab-Runner warten müssen.

Um die Durchlaufzeiten weiter zu verringern, migrieren wir die Repositorys derzeit auf einen eigenen Gitlab-Server.

Hinweis: Das müssen wir wegen dem Fall des Privacy Shields ohnehin machen 🙂

Dokumentation erstellen

Die in Projekten zu erstellende Dokumentation reicht je nach Wunsch des Kunden von kurzen Beschreibungen über HTML-Dateien bis zu sauber mit LaTeX gesetzten Dokumenten. Das Ausgangsformat der Dokumente ist für uns stets Markdown, da dies einfach zu schreiben ist, wir uns auf das Wesentliche konzentrieren können und alle gewünschten Zielformate erzeugt werden können.

In Gitlab erzeugen wir mit pandoc aus den Quelldateien das Zielformat. Gegebenenfalls verarbeiten wir das Resultat automatisiert weiter. Wenn als Ergebnis beispielsweise ein PDF erzeugt werden soll, dann bedeutet dies, dass wir aus Markdown LaTeX-Dokumente erzeugen und diese im Anschluss mit lualatex in ein PDF wandeln. Damit dies möglich ist, haben wir uns ein Docker-Image erstellt, in dem TeX Live installiert ist.

Da wir lualatex aus TeX Live einsetzen, ist unser Docker-Image mehrere Gigabyte groß. Diese Kröte müssen wir wohl schlucken. Pandoc leistet sehr gute Dienste und die Entscheidung für Markdown als Ausgangsformat hat sich bewährt.

Wir werden diese Kombination beibehalten, jedoch gelegentlich prüfen, ob wir das Docker-Image etwas verkleinern können 🙂

Zusammenfassung

Wir erstellen mit Gitlab automatisiert Perl-Distributionen, Docker-Images und Dokumente in unterschiedlichen Formaten. Gitlab als Plattform hat sich hierfür bewährt. Durch den Einsatz einer selbst betriebenen Gitlab-Instanz erhoffen wir uns geringere Durchlaufzeiten.

Links


Permalink: