Die Geschichte von einem Tanuki und einem grünen Schwan | Arroba IT
Zum Inhalt springen
devops

Die Geschichte von einem Tanuki und einem grünen Schwan

23. Nov 2018

Gitlab CI für ein Sylius-Projekt aktivieren

Während ich schon viele Projekte mit TravisCI eingerichtet habe, hatte ich noch nie mit GitLab CI gearbeitet. Ich wußte, dass ich analog zu TravisCI, eine Konfigurationsdatei benötige, die die Automatisierung steuert. GitLab sagt, dass es super einfach ist - man muss nur eine .gitlab-ci.yml in seinem Projektverzeichnis erstellen. Aber je mehr ich die Dokumentation und die Blogbeiträge von GitLab las, desto mehr Fragen kamen auf.

  • Muss ich einen Docker-Container erstellen?

  • Wo soll ich ihn speichern?

  • Wo muss ich ihn registrieren?

  • Einen Gitlab-Runner installieren? Was ist das? Wo? Warum?

  • Was sind gemeinsam genutzte Runner?

Ich dachte, da Sylius auf Symfony 4 aka Flex basiert, hat irgendjemand bereits eine Konfigurationsdatei dafür geschrieben und so habe dann im Sylius Slack gefragt, aber die Antwort war negativ. In meiner Recherche im Netz habe ich auch nur veraltete oder irreführende Informationen gefunden, aus denen ich mir Stück für Stück die Snippets herausgepickt und buchstäblich Zeile für Zeile in GitLab übertragen.

Unten seht ihr das Ergebnis und ich werde kurz meine Konfigurationsdatei erklären. Sie kann für ein Sylius 1.3 Projekt verwendet werden.

.gitlab-ci.yml

TLDR: Wenn Du es eilig hast, kannst Du die Datei einfach kopieren.

1stages:
2 - test
3 
4variables:
5 MYSQL_DATABASE: sylius_test_cached
6 MYSQL_ROOT_PASSWORD: root
7 MYSQL_USER: root
8 # This is normally provided by the .env file. But since we have to use "mysql" as host name, its defined
9 # here. We not using any .env file!
10 # The pattern is: mysql://user:password@host/database
11 DATABASE_URL: mysql://$MYSQL_USER:$MYSQL_ROOT_PASSWORD@mysql/$MYSQL_DATABASE
12 
13 # Set memory limit to infinite to avoid running out of memory issues
14 COMPOSER_MEMORY_LIMIT: -1
15 
16 # Set the environments variables manually
17 APP_ENV: test_cached
18 APP_DEBUG: 1
19 APP_SECRET: 1542752314
20 MAILER_URL: smtp://localhost
21 
22 PHP_DATE_TIMEZONE: Europe/Copenhagen
23 
24cache:
25 key: $CI_COMMIT_REF_NAME
26 paths:
27 - vendor
28 - node_modules
29 - public
30 - .yarn
31 
32test:
33 stage: test
34 
35 allow_failure: false # Its there for easy switching
36 
37 services:
38 - mysql:5.7
39 - memcached
40 
41 # This image was made for Laravel but works for Sylius as well
42 # https://github.com/edbizarro/gitlab-ci-pipeline-php
43 image: edbizarro/gitlab-ci-pipeline-php:7.2-alpine
44 
45 before_script:
46 - sudo yarn config set cache-folder .yarn
47 - mkdir -p public/media/cache && mkdir -p public/media/image # Avoiding error: public/media/image folder not found
48 
49 script:
50 # Install the dependencies. Don't execute scripts because the cache clean up take too long, sometimes times out
51 - composer install --prefer-dist --no-ansi --no-scripts --no-interaction --no-progress --no-suggest
52 - bin/console doctrine:database:create --if-not-exists --env=test_cached -vvv # Have to run with debug = true, to omit generation proxies before setting up the database
53 - yarn install
54 - bin/console sylius:theme:assets:install public
55 - bin/console sylius:install:assets
56 - yarn build
57 - bin/console cache:warmup --env=test_cached --no-debug -vvv
58 - bin/console doctrine:migrations:migrate --no-interaction --env=test_cached --no-debug -vvv
59 
60 # Running checks
61 - vendor/bin/phpcs -n --standard=PSR2 src
62 - vendor/bin/security-checker security:chec
63 - vendor/bin/phpspec run --no-interaction -f dot
64 
65 # Set up a frontend with fixture data
66 - bin/console sylius:fixtures:load --no-interaction --env=test_cached --no-debug -vvv
67 - bin/console server:run 127.0.0.1:8080 -d web --env test_cached > /dev/null 2>&1 &
68 
69 # Running tests
70 - echo "Starting BEHAT tests."
71 - cp behat.yml.dist behat.yml
72 - php bin/behat
73 - echo "BEHAT tests done."

Docker

Den Docker-Container musste ich nicht selbst erstellen, sondern es wurde einer von anderen großartigen Menschen erstellt und ich konnte diesen einfach nutzen. Auf der Suche nach dem richtigen Container habe ich zunächst Alpine versucht, aber da fehlte eine ganze Menge Pakete. Ich endete mit dem Image von edbizarro/gitlab-ci-pipeline-php, der zwar für Laravel gemacht wurde, aber sehr gut für Flex/Sylius funktioniert.

MySQL

Ich habe eine Weile gebraucht, um die Verbindung zur Datenbank zu konfigurieren. Bei der Verwendung von localhost oder 127.0.0.1 für die Option --host erhielt ich immer die Fehlermeldung Connection refused. Erst als ich mysql für die Host-Option verwendet habe (da ich einen MySQL-Docker-Container importiere, wenn ich mysql als Dienst in .gitlab-ci.yml angebe), klappte die Verbindung.

.env Configuration

Eine der Quellen für meine .gitlab-ci.yml war die Datei .travis.yml auf https://github.com/Sylius/Sylius-Standard/blob/master/.travis.yml. Von dort habe ich die grobe Struktur und die Umgebung übernommen ... für den Fall, Du fragst Dich, warum ich --env=test_cached verwende ... jetzt weißt Du es :-)

Wenn Du die Datei ließt, siehst Du, dass sie eine bestimmte .env.test_cached-Datei verwendet, die auf die test_cached-Umgebung reagiert. Die Datei wird kopiert und als Quelle verwendet, um die Umgebungsvariablen verfügbar zu machen.

1- cp .env.test_cached.dist .env.test_cached
2- set -a && source .env.test_cached && set +a

Du wirst das in meiner Konfiguration vermissen, weil Umgebungsvariable DATABASE_URL auf mysql:://root@127.0.0.1/sylius_test_cached zeigt. Das war mir zu statisch und ich habe deswegen die Umgebungsvariablen manuell definiert um diese Variablen zur Erstellung der Logindaten für Datenbank zu verwenden.

Composer

Alle Abhängigkeiten von Sylius werden via Composer verwaltet. In der Konfiguration gibt es zwei Punkte, die ich hervorheben möchte:

  1. Composer run out of memory: Dieser Fehler habe ich zum einen erhalten, als Composer die Abhängigkeiten von Upstream holte und zum anderen während er den Cache nach der Installation der Abhängigkeiten geleert hat. Deshalb habe ich in Zeile 14 das Speicherlimit auf unendlich gesetzt.

  2. Composer hit max execution time: Auch hier war der Befehl composer clear cache der Übeltäter. Es dauert eine Ewigkeit, einen - vermutlich bereits leeren - Cache zu leeren, was den gesamten Prozess verlangsamt und manchmal sogar das max_execution_time-Limit erreicht hat. Ich entschied mich, composer install mit der Option --no-scripts auszuführen (Zeile 51).

Ich denke, der Rest ist ziemlich grundlegend und selbsterklärend.