In der dynamischen Welt der Softwareentwicklung steht unser Team bei DER STANDARD vor ständigen Herausforderungen. Die steigende Komplexität von Projekten erfordert nicht nur ein tiefes Verständnis für die eingesetzten Technologien, sondern auch eine durchdachte und effiziente Entwicklungspraxis.

In diesem Blogbeitrag möchten wir Einblicke in unseren Entwicklungsprozess geben – von der Erfassung von Aufgaben in Jira bis zur erfolgreichen Bereitstellung von Features in der Produktionsumgebung. Vieles davon ist gängige Industriepraxis – und wird bei manchen Entwickler:innen nur zu einem "ja eh" Effekt führen. Trotzdem wollen wir über unsere gelebte Erfahrung berichten.

Epics, Stories, Tasks & Bugs

In unserem Entwicklungsprozess nutzen wir Jira als zentrales Werkzeug zur Verwaltung unserer Projekte. Hier beginnt der Weg eines jeden Features mit der Erfassung von Anforderungen in Form von Epics, Stories, Tasks und Bugs.

In regelmäßigen Sprint-Refinement-Meetings, an denen PMs und Entwickler:innen teilnehmen, erfolgt eine gemeinsame Bewertung der erfassten Anforderungen. Hierbei wird die Klarheit der Anforderungen überprüft, und es werden etwaige Unklarheiten oder Missverständnisse beseitigt. Dieser Schritt fördert ein gemeinsames Verständnis und hilft dabei, mögliche Missverständnisse frühzeitig zu identifizieren.

Screenshot
Eine simple Story zum Adventkalender Button.
DerStandard - Product und Engineering

Die identifizierten Anforderungen werden in kleinere, handhabbare Einheiten heruntergebrochen. Dies geschieht in enger Zusammenarbeit zwischen Produktmanager:innen und Entwickler:innen. Die größeren funktionalen Einheiten, repräsentiert durch Epics, werden in Stories umgewandelt, die detaillierte Funktionalitäten beschreiben. Jede Story wird dann weiter in Tasks aufgeteilt, die konkrete, abgeschlossene Aufgaben darstellen.

Während des Sprint Refinement-Prozesses werden die Stories und Tasks mit zusätzlichen Informationen angereichert. Hierzu gehören klare Definitionen von Akzeptanzkriterien, die den Abschluss der Aufgaben quantifizieren. Darüber hinaus werden notwendige Ressourcen, technische Details und etwaige Abhängigkeiten festgelegt. Dieser Schritt bildet die Grundlage für eine effektive Umsetzung der Features und den weiteren Verlauf des Entwicklungszyklus.

Entwicklung in Feature Branches

Feature Branches sind separate Zweige (Branches) in unserem Git-Repository, die speziell für die Entwicklung neuer Funktionen oder Features erstellt werden. Diese Branches isolieren den Code, der für eine bestimmte Funktion geschrieben wird, vom Hauptentwicklungsstrang (in der Regel "develop" oder "main"). Entwickler:innen erstellen einen Feature Branch, um unabhängig an einer neuen Funktion zu arbeiten, ohne den Hauptcode zu beeinträchtigen.

Der Feature Branch wird erstellt, wenn eine neue Aufgabe oder Story in Jira angenommen wird. Diese Branches folgen dem Muster "feature/COM-1732-Adblocker-Detection", wobei "COM-1732" die Jira-Story-ID ist und "Adblocker-Detection" die Beschreibung der Aufgabe darstellt. Jeder Branch ist somit mit einer spezifischen Aufgabe verknüpft, was eine klare Zuordnung von Codeänderungen zu den entsprechenden Anforderungen ermöglicht.

Screenshot
Einige aktive Feature Branches.
DerStandard - Product und Engineering

Einige der Vorteile der Verwendung von Feature Branches sind dabei für uns:

Pull Request in den DEVELOP Branch & Code Review

Erstellung des Pull Requests: Nachdem Entwickler:innen ihre Arbeit auf einem Feature Branch abgeschlossen haben, wird ein Pull Request erstellt, um die Änderungen in den Entwicklungsbranch "develop" zu integrieren. Der Pull Request enthält eine Zusammenfassung der durchgeführten Änderungen, verknüpfte Jira-Tickets und gegebenenfalls relevante Anmerkungen.

Automatisierte Tests: Vor der manuellen Überprüfung durch die Kolleg:innen werden automatisierte Tests auf dem Feature Branch ausgeführt. Dies umfasst Unit-Tests, Integrationstests und gegebenenfalls auch Regressionstests, um sicherzustellen, dass die neuen Änderungen keine bestehenden Funktionen beeinträchtigen.

Reviewer:innen auswählen: Der Pull Request wird an ausgewählte Reviewer:innen im Team weitergeleitet. Diese können je nach Fachgebiet und Verfügbarkeit variieren. Das Ziel ist es, eine umfassende Überprüfung der Änderungen sicherzustellen und wertvolles Feedback zu erhalten.

Code Review: Die Reviewer:innen beginnen damit, den Pull Request zu inspizieren und das Verständnis der vorgenommenen Änderungen zu entwickeln. Dies beinhaltet die Überprüfung des Codes, neuer Funktionen und eventuell hinzugefügter oder modifizierter Dokumentation. Es wird darauf geachtet, dass der Code den Coding-Standards entspricht, gut dokumentiert ist und keine offensichtlichen Fehler oder Schwächen aufweist. Zudem wird überprüft, ob die vorgenommenen Änderungen im Einklang mit den Projektzielen und den vereinbarten Best Practices stehen. Die Reviewer:innen geben konstruktives Feedback zu den vorgenommenen Änderungen. Dies kann in Form von Kommentaren im Code, allgemeinen Anmerkungen im Pull Request oder spezifischen Fragen an den Entwickler:innen erfolgen. Der Dialog zwischen dem Entwickler:innen und den Reviewer:innen ist ein wichtiger Bestandteil dieses Prozesses. Basierend auf dem Feedback nehmen die Entwickler:innen möglicherweise weitere Anpassungen an ihrem Code vor. Dieser iterative Prozess setzt sich fort, bis die Reviewer:innen zufrieden sind und grünes Licht für die Integration geben.

Screenshot
Code Review
DerStandard - Product und Engineering

Nach erfolgreicher Code-Review und Zustimmung der Reviewer:innen wird der Pull Request in den Entwicklungsbranch ("develop") gemerged. Dies bedeutet, dass die entwickelte Funktion jetzt Teil des Gesamtprojektcodes ist.

CI/CD-Pipelines

Nach dem erfolgreichen Merge eines Feature Branches werden automatisierte Build- und Testprozesse auf dem Entwicklungsbranch ausgelöst. Diese Prozesse dienen dazu, sicherzustellen, dass die integrierten Änderungen nicht zu Konflikten führen und die allgemeine Stabilität des Codes gewährleistet ist. Bitbucket ermöglicht es uns, diese Schritte nahtlos in unseren Workflow zu integrieren, wodurch eine effiziente Überprüfung der Codeintegrität gewährleistet wird.

Nach erfolgreichen Builds und Tests wird der Code automatisch auf unsere Testumgebung "Builders" bereitgestellt. Diese automatisierte Bereitstellung ist ein zentraler Bestandteil unseres CD-Prozesses. Sie ermöglicht es uns, neue Funktionen schnell in einer kontrollierten Umgebung zu testen. Durch diese frühe Testphase können potenzielle Probleme identifiziert und behoben werden, bevor der Code in produktionsrelevante Umgebungen gelangt.

Die Automatisierung dieses Schrittes über Bitbucket CI/CD bietet nicht nur Geschwindigkeit und Effizienz, sondern auch eine höhere Sicherheit im Entwicklungsprozess. Die Zuverlässigkeit dieser Pipelines trägt dazu bei, menschliche Fehler zu minimieren und sicherzustellen, dass nur qualitativ hochwertiger Code in die Testumgebung übergeht.

Testumgebungen - "Builders" und "Works"

Die Einrichtung effektiver Testumgebungen ist ein entscheidender Schritt, um sicherzustellen, dass unsere Software nicht nur stabil und funktional, sondern auch den höchsten Qualitätsstandards entspricht. Die jeweilige Testumgebung besteht aus Komponenten in Amazon Webservices, sowie auch in der lokalen Umgebung – und somit eine vollständige Kopie der Produktionsumgebung, mit anderen Datensets (zum Beispiel keine echten Userdaten, Testartikel etc.).

"Builders": Testen von Features auf Basis des Entwicklungsbranches
"Builders" ist eine isolierte Testumgebung, die auf dem aktuellen DEVELOP Branch basiert. Hier haben Entwickler:innen die Möglichkeit, neue Features und Funktionen in einer Umgebung zu testen, die dem aktuellen Stand der Entwicklungsarbeit entspricht. Dies ermöglicht es, frühzeitig potenzielle Probleme zu erkennen und eine kontinuierliche Integration von Codeänderungen sicherzustellen.

"Builders" fördert schnelle Iterationen und ermöglicht es Entwickler:innen, ihre Arbeit ohne Beeinträchtigung des Hauptcodes zu überprüfen. Dieser Ansatz unterstützt eine agile Entwicklung, da Teams ihre Fortschritte kontinuierlich prüfen und anpassen können, bevor sie in stabilere Umgebungen übergehen. Durch das Testen von Features erhalten Entwickler:innen frühzeitiges Feedback, was eine effiziente Problembehandlung ermöglicht. Dies trägt dazu bei, sicherzustellen, dass nur getesteter und qualitativ hochwertiger Code den Weg in stabilere Umgebungen findet.

"Works": Stabile Testumgebung für Hauptzweige und Produktionsvorbereitungen
Die "Works" Umgebung stellt eine stabilere Testumgebung dar, die auf dem MAIN Branch basiert. Hier werden Codeänderungen integriert und auf mögliche Konflikte sowie Auswirkungen auf den Gesamtcode geprüft. Diese Umgebung ist entscheidend für die Vorbereitung auf Produktionsbereitstellungen und stellt sicher, dass der Code auf einem höheren Qualitätsniveau stabil bleibt.

In "Works" werden umfassendere Tests durchgeführt, einschließlich Integrationstests und Regressionstests. Dies gewährleistet, dass neue Funktionen nicht nur isoliert, sondern auch im Zusammenspiel mit bestehendem Code erfolgreich funktionieren. "Builders" dient als Zwischenschritt vor der Bereitstellung in produktionsrelevante Umgebungen. Hier werden letzte Anpassungen und Überprüfungen durchgeführt, um sicherzustellen, dass der Code den erforderlichen Standards entspricht und bereit für den Einsatz in der Live-Umgebung ist.

Die klare Unterscheidung zwischen "Builders" und "Works" ermöglicht es uns, die Vorzüge verschiedener Testumgebungen zu nutzen. "Builders" fördert schnelle Entwicklungszyklen und frühzeitiges Feedback, während "Works" eine robuste Testumgebung für umfassende Tests und Produktionsvorbereitungen bereitstellen. Zusammen tragen diese Testumgebungen dazu bei, die Qualität und Stabilität unserer Software während des gesamten Entwicklungszyklus sicherzustellen.

Screenshot
Ausrollen einer Story in die drei Umgebungen.
DerStandard - Product und Engineering

Waren die Tests auf beiden Umgebungen erfolgreich, wird die Änderung schließlich durch ein drittes Release in der "Production" Umgebung für alle Leser:innen ausgerollt.

Fazit

Von der Anforderungserfassung in Jira bis zur Produktbereitstellung haben wir bei DER STANDARD einen agilen und qualitätsorientierten Entwicklungsprozess gestaltet. Die klare Struktur von Epics, Stories, Tasks und Bugs ermöglicht eine effiziente Zusammenarbeit im Team und unterstützt die Umsetzung von Features. Die Nutzung von Feature Branches erleichtert die parallele Entwicklung und Pflege des Hauptcodes. Der Pull Request-Prozess mit Code Reviews stellt sicher, dass nur qualitativ hochwertiger Code in den Entwicklungsbranch integriert wird.

Die Integration von CI/CD-Pipelines über Bitbucket ermöglicht automatisierte Builds, Tests und Bereitstellungen, was die Effizienz und Sicherheit im Entwicklungsprozess steigert. Die Testumgebungen, insbesondere "Builders" für schnelle Iterationen und "Works" für umfassende Tests, tragen maßgeblich zur Qualitätssicherung bei. (Max Knor, 10.01.2024)