Magento-Projekte wiederverwenden
Zehn Magento-Shops mit zehn identischen Pipeline-Dateien zu betreiben ist technische Schulden in Reinform. Jede Änderung am Deploy-Prozess muss zehnmal gemacht werden. GitLab-Templates mit include und extends lösen das Problem – ein zentraler Build-Standard, individuell erweiterbar pro Projekt.
Inhaltsverzeichnis
- 1. Das Problem mit kopierten Pipeline-Dateien
- 2. GitLab include: Grundlagen und Varianten
- 3. extends: Jobs aus Templates ableiten und überschreiben
- 4. YAML-Anchors als Alternative innerhalb einer Datei
- 5. Ein zentrales Template-Repository für Magento-Projekte
- 6. Projektspezifische Overrides und Erweiterungen
- 7. Template-Versionierung und Breaking Changes
- 8. Vergleich: Kopierte Pipelines vs. Template-basierte Pipelines
- 9. Fallstricke bei der Template-Wiederverwendung
- 10. Zusammenfassung
- 11. FAQ
1. Das Problem mit kopierten Pipeline-Dateien
Agenturen und Teams, die mehrere Magento-Projekte betreiben, kennen das Problem: Die erste .gitlab-ci.yml wird sorgfältig entwickelt, getestet und als funktionierend befunden. Beim zweiten Projekt wird sie kopiert und leicht angepasst. Beim dritten Projekt wird die Kopie des zweiten Projekts kopiert. Nach einem Jahr existieren zehn Pipeline-Dateien, die sich in Details unterscheiden, weil Verbesserungen nur in einige Projekte eingepflegt wurden. Eine Sicherheitslücke im Deploy-Skript muss in zehn Repositories einzeln gefixt werden.
Das ist kein akademisches Problem, sondern ein alltäglicher Betriebszustand in Agenturen mit mehreren Kundenprojekten. Die Lösung ist dieselbe, die Softwareentwickler seit Jahrzehnten für Code-Duplikation einsetzen: Abstraktion und Wiederverwendung. GitLab bietet dafür das include-Schlüsselwort, das externe YAML-Dateien in die aktuelle Pipeline einbindet, und extends, das Job-Definitionen aus eingebundenen Templates ableitet und erweitert.
Das Ziel ist ein System, in dem der gemeinsame Build-, Test- und Deploy-Standard an einem Ort definiert ist – im Template-Repository – und jedes Projekt nur noch das einbindet und dort konfiguriert, was projektspezifisch ist. Eine Verbesserung am Deploy-Standard wird einmal gemacht und steht sofort allen Projekten zur Verfügung, die das Template in einer kompatiblen Version referenzieren.
2. GitLab include: Grundlagen und Varianten
Das include-Schlüsselwort in GitLab CI/CD erlaubt das Einbinden externer YAML-Dateien in die aktuelle Pipeline-Konfiguration. Es gibt vier Varianten: local (Datei im selben Repository), project (Datei in einem anderen GitLab-Projekt), remote (URL zu einer externen YAML-Datei) und template (vordefinierte GitLab-Templates). Für die Wiederverwendung über mehrere Magento-Projekte ist die project-Variante die geeignetste, weil sie ein zentrales Template-Repository in derselben GitLab-Instanz referenziert und von GitLabs Zugriffskontrolle profitiert.
Ein wichtiger Aspekt bei include: project ist die ref-Option, die festlegt, welcher Branch, Tag oder Commit-SHA aus dem Template-Repository verwendet wird. Wenn ref auf einen fixen Tag zeigt, ist die Template-Version eingefroren und Änderungen am Template-Repository wirken sich nicht sofort auf alle Projekte aus. Wenn ref auf main zeigt, verwenden alle Projekte immer die neueste Template-Version – praktisch für kleine Teams, aber riskant, weil Breaking Changes sofort alle Projekte treffen.
# .gitlab-ci.yml in a Magento project
# Includes templates from a central template repository
include:
# Pin to a specific version tag for stability
- project: "mironsoft/gitlab-ci-templates"
ref: "v2.1.0"
file:
- "/magento/build.yml"
- "/magento/test.yml"
- "/magento/deploy.yml"
# Project-specific variables override template defaults
variables:
MAGENTO_VERSION: "2.4.8"
PHP_VERSION: "8.4"
DEPLOY_HOST: "shop1.example.com"
DEPLOY_PATH: "/var/www/shop1"
THEME_PATH: "app/design/frontend/Mironsoft/default"
# Project-specific stage additions (template stages remain)
stages:
- build
- test
- package
- deploy
- verify
- rollback
3. extends: Jobs aus Templates ableiten und überschreiben
Das extends-Schlüsselwort erlaubt es, einen Job aus einem Template abzuleiten und einzelne Eigenschaften zu überschreiben oder zu ergänzen. GitLab führt dabei ein Deep-Merge durch: Dictionaries (wie variables und cache) werden zusammengeführt, Skalare und Listen werden überschrieben. Das ermöglicht fein granulierte Overrides, ohne die komplette Job-Definition kopieren zu müssen.
Ein typisches Muster ist, einen Template-Job zu definieren, der den Standard-Build-Prozess für Magento beschreibt, und in jedem Projekt nur die projektspezifischen Abweichungen zu überschreiben. Das Template definiert das PHP-Image, die Composer-Optionen, den Cache und die Artefakt-Konfiguration. Das Projekt überschreibt nur das spezifische Theme-Verzeichnis oder fügt projektspezifische Build-Schritte hinzu.
# templates/magento/build.yml (in template repository)
# Base build job for Magento projects — extended in each project
.build:magento:base:
stage: build
image: "php:${PHP_VERSION:-8.4}-cli"
variables:
COMPOSER_CACHE_DIR: "${CI_PROJECT_DIR}/.cache/composer"
COMPOSER_HOME: "${CI_PROJECT_DIR}/.cache/composer"
THEME_PATH: "app/design/frontend/Mironsoft/default" # Default theme
cache:
key:
files:
- composer.lock
paths:
- .cache/composer/
policy: pull-push
script:
- composer install --no-dev --prefer-dist --optimize-autoloader
- npm ci --prefix "${THEME_PATH}/web/tailwind"
- npm run build --prefix "${THEME_PATH}/web/tailwind"
- bin/magento setup:di:compile
artifacts:
paths:
- vendor/
- generated/
- "${THEME_PATH}/web/tailwind/css/"
expire_in: 3 hours
---
# .gitlab-ci.yml in a specific project — extends the template
build:magento:
extends: .build:magento:base
variables:
THEME_PATH: "app/design/frontend/Acme/custom" # Project-specific override
script:
- !reference [.build:magento:base, script] # Include base script
- echo "Project-specific post-build step"
4. YAML-Anchors als Alternative innerhalb einer Datei
YAML-Anchors sind eine YAML-native Lösung für Wiederverwendung innerhalb einer einzigen Datei. Mit &anchor-name wird ein Block als Anker definiert, mit *anchor-name wird er referenziert und mit <<: *anchor-name werden die Werte in einen anderen Block eingemischt. GitLab CI/CD unterstützt YAML-Anchors vollständig, was sie für die Wiederverwendung innerhalb der projektlokalen .gitlab-ci.yml nützlich macht.
YAML-Anchors sind jedoch keine Lösung für projektübergreifende Wiederverwendung, weil sie nicht aus externen Dateien importiert werden können. Sie eignen sich für das Vermeiden von Duplikationen innerhalb einer Datei, nicht als Ersatz für das include-System. In der Praxis werden YAML-Anchors oft für Common-Variables-Blöcke und SSH-Setup-Schritte verwendet, die in mehreren Jobs derselben Pipeline benötigt werden.
5. Ein zentrales Template-Repository für Magento-Projekte
Das zentrale Template-Repository ist der Kern der Template-Wiederverwendung. Es enthält die gemeinsamen Bausteine für alle Magento-Projekte: Build-Jobs, Test-Jobs, Deploy-Jobs, Verify-Jobs und Rollback-Jobs. Die Struktur sollte nach Funktionsbereichen organisiert sein, damit Projekte nur die Teile einbinden, die sie benötigen. Ein Projekt, das kein Rollback-Job benötigt, bindet rollback.yml nicht ein.
Das Template-Repository benötigt eine eigene Pipeline, die die Templates validiert. GitLab bietet dafür den ci-lint-Endpoint der API, der eine Pipeline-Konfiguration syntaktisch und semantisch prüft. Für das Template-Repository bedeutet das: Ein Test-Job in der Template-Pipeline führt einen Lint-Check über alle Template-Dateien aus und stellt sicher, dass keine syntaktisch ungültige Konfiguration veröffentlicht wird.
# Structure of the central template repository
# mironsoft/gitlab-ci-templates/
# magento/build.yml — Composer, npm, di:compile, static content
# magento/test.yml — PHPStan, PHPCS, PHPUnit
# magento/deploy.yml — SSH, rsync, symlink switch, shared files
# magento/verify.yml — Health check, smoke tests, cache status
# magento/rollback.yml — Symlink switch to previous release
# magento/cleanup.yml — Remove old releases, clean old artifacts
# Template repository pipeline (validates all templates)
# .gitlab-ci.yml (in template repo itself)
validate:templates:
stage: test
image: alpine:latest
script:
- apk add --no-cache curl
# Validate each template file against GitLab CI lint API
- |
for file in magento/*.yml; do
echo "Validating: $file"
curl -sf \
--header "PRIVATE-TOKEN: ${GITLAB_API_TOKEN}" \
--header "Content-Type: application/json" \
--data "{\"content\": \"$(cat ${file} | jq -Rs .)\"}" \
"${CI_API_V4_URL}/ci/lint" | jq -e '.valid == true'
done
6. Projektspezifische Overrides und Erweiterungen
Nicht jedes Magento-Projekt ist identisch. Einige Projekte haben zusätzliche Stores mit unterschiedlichen Themes, andere deployen auf mehrere Server-Umgebungen, wieder andere haben spezifische Test-Anforderungen. Das Template-System muss Overrides und Erweiterungen ermöglichen, ohne die Wiederverwendbarkeit der Basis-Templates zu beeinträchtigen.
Die empfohlene Strategie ist, projektspezifische Konfiguration über Variablen zu übergeben, die im Template als Defaults definiert sind. Wenn das Template MAGENTO_LOCALE: "de_DE" als Default setzt und ein Projekt mehrsprachig ist, überschreibt das Projekt die Variable auf MAGENTO_LOCALE: "de_DE en_US fr_FR". Der Template-Job konsumiert die Variable, ohne den Job-Code zu verändern. Nur wenn die Projektanforderung fundamental über das Template hinausgeht, wird der Job mit extends abgeleitet und die abweichenden Schritte überschrieben.
# Project-specific .gitlab-ci.yml — minimal override pattern
include:
- project: "mironsoft/gitlab-ci-templates"
ref: "v2.1.0"
file: ["/magento/build.yml", "/magento/deploy.yml", "/magento/verify.yml"]
# Override only what differs from the template defaults
variables:
DEPLOY_HOST: "${PROD_DEPLOY_HOST}" # From GitLab CI/CD variables
DEPLOY_PATH: "/var/www/shop"
MAGENTO_LOCALE: "de_DE en_US" # Multi-locale override
THEME_PATH: "app/design/frontend/Mironsoft/default"
# Extend the template deploy job with a project-specific step
deploy:production:
extends: .deploy:production:base # From included template
after_script:
# Notify project-specific Slack channel after deployment
- |
curl -X POST "${SLACK_WEBHOOK_URL}" \
-d "{\"text\": \"Deployed ${CI_COMMIT_TAG} to production\"}"
7. Template-Versionierung und Breaking Changes
Templates, die von mehreren Projekten referenziert werden, müssen versioniert sein. Ohne Versionierung führt jede Änderung am Template sofort zu Auswirkungen auf alle Projekte, die das Template einbinden. Das ist für Breaking Changes – zum Beispiel das Umbenennen eines versteckten Jobs oder das Hinzufügen einer Pflicht-Variable – inakzeptabel, weil Projekte möglicherweise ohne Vorwarnung brachen.
Semantische Versionierung (SemVer) ist auch für CI-Templates geeignet: Patch-Versionen für Bug-Fixes, Minor-Versionen für neue optionale Features, Major-Versionen für Breaking Changes. Projekte, die auf einen Major-Versions-Tag zeigen, erhalten automatisch alle kompatiblen Verbesserungen, müssen aber beim nächsten Major-Release bewusst migrieren. Die Template-Repository-Pipeline erzeugt automatisch Tags bei Merges auf main, um den Versionierungsprozess zu vereinfachen.
8. Vergleich: Kopierte Pipelines vs. Template-basierte Pipelines
Der Unterschied zwischen kopierten und template-basierten Pipelines zeigt sich besonders deutlich, wenn ein Sicherheitsproblem oder ein Best-Practice-Update über alle Projekte eingespielt werden muss. Bei kopierten Pipelines ist das ein manueller Prozess über alle Repositories. Bei template-basierten Pipelines ist es eine einzige Änderung im Template-Repository.
| Aspekt | Kopierte Pipelines | Template-basierte Pipelines | Vorteil |
|---|---|---|---|
| Security-Fix einspielen | N Repositories editieren | 1 Template-Update | Drastisch weniger Aufwand |
| Konsistenz über Projekte | Divergiert mit der Zeit | Zentral erzwungen | Gleicher Standard überall |
| Neue Projekte aufsetzen | Kopieren, anpassen, testen | include + Variablen setzen | Minuten statt Stunden |
| Nachvollziehbarkeit | Jedes Repo eigenständig | Zentraler Changelog | Auditierbar, nachvollziehbar |
| Projektspezifische Anpassungen | Direkt möglich | Via extends und Variablen | Flexibel, aber kontrolliert |
9. Fallstricke bei der Template-Wiederverwendung
Ein häufiger Fallstrick ist das unbeabsichtigte Überschreiben von Template-Variablen durch Projekt-Variablen. Wenn ein Template eine Variable als Pflicht-Variable definiert und das Projekt eine gleichnamige Variable mit einem anderen Wert setzt, gilt der Projekt-Wert – ohne Fehlermeldung. Das kann zu stillen Fehlfunktionen führen, die schwer zu debuggen sind. Eine Namenskonvention für Template-interne Variablen (zum Beispiel Präfix _TMPL_) reduziert Kollisionen.
Ein zweiter Fallstrick betrifft die Referenzierung von hidden Jobs aus Templates. Hidden Jobs beginnen mit einem Punkt (zum Beispiel .build:magento:base) und werden nicht direkt ausgeführt. Wenn ein Projekt einen Job mit extends: .build:magento:base erweitert und der Template-Job umbenannt wird, schlägt die Pipeline des Projekts mit einer nichtssagenden Fehlermeldung fehl. Breaking Changes in Templates müssen daher immer mit einer Major-Version und einem klaren Changelog kommuniziert werden.
Ein dritter Fallstrick ist das Caching von Template-Dateien durch GitLab. Bei der include: remote-Variante cached GitLab die externe URL. Bei include: project mit einem Branch-Ref (statt einem Tag) wird die Template-Datei zum Zeitpunkt der Pipeline-Ausführung aus dem Repository gelesen – was die erwartete Aktualität bietet, aber bei einem ungültigen Commit im Template-Repository sofort alle abhängigen Projekte-Pipelines blockiert.
10. Zusammenfassung
GitLab CI-Templates für mehrere Magento-Projekte wiederverwenden ist eine Investition, die sich ab dem zweiten Projekt auszahlt. Das include: project-System ermöglicht es, einen gemeinsamen Build-, Test- und Deploy-Standard zentral zu definieren und über Versionstags kontrolliert an alle Projekte auszuliefern. extends erlaubt projektspezifische Overrides ohne vollständige Job-Kopien. Variablen-Defaults im Template und Overrides im Projekt-Repository trennen den gemeinsamen Standard von den projektspezifischen Details.
Das Template-Repository selbst braucht eine eigene Pipeline mit Lint-Checks und semantischer Versionierung. Breaking Changes müssen kommuniziert werden; Projekte migrieren bewusst auf neue Major-Versionen. Mit diesem System ist ein Security-Fix im Deploy-Skript ein einmaliger Commit im Template-Repository statt zehn Commits in zehn Repositories.
GitLab CI Templates — Das Wichtigste auf einen Blick
include: project
Bindet Templates aus einem zentralen Repository ein. ref auf Tag setzen für Stabilitätskontrolle. Zugriff über GitLab-Berechtigungen gesteuert.
extends
Leitet Jobs aus Template-Definitionen ab. Deep-Merge für Dictionaries. Nur abweichende Eigenschaften überschreiben.
Versionierung
SemVer für Template-Tags. Patch: Bug-Fixes, Minor: neue Features, Major: Breaking Changes mit explizitem Changelog.
Projekt-Overrides
Variablen-Overrides für konfigurierbare Unterschiede. extends für strukturelle Abweichungen. Kein direktes Editieren von Template-Dateien.