Integrate Open Rewrite
  • Learning Friday
  • Software-Modernisierung

Integrate Openrewrite

Wie können Abhängigkeits-Updates automatisiert und notwendige Codeanpassungen gleichzeitig umgesetzt werden? Mit der Kombination aus Renovate, OpenRewrite und GitHub Actions haben wir eine Lösung entwickelt, die flexible und anpassbare Automatisierungen ermöglicht. In unserem Blogartikel zeigen wir, wie diese Technik Projekte effizient modernisiert und welche Herausforderungen dabei gemeistert wurden.

Einführung

Im Rahmen unseres Learning Friday haben wir uns bereits sehr intensiv mit dem Thema Software-Modernisierung auseinandergesetzt und dabei große Fortschritte erzielt:

// Automatisierung mit Renovate: Durch den Einsatz von Renovate in Kundenprojekten können wir automatisiert über Versions-Updates informiert werden. Mehr dazu in unserem Blog: Blog Renovate

// Erweiterung von Renovate mittels OpenRewrite, um durch Quarkus-Updates notwendig gewordene Codeänderungen automatisiert durchführen zu können 

Diese Fortschritte haben uns angespornt, noch weiter in die Tiefe zu gehen und zu erreichen, dass für eine beliebige Abhängigkeit und den zugehörigen Renovate-Pull-Request ein passendes OpenRewrite-Rezept automatisiert ausgeführt wird.

Zielsetzung

Unser Ziel war es, für jeden Renovate-Pull-Request und die zugehörige Abhängigkeit automatisch ein passendes OpenRewrite-Rezept auszuführen, um nicht mehr nur wie bisher Quarkus-Updates mit Codeänderungen, sondern auch beliebige Abhängigkeitsupdates sollten mit automatisierten Code-Updates unterstützt werden.

Vorgehensweise

Nachdem wir unser Ziel definiert hatten, mussten einige Entscheidungen getroffen werden. Unter anderem ging es darum, ob wir das Rezept über die bekannten postUpgradeTasks von Renovate ausführen oder eine eigene GitHub-Action einrichten wollten, die beim Öffnen des Renovate-Pull-Requests getriggert wird. Um unabhängiger von Renovate zu sein, haben wir uns für die zweite Variante – die GitHub-Actions – entschieden.

Zudem haben wir beschlossen, eine Sammlung von OpenRewrite-Rezepten zu erstellen, die je nach Projekt variieren kann. Diese Sammlung haben wir dann in ein eigenes „Gepardec-Rezept“ verpackt. Dieses “Gepardec-Rezept” sollte anschließend, nach dem Ausführen des Renovate-Bots, automatisiert über eine GitHub-Action ausgeführt werden. Dabei mussten wir uns entscheiden, wie der Aufbau dieses Rezeptaufrufs in der Pipeline aussehen sollte – entweder GepardecRezeptName.${groupid} oder GepardecRezeptName.${groupid}:${artifactid}. Letztendlich haben wir uns für die erste Variante entschieden, da wir der Meinung sind, dass bei einem Update gleich die gesamte Gruppe aktualisiert werden sollte und die erste Variante somit zu feingranular gewesen wäre.

Unsere Vorgehensweise haben wir am Beispiel Log4j erfolgreich erprobt. Bei dieser Dependency musste nicht nur die Version upgedatet werden, sondern auch der Code angepasst werden. Renovate hat mittels Pull-Request ein Update der Abhängigkeit von Version 1.2.14 auf 1.2.17 vorgeschlagen. Dieses wurde durch das “UpgradeDependencyVersion”-Rezept realisiert. Durch Recherche auf “maven-central” haben wir jedoch festgestellt, dass dies das letzte Version-Update der “Log4j Version 1.x” ist, und neuere Versionen der “Log4j Version 2.x” unter geänderten Koordinaten (groupId: org.apache.logging.log4j, artifactId: log4j-core) zu finden sind. Das bereits bestehende Rezept “Log4j1ToLog4j2” erlaubt es, beide Schritte – d.h. den Wechsel auf die neuen Koordinaten, sowie das Upgrade auf die neueste Version  – auf einmal auszuführen, daher haben wir dieses verwendet.

Die Herausforderung

Die bereits angesprochene “Rezeptsammlung” stellte uns vor einige Herausforderungen: einerseits wo wir diese veröffentlichen wollten und andererseits, wie man sie möglichst einfach verwenden kann. 

Bei der Veröffentlichung haben wir sowohl ein öffentliches Repository, als auch unser GitHub-Repository in Betracht gezogen. Wir haben uns für Zweiteres entschieden und dann in Form eines package-release umgesetzt. 

Die Verwendung der “Rezeptsammlung” gestaltete sich als problemlos, da wir sie einfach als Maven-Abhängigkeit hinzufügen konnten.

Einschränkungen der Lösung:

Die von uns erstellte Lösung macht es nun möglich, durch das Update notwendig gewordene Codeänderungen automatisiert durchzuführen. Dies jedoch mit der Einschränkung, immer auf die neueste Version upgraden zu müssen (da der Renovate-Bot diese automatisch vorschlägt). In manchen Fällen möchte man jedoch definieren können, auf welche Version upgegraded werden soll (z.B. im Fall von breaking changes). Dies kann im Rezept zusätzlich spezifiziert werden.

Fazit

Die Erweiterung von Renovate um die Verwendung einer “personalisierten” Rezeptsammlung erleichtert nun nicht mehr nur Quarkus- oder Spring Boot-Updates, sondern auch die Updates vieler weiterer Abhängigkeiten im Projekt. Außerdem ist diese Sammlung einfach erweiter- und anpassbar, und somit perfekt für die Verwendung in den unterschiedlichsten Kundenprojekten geeignet.

geschrieben von:
Chiara
WordPress Cookie Plugin von Real Cookie Banner