Zum Inhalt springen
DedicatedPHP Kontakt

Kontinuierliche Integration in PHP: Was vor dem Deployment zu prüfen ist

Eine zuverlässige CI-Pipeline für PHP validiert Abhängigkeiten, Code, Tests und Artefakte und macht Fehler sichtbar, bevor sie ein Deployment freigibt.

Redaktionelles Diagramm einer CI-Pipeline für PHP mit Phasen für Abhängigkeiten, Analyse, Tests und Artefaktvalidierung

Eine Pipeline für kontinuierliche Integration (CI) muss eine konkrete Frage beantworten: Kann diese Änderung in die gemeinsame Codebasis integriert werden, ohne bekannte Fehler einzuführen oder vereinbarte Anforderungen zu verletzen? Um das zu beantworten, sollten wiederholbare Prüfungen definiert, ihre Ausführung geordnet und Fehler so aufbereitet werden, dass sie nützliche Informationen liefern.

CI bedeutet nicht, jede Änderung automatisch bereitzustellen. Gemeint ist die Praxis, Änderungen häufig zu integrieren und automatisiert zu validieren. Continuous Delivery bereitet kontinuierlich eine bereitstellbare Version vor; Continuous Deployment ergänzt die automatische Veröffentlichung in der Produktion, sobald die festgelegten Bedingungen erfüllt sind. Eine Anwendung kann CI nutzen, ohne die Auslieferung zu automatisieren, oder die Auslieferung bis in eine Testumgebung automatisieren und vor der Produktion eine Freigabe verlangen.

Den Vertrag der Pipeline definieren

Den Vertrag der Pipeline definieren — guía visual de DedicatedPHP

Bevor du Tools auswählst, solltest du festlegen, welche Eingaben ein Lauf erhält, was er erzeugen muss und unter welchen Bedingungen er fehlschlägt. Eine nützliche Konfiguration dokumentiert mindestens:

  • Eingaben: die zu validierende Änderung, die relevante Konfiguration und die vom Projekt deklarierten Abhängigkeiten.
  • Umgebung: Betriebssystem und Laufzeitanforderungen, PHP-Konfiguration sowie die für Tests benötigten Dienste. Sie sollte zwischen den Läufen ausreichend ähnlich sein, damit die Ergebnisse vergleichbar sind.
  • Ergebnis: den Endstatus, Test- und Analyseberichte sowie gegebenenfalls ein eindeutig identifizierbares Artefakt, das später validiert werden kann.
  • Fehlerbedingungen: welche Fehler die Integration blockieren, welche Warnungen auslösen und wer eine vorübergehende Ausnahme genehmigen darf.

Die Installation sollte von der versionierten Abhängigkeitskonfiguration ausgehen und die Lock-Datei berücksichtigen, statt bei jedem Lauf stillschweigend neue Versionen aufzulösen. So lässt sich eine Ursache für Unterschiede zwischen Entwicklern und CI reduzieren. Außerdem sollten die von der Anwendung erwarteten Plattform- und Erweiterungsanforderungen angegeben und geprüft werden, ob die Laufzeitumgebung sie erfüllt.

Vermeide Abhängigkeiten der Pipeline von lokalen Dateien, persönlichen Diensten oder undokumentierten manuellen Schritten. Benötigt eine Prüfung eine Datenbank, einen Cache oder einen anderen Dienst, lege fest, wie dieser gestartet wird, welche Daten erforderlich sind und wie die Bereinigung erfolgt. Der Vertrag muss die Produktion nicht vollständig nachbilden, sollte aber Unterschiede, die das Ergebnis beeinflussen können, ausdrücklich benennen.

Prüfungen nach Aufwand und Erkennungsleistung ordnen

Eine praktikable Reihenfolge beginnt mit schnellen Validierungen und endet mit den Prüfungen, die mehr Zeit oder Infrastruktur benötigen. Ziel ist nicht, möglichst viele Aufgaben anzuhäufen, sondern Probleme frühzeitig zu erkennen, ohne auf wesentliche Abdeckung zu verzichten.

  1. Reproduzierbare Installation: Löse die Abhängigkeiten anhand der Projektdefinition und der Lock-Datei auf. Schlägt dieser Schritt fehl, sind die übrigen Ergebnisse nicht verlässlich.
  2. Formatierung und Konventionen: Prüfe die vereinbarten Formatierungs- oder Stilregeln. Diese Prüfungen sind schnell und verhindern, dass Unterschiede in der Darstellung erst bei einer aufwendigeren Überprüfung auffallen.
  3. Statische Analyse: Suche nach Inkompatibilitäten und Fehlern, die sich erkennen lassen, ohne alle Abläufe der Anwendung auszuführen. Richte die Regeln am tatsächlichen Code und der realen Projektkonfiguration aus.
  4. Tests: Führe zuerst Unit-Tests aus und ergänze Integrations- oder End-to-End-Tests entsprechend dem Risiko, das sie abdecken, und den benötigten Diensten.
  5. Artefaktvalidierung: Prüfe, ob das erzeugte Paket oder Image alles für die Ausführung Notwendige enthält und Entwicklungsdateien, lokale Daten sowie Secrets ausschließt.

Nicht für jede Anwendung sind dieselben Tests oder dieselbe Reihenfolge erforderlich. Dauert eine statische Analyse deutlich länger als ein kleiner Unit-Test, kann es sinnvoll sein, beide Prüfungen nach der Installation der Abhängigkeiten parallel auszuführen. Unabhängige Aufgaben können ebenfalls parallel laufen, um die Wartezeit zu verkürzen, sofern sie auf einer reproduzierbaren Grundlage aufbauen und ihre Ergebnisse derselben Änderung zugeordnet bleiben.

Schritte, die dasselbe Verzeichnis verändern oder von vorherigen Ergebnissen abhängen, sollten dagegen nicht unüberlegt parallelisiert werden. Trenne die gemeinsame Vorbereitung von nachfolgenden Aufgaben, begrenze die gleichzeitige Nutzung gemeinsam verwendeter Dienste und mache Abhängigkeiten zwischen Phasen deutlich. Ziel ist es, die Feedbackzeit zu verkürzen, ohne die Pipeline unvorhersehbar zu machen.

Festlegen, was blockiert und was später ausgeführt wird

Als erste Regel sollte die Integration blockiert werden, wenn eine für die Sicherheit der Änderung relevante Prüfung fehlschlägt: Installation, vereinbarte Analyse, vorgeschriebene Tests oder Paketvalidierung. Eine informative Aufgabe – etwa eine noch in der Bewertung befindliche Prüfung – kann während eines festgelegten Zeitraums Ergebnisse melden, ohne zu blockieren. Sie braucht eine verantwortliche Person, einen Überprüfungstermin und ein Kriterium dafür, wann sie verpflichtend wird. Andernfalls werden Warnungen dauerhaft und verlieren ihren Wert.

Schnelle Prüfungen sollten bei jeder Änderung frühzeitig Feedback liefern. Aufwendige Tests können parallel oder in einer späteren Phase ausgeführt werden oder seltener stattfinden, wenn Zeit oder Infrastruktur dies rechtfertigen. Werden jedoch alle wichtigen Validierungen erst nach der Integration ausgeführt, entsteht ein Zeitraum, in dem Änderungen ungeprüft bleiben. Lege fest, was vor der Integration erforderlich ist und was als zusätzliche Validierung folgt, und berücksichtige dabei die Auswirkungen eines spät entdeckten Fehlers.

Ein erfolgreicher Lauf bedeutet nicht, dass ein Deployment freigegeben ist. CI validiert die Änderung und kann ein Artefakt erzeugen; der Auslieferungsprozess entscheidet, wie es weitergegeben wird, in welche Umgebung und unter welchen Kontrollen. Eine ausdrücklich definierte Grenze verhindert, dass eine Validierungsaufgabe versehentlich in der Produktion veröffentlicht. Wenn automatisches Deployment vorgesehen ist, sollten dessen Bedingungen, Freigaben, Rollout-Strategie und Rollback-Mechanismus separat festgelegt werden.

Konfiguration und Secrets schützen

Secrets dürfen weder ins Repository noch in Beispiel-Konfigurationsdateien oder Ausführungsberichte gelangen. Nutze den Secrets-Management-Mechanismus der CI-Umgebung, beschränke ihre Verfügbarkeit auf die Aufgaben, die sie benötigen, und gib Validierungen, die lediglich isolierte Dienste brauchen, keine Produktionszugangsdaten.

Prüfe auch die Protokolle: Eine Exception, ein fehlgeschlagener Test oder ein Diagnosebefehl kann sensible Variablen ausgeben. Werte zu maskieren ist hilfreich, ersetzt aber nicht die Vermeidung ihrer Ausgabe. Verwende Testdaten, die keine echten Informationen offenlegen, und lege ein Verfahren fest, um Zugangsdaten zu widerrufen, falls sie in einem Protokoll oder Artefakt auftauchen.

Fehler diagnostizierbar machen

Ein roter Status ohne Kontext zwingt dazu, Arbeit zu wiederholen, und macht CI zur Blackbox. Bewahre Test- und Analyseberichte, die zur Identifizierung des fehlgeschlagenen Schritts erforderliche Ausgabe sowie Kennungen der Abhängigkeitsversionen oder des Artefakts auf. Vermeide dagegen die Protokollierung personenbezogener Daten, von Secrets oder undifferenzierten Umgebungs-Dumps.

Schlägt ein Test sporadisch fehl, sollte er nicht nach unbegrenzten Wiederholungen als erfolgreich markiert werden. Erfasse, welche Tests fluktuieren, wie häufig und unter welchen Bedingungen; untersuche Ursachen wie Parallelität, externe Abhängigkeiten, gemeinsam genutzten Zustand oder Zeitlimits. Wird ein instabiler Test vorübergehend isoliert, dokumentiere das Risiko, benenne eine verantwortliche Person und setze einen Termin, um ihn wieder als blockierende Prüfung einzustufen.

Es ist außerdem sinnvoll, zwischen einem Codefehler und einem Infrastrukturproblem zu unterscheiden. Melde, wenn Dienste nicht gestartet, Abhängigkeiten nicht abgerufen oder Aufgaben wegen fehlender Ressourcen nicht abgeschlossen werden konnten. Bei einer vorübergehenden Unterbrechung kann ein erneuter Versuch sinnvoll sein, sollte jedoch begrenzt und sichtbar sein. Wird der erste Fehler verborgen, lassen sich wiederkehrende Probleme schwerer erkennen.

CI an eine Legacy-Anwendung anpassen

CI an eine Legacy-Anwendung anpassen — guía visual de DedicatedPHP

Bei einem älteren System können strengere Regeln, die schlagartig aktiviert werden, nützliche Änderungen blockieren und unkontrollierte Ausnahmen fördern. Beginne mit einer Baseline: Ermittle, welche Tests derzeit bestehen, welche bereits vorhandenen Fehler die Analyse meldet und wie lange die einzelnen Phasen dauern. Stelle ein bereits bestehendes Problem nicht als Regression dar, lass die Baseline aber auch nicht zu einer zeitlich unbegrenzten Ausrede werden.

  • Verpflichte zunächst zu reproduzierbaren, bereits stabilen Prüfungen wie der Installation und einer verlässlichen Testsuite.
  • Erfasse bestehende Befunde und verlange, dass neue Änderungen das Problem nicht vergrößern, sofern Tool und Projekt einen solchen Vergleich ermöglichen.
  • Ergänze Tests für Bereiche mit höherem Änderungsrisiko und erweitere ihre Abdeckung schrittweise.
  • Reduziere Ausnahmen in kleinen, gut überprüfbaren Änderungen; benenne für jede vorübergehende Ausnahme eine verantwortliche Person und einen Termin.
  • Miss Dauer und Fehlerursachen, um gezielt einzelne Phasen zu optimieren, statt Validierungen zu entfernen, ohne zu wissen, welches Risiko sie abdeckten.

Eine gute kontinuierliche Integration in PHP wird nicht durch die Anzahl der Phasen definiert, sondern durch reproduzierbare und verständliche Ergebnisse. Kann das Team erklären, was jeder Schritt validiert, was die Integration blockiert und wie sich ein Fehler untersuchen lässt, hilft die Pipeline dabei, anhand von Belegen zu entscheiden, wann eine Änderung bereit ist, weiterzugehen.

Möchten Sie diese Ideen in Ihrem Projekt anwenden?Lass uns über deine PHP-Plattform sprechen.
Verwandten Dienst anzeigen