Naprawdę nie wiem, kiedy to zleciało, ale minął już rok, od kiedy dołączyłem do #GetResponse jako Software Architect 😵 Był to intensywny i owocny czas, który warto podsumować!

Współpraca z GetResponse

Kiedy rok temu szukałem nowego miejsca pracy, przeszedłem wiele procesów rekrutacyjnych, na koniec jednak liczyły się tylko 2 oferty, z których wybrałem GetResponse. Z perspektywy czasu nie żałuję tej decyzji i bardzo się cieszę, że dołączyłem do tego zespołu 🙂. Firma oferuje 100% pracę zdalną, co było dla mnie szczególnie istotne po latach spędzonych w pociągu, między domem a biurem. Nie bez znaczenia jest również to, że sama usługa jest duża, skomplikowana i wymagająca — stanowi nie lada wyzwanie pod wieloma względami. Dział IT jest duży i złożony z wielu specjalistów, od których można się sporo nauczyć. Stack technologiczny również pokaźny, choć — nie ma co kryć — jest też spory ogon długu technicznego…

Moja rola w GR

Dołączyłem do GetResponse jako Software Architect w ramach międzyobszarowego zespołu, a co za tym idzie, byłem przez ten rok swego rodzaju wolnym elektronem — jasne, miałem pewnego rodzaju projekty do realizacji, ale poza nimi sam mogłem znajdować miejsca do potencjalnej optymalizacji, sygnalizować problemy i implementować rzeczy wpływające na proces wytwarzania oprogramowania. Nie będę ukrywał, że ta rola bardzo mi odpowiada, ponieważ daje pole do popisu. Wymaga pewnego rodzaju samodyscypliny i organizacji, ale dzięki temu możliwe jest podejmowanie prac, które mogłyby mieć problem z zakwalifikowaniem się do sprintów nastawionych na cele biznesowe…

Zrealizowane inicjatywy

Przez ten rok udało się zrobić wiele mniejszych i większych rzeczy, z których bardzo duża część była moją inicjatywą. Po prostu realizując zadania, napotykałem różne problemy, zagwozdki czy komplikacje, które sygnalizowałem, konsultowałem, i które często przeradzały się w kolejne zadania lub projekty. Zobaczmy więc, co udało się dowieźć, mniej więcej chronologicznie 😉

Wdrożenie Rectora w proces wytwarzania

#Rector potrafi pomóc w aktualizacji przestarzałych zależności, ponieważ zawiera szereg reguł eliminujących wycofane użycia. Oczywiście nie tylko w tym może nam pomóc, zawiera również całą masę innych reguł poprawiających istniejący kod (np. wykorzystując nowsze składnie językowe), nie zmieniając przy tym jego logiki (dzięki temu jest bezpieczny, ale pamiętajcie, by nigdy nie ufać w 100% żadnemu narzędziu modyfikującemu kod).

Udało mi się wdrożyć to narzędzie tak, by bezinwazyjnie, krok po kroku, refaktoryzowało aplikację — w procesie CI jest zadanie, które ma przyzwolenie na niepowodzenie, dzięki czemu nie blokuje procesu (analizuje pliki zmienione w ramach Merge Requestu i podpowiada potencjalne zmiany), a lokalnie każdy deweloper może skorzystać z poręcznych skryptów Composera, by automatycznie zaaplikować podpowiedzi Rectora.

Udało się też napisać niestandardowe reguły, dzięki którym systematycznie możemy poprawiać kod z obszaru legacy (eliminacja notacji węgierskiej czy bezpośredniego użycia const’ów).

Usprawnienie implementacji PHPStan

#PHPStan był już zaimplementowany w proces, gdy dołączyłem do GR, ale niektóre rzeczy nie były zrobione optymalnie, a zatem narzędzie nie wnosiło takiej wartości, jaką mogło. Z mojej inicjatywy udało się wprowadzić obsługę plików baseline, podnieść poziom analizy, dołożyć rozszerzenia (Symfony, Prophecy, MyCLabs enum), które poprawiły jakość analizy.

W procesie CI udało się zrównoleglić analizę poprzez uruchamianie zagnieżdżonych pipeline’ów. Z różnych powodów musieliśmy odejść od sugerowanej przez autora pełnej analizy i mamy wydzielone 4 obszary, analizowane osobno. Kiedyś te 4 obszary były analizowane jeden po drugim w ramach jednego zadania, co sprawiało, że trwało ono bardzo długo, ale też niepowodzenie w dowolnym obszarze (poza ostatnim) skutkowało brakiem analizy w kolejnych obszarach, co utrudniało naprawę błędów. Udało mi się jednak zmodyfikować ten proces tak, że główny pipeline wyzwala pipeline-dziecko z 4 osobnymi zadaniami, które mogą być realizowane równolegle, co skraca sumaryczny czas analizy.

W międzyczasie zainicjowałem i wykonałem również upgrade PHPStan z wersji 0.* na wersję 1.*, co było konieczne, aby wciąż otrzymywać aktualizacje i móc korzystać z nowych funkcjonalności narzędzia.

Wciąż jest w tym obszarze dużo wyzwań i sporo pracy przed nami, ale naprawdę na przestrzeni tych 12 miesięcy dużo udało się już zrealizować.

Wdrożenie Easy Coding Standard

Gdy dołączyłem do GR, nie było żadnej automatyzacji standardów kodowania (poza wytycznymi na Confluence 😉), co samo w sobie nie jest problemem, jednak otwiera furtkę dla wszelakich niespójności. Wyszedłem zatem z inicjatywą, by wprowadzić do projektu #ECS, a następnie wraz z jednym z kolegów wdrożyłem go. Na początkowym etapie zadanie w CI również zezwalało na niepowodzenie, by deweloperzy mieli czas na zastosowanie poprawek w swoich obszarach. W pewnym jednak momencie zadanie stało się wymagane i obecnie blokuje merge, gdy w kodzie znalezione zostaną naruszenia ustalonych standardów. Deweloperzy mają oczywiście możliwość zaaplikowania tych poprawek lokalnie, korzystając z przygotowanych skryptów Composera.

Centralny Traefik

W GetResponse poza główną aplikacją jest cała masa różnych projektów, a każdy z nich (lub zdecydowana większość) oferuje stack Dockera do lokalnego developmentu. Aplikacje w ramach tych stacków eksponują domeny, a robią to za pomocą Traefika. Niestety implementacja nie była optymalna, ponieważ każdy stack posiadał własną usługę Traefika, przez co niemożliwe było uruchomienie wielu stacków jednocześnie (ponieważ tylko jeden Traefik może się podpiąć do portów 80/443). Praca z aplikacjami jak najbardziej była możliwa, utrudnione było co najwyżej integrowanie ich między sobą oraz zmiana kontekstu pracy (konieczność wyłączania stacku przed uruchomieniem innego).

Z mojej inicjatywy wprowadziliśmy zmianę polegającą na wydzieleniu centralnego Traefika, którego uruchamia się w tle jako samodzielny stack, a pozostałe stacki eksponują domeny korzystając z etykiet w usługach, które mają być dostępne przez HTTPS. Dzięki temu można uruchomić dowolną liczbę środowisk, a stacki mogą komunikować się między sobą (poprzez wspólną sieć Dockera).

Dodatkową zaletą tego rozwiązania jest to, że certyfikaty SSL muszą być aktualizowane tylko w jednym miejscu 🙂

Wdrożenie Captain Hook

Wszystkie narzędzia QA, które do tego momentu udało się wdrożyć/usprawnić miały jedną, zasadniczą wadę — nacisk na ich użycie był położony na proces CI. Chcieliśmy trochę odciążyć runnery i sprawić, by więcej problemów wyłapywanych było już po stronie dewelopera, na jego komputerze. W tym celu zastosowaliśmy CaptainHook 🪝

Dzięki temu było możliwe:

  • sprawdzanie poprawności plików PHP (linter)
  • sprawdzanie zgodności ze standardami kodowania
  • statyczna analiza z użyciem PHPStan
  • weryfikacja tytułu commita (wymóg taska z Jiry 😉)

Część z tych zadań realizowana jest przed commitem, inne przed pushem, część w obu przypadkach. Generalnie cel jest taki, by deweloper dostał błyskawiczny feedback jeszcze zanim prześle kod do centralnego repozytorium. Dzieje się to w sposób zautomatyzowany, ponieważ hooki instalują się automatycznie w momencie stawiania projektu (a konkretnie po instalacji paczek Composera).

Kierunek: PHP8!

Przychodząc do GR miałem za sobą parę miesięcy kodowania w PHP8, a tutaj musiałem wykonać krok w tył, ponieważ główny system wciąż opiera się o PHP 7.4. Ponownie, nie jest to problemem jako takim, bo system działa stabilnie — chodzi tylko i wyłącznie o niedostępność pewnych funkcjonalności oferowanych przez PHP w nowszych wersjach, a które znacznie upraszczają kod i sprawiają, że praca z językiem jest wygodniejsza.

Drążyłem zatem temat i udało mi się samemu lub z pomocą innych osób wprowadzić szereg zmian zapewniających kompatybilność z PHP8: aktualizacja zależności do wersji wspierających tę wersję (lub pozbycie się ich, jeśli okazały się zbędne), poprawa istniejącego kodu aplikacyjnego oraz wewnętrznych zależności (np. poprawa sygnatur metod implementowanych z interfejsów, pozbycie się słowa resource z namespace’ów itp). Przed nami wciąż długa droga, bo blokują nas inne uwarunkowania, ale jeśli chodzi o sam kod, jesteśmy dużo bliżej PHP8 niż wtedy, gdy zaczynałem pracę z projektem 🙂

Gitlab jako narzędzie do Code Review

To postrzegam jako jeden z moich większych sukcesów — udało mi się przekonać osoby decyzyjne w dziale IT do zmiany narzędzia do Code Review: z Crucible przeszliśmy na Gitlab Premium! Byłem inicjatorem tego przedsięwzięcia, ale też jednym z koordynatorów całego procesu — od zebrania informacji o wymaganiach stawianych przez zespoły deweloperskie i o możliwościach narzędzia, przez wsparcie procesu migracyjnego, aż po przygotowanie dokumentu opisującego proces Code Review w Gitlabie.

Wcześniej, gdy code review wykonywane było z użyciem Crucible, Gitlab również był wykorzystywany, ale nie w wersji Premium i służył tylko do przechowywania kodu oraz realizowania procesu CI/CD. Miało to zasadniczą wadę — code review wykonywało się w oderwaniu od wyniku procesu QA, zatem recenzenci albo weryfikowali wynik pipeline’u ręcznie, albo zostawiali to na barkach autora zmian i skupiali się tylko na tym, jakie są wprowadzone zmiany, a nie czy działają.

Bardziej subiektywnie: UI Crucible jest specyficzny. Osoby przyzwyczajone do Gitlab/Github raczej nie czują się tam swobodnie 😅. Z mojej perspektywy ta zmiana drastycznie poprawiła sposób pracy z code review dostarczanych zmian.

Osobnym tematem jest przejście na wersję Premium, w której dostępne jest wiele rozwiązań usprawniających procesy:

Jednak dla osób, które odczuwały mocne przyzwyczajenie do poprzedniego procesu, właśnie dzisiaj zakończyliśmy integrację Gitlab-Jira poprzez development panel — tak, ten temat też zainicjowałem i pilotowałem 😉

Struktura organizacyjna w Gitlabie

Zaproponowałem i wdrożyłem (póki co ręcznie zarządzaną) drzewiastą strukturę organizacyjną, która opisuje zespoły deweloperskie oraz meta-zespoły obszarowe. Dzięki temu możliwe jest:

  • przypisanie określonych grup osób jako code owners
  • wzmiankowanie grup (zespołów) w Merge Requestach
  • nadawanie uprawnień do projektów lub całych grup projektowych poprzez udostępnienie ich grupie (co znacznie upraszcza zarządzanie dostępami, aczkolwiek ma swoje minusy)

Operowanie na grupach znacznie ułatwia onboarding/offboarding czy wszelakie przetasowania międzyzespołowe, ponieważ użytkowników wystarczy dodać/usunąć do/z grup, zamiast żmudnie przechodzić przez niezliczoną ilość miejsc w celu nadania/odebrania indywidualnych uprawnień.

Zmiana procesu wdrożeniowego

Deployment głównej aplikacji GetResponse jest dość specyficzny i nie będę go opisywał. Trwa w każdym razie długo, ponieważ jest wieloetapowy i wymaga różnego rodzaju weryfikacji. Gdy dołączyłem do GR, proces takiego wdrażania w zasadzie blokował główną gałąź rozwojową, do której deweloperzy integrowali swoje zmiany. Nie można było zatem mówić o #Continuous Integration, co miało oczywiste wady (np. późne dowiadywanie się o konfliktach między zmianami wprowadzanymi przez różne osoby).

Zaproponowałem zatem pewne drobne zmiany, które sprawiły, że główna gałąź rozwojowa została odblokowana i można się do niej integrować w dowolnym momencie (gdy zmiany przejdą proces code review i QA oraz zostaną zaakceptowane). Poza nakreśleniem koncepcji zajmowałem się również dostosowaniem dokumentacji na Confluence i modernizacją definicji Gitlab CI.

Wciąż przyglądamy się temu, jak ten proces działa i myślimy, jak mógłby wyglądać. Na pewno da się zrobić jeszcze dużo, by codzienne dostarczanie wartości klientom GetResponse było wygodniejsze, przyjemniejsze i sprawniejsze z perspektywy zespołów deweloperskich.

Współdzielony katalog .idea

Nie znam dokładnych danych, ale wydaje się, że zdecydowana większość deweloperów w GR korzysta z PHPStorm. To świetne środowisko programistyczne, które bardzo pomaga w efektywnej pracy z projektami. Mamy lokalne środowisko uruchomieniowe oparte o Dockera, wszelakie skrypty i narzędzia ujednolicające proces wytwarzania. Tylko jak to zautomatyzować w ramach IDE?

Z pomocą przychodzi folder .idea - to taki kontener na metadane, w którym PHPStorm przechowuje sobie masę informacji o tym, jak powinien działać projekt. Bardzo często można zobaczyć, że ten katalog dodawany jest do .gitignore, ale czy słusznie? Dawniej uważałem, że tak, jednak zaczynając pracę z aplikacją GetResponse, cały czas łapałem się na tym, że wiele rzeczy muszę dokonfigurować sam i pomyślałem sobie: “Dlaczego każdy nowy pracownik musi tracić czas na ustawianie czegoś, co powinno być dostępne od razu po sklonowaniu projektu?” 😉

Wyszedłem zatem z inicjatywą, by pójść tropem rekomendacji JetBrains i współdzielić część ustawień dodając wybrane pliki z .idea do repozytorium #Git, co następnie zaimplementowałem. Dzięki takiemu zabiegowi wszyscy deweloperzy współdzielą konfiguracje:

  • wersji PHP wymaganej do działania aplikacji
  • zdalnego interpretera PHP opartego o kontener Dockera w lokalnym stacku
  • XDebug z użyciem zdalnego interpretera
  • połączeń do baz danych uruchomionych w stacku Dockera
  • pluginu Symfony
  • inspekcji #PHPStan i PHPCodeSniffer oparte o zdalny interpreter
  • skryptów uruchomieniowych (uruchamianie różnych skryptów make czy Composera z menu IDE)

Główną zaletą tego podejścia jest minimalizacja pracy, jaką należy włożyć w to, by zacząć pracę z projektem. Wszystko, co potrzeba, po prostu działa od razu po uruchomieniu projektu. A w przypadku dodawania nowych konfiguracji wraz z rozwojem projektu u każdego dewelopera pojawią się one automatycznie.

Modernizacja integracji Renovate Bota

Renovate to narzędzie automatyzujące żmudny proces utrzymywania aktualnych zależności projektowych. Działał już, gdy dołączyłem do GR, jednak nie byłbym sobą, gdybym nie znalazł dziury w całym 😉

Było kilka detali negatywnie wpływających na proces aktualizacji paczek:

  • Renovate Bot działał uruchomiony z niestandardowego obrazu, co generowało dodatkowy narzut utrzymaniowy i rodziło dług techniczny
  • rangeStrategy ustawione było tak, że bot modyfikował composer.json ustawiając najnowsze wersje paczek jako wymagane, co mogło prowadzić do problemów z rozwiązaniem zależności (tak naprawdę wymagana powinna być najniższa wersja, która faktycznie zawiera to, co jest potrzebne do działania aplikacji — wszystkie nowsze wersje są jedynie opcjonalne z perspektywy naszego projektu, a szerszy zakres wspieranych wersji to większe prawdopodobieństwo, że zależności innych paczek nie będą konfliktowały z naszymi wymaganiami). Jednocześnie modyfikacja composer.json generowała zmianę content-hash w composer.lock, co przy rozproszonej pracy wielu osób często prowadziło do konfliktów w Git…
  • Merge Requesty wystawiane przez bota zawierały masowe aktualizacje paczek, co utrudniało ich weryfikację, a gdy pojawiały się problemy, nie zawsze można było jednoznacznie wskazać, która paczka je spowodowała
  • tytuły Merge Requestów nie były przyjazne

Przysiadłem zatem i zmodyfikowałem ten proces. Zaczęliśmy korzystać z oficjalnego obrazu Renovate, który zawiera wszystko, co potrzeba, by analizować zależności wielu popularnych menedżerów paczek. Stworzyłem presety, które zdefiniowały nasze oczekiwania co do paczek PHP (ignorowanie wersji rozwojowych 0.*; aktualizacja wersji tylko w ramach zdeklarowanego constraintu, czyli z zachowaniem Semantic Versioning; aktualizacja pojedynczych paczek w ramach MR; linkowanie wewnętrznych paczek pochodzących z firmowego Packagista on premise w tabelce podsumowującej zmiany). Presety te zostały stworzone w osobnym repozytorium, by można je było używać w dowolnym projekcie PHP. Dodane zostało wsparcie dla innych menedżerów — Renovate pilnuje nam również Dockerfile czy .gitlab-ci.yml. Wykorzystaliśmy również (zainicjowany wcześniej przeze mnie) mechanizm code owners, by automatycznie przypisywać recenzentów do utworzonych merge requestów.

Wszystkie te zmiany pozwoliły nam na bieżące aktualizowanie zależności bez dużego nakładu pracy. Merge Requesty zawierają aktualizacje pojedynczych paczek, więc diff jest niewielki, content-hash się nie zmienia więc można merdżować taśmowo wszystkie wystawione MRy, gdy zostaną zaakceptowane przez recenzentów i przejdą pipeline. W teorii moglibyśmy nawet pozwolić botowi automatycznie merdżować zmiany po przejściu pipeline, ale jeszcze do tego nie dojrzeliśmy 😅

Multi-stage Docker build

Środowisko do lokalnej pracy oparte o Dockera to moim zdaniem konieczność, by myśleć o osiągnięciu powtarzalnych rezultatów u dowolnej osoby pracującej z projektem. Środowisko takie powinno odzwierciedlać środowisko produkcyjne, może nie w kontekście pełnej infrastruktury, ale co najmniej środowiska uruchomieniowego: wersja PHP, dostępne rozszerzenia, biblioteki systemowe — to wszystko powinno być spójne.

W GetResponse Dockerfile miał kilka drobnych rozbieżności względem stanu produkcyjnego, a do tego był skonstruowany w taki sposób, że build cache dość łatwo się przedawniał i każda przebudowa obrazu trwała długo. W ciągu tego roku rękami moimi oraz kolegów ze smykałką do devopsowania udało się zrealizować wiele prac w tym obszarze, dzięki czemu:

  • wprowadzony został multi-stage build z jawnym podziałem na środowisko uruchomieniowe (system operacyjny, pakiety) i budowanie samej aplikacji (instalowanie zależności projektowych, generowanie cache aplikacyjnego czy innych statycznych plików)
  • wydzieliliśmy targety developerskie (używane w CI do uruchamiania zadań QA) i produkcyjne (przeznaczone do uruchamiania, zaskakująco, na produkcji 😉), mające wspólną bazę, ale różniące się pod wieloma względami od siebie
  • do lokalnej pracy z aplikacją użyliśmy targetu, który nie zawiera buildu samej aplikacji, ponieważ aplikacja w obrazie i tak była “przykrywana” wolumenem podpinamym poprzez docker compose. To skraca czas budowania obrazu lokalnie i praktycznie eliminuje ryzyko przedawniania build cache’u (system operacyjny i pakiety zmieniają się niezwykle rzadko).
  • udało się uspójnić środowisko uruchomieniowe z obecnym stanem produkcji (tak, nie dotarliśmy tam jeszcze z Dockerem, ale jesteśmy blisko 😅) i zlecić zadania na weryfikację czy rozszerzenia, jakie dodaliśmy na podstawie stanu produkcji, są w ogóle potrzebne (czy może kod, który ich używał jest zwyczajnie martwy)

To był naprawdę kawał dobrej roboty 👍

Wysprzątanie zależności Composera

Gdy zaczynałem pracę z aplikacją GetResponse, w zależnościach #Composera było kilkanaście paczek oznaczonych jako porzucone. Oznacza to, że nie były one ani rozwijane, ani nawet wspierane, a co za tym idzie, były długiem technicznym i potencjalnym źródłem problemów. Udało mi się wysprzątać zależności tak, że nie było nawet jednej porzuconej paczki.

Sporo paczek było również zablokowanych na konkretnej wersji, więc umożliwiłem im aktualizację do nowszych wersji. Rekordzistą było aws/aws-sdk-php, które zostało zaktualizowane z wersji 3.103.2 na 3.208.5 😅 Pamiętajcie: jeśli po aktualizacji paczki macie problem z działaniem swojej aplikacji, spróbujcie zdiagnozować przyczynę problemu i ją wyeliminować, jeśli to się nie uda — zgłoście bug na Githubie/Gitlabie. Dopiero w ostateczności blokujcie wersję zależności, wciąż unikając sztywnych constraintów, bo to prosta droga do ogromnego długu technicznego, który prędzej czy później odbije się czkawką.

Aktualizacja komponentów Symfony

W momencie pierwszej instalacji zależności projektowych, wśród paczek były komponenty Symfony nawet w wersji 3.4! Sukcesywnie podnosiliśmy wersje tych paczek — najpierw do 4.*, a w ostatnich dniach do głównej gałęzi trafił mój Merge Request aktualizujący wszystkie komponenty do wersji 5.4. Nie było to takie proste, na jakie wygląda, dlatego że aplikacja używa dużo wewnętrznych komponentów, które bazują na komponentach Symfony i rozwikłanie tych zależności w kilkunastu repozytoriach wymagało nie lada gimnastyki. Niestety, na v6 będziemy musieli jeszcze poczekać aż do momentu wspomnianej migracji na PHP8…

Pozbycie się najstarszych wersji komponentów umożliwiło m.in. użycie symfony/framework-bundle i zaimplementowanie kernela, który potrafi automatycznie budować kontener DI (dla ludzi pracujących z modelowym Symfony wydaje się to naturalne, ale GR nie korzysta z Symfony Framework, a jedynie z jego poszczególnych komponentów — całość jest sklejona w niestandardowy sposób).

Inne

Powyżej opisane inicjatywy często były rozłożone w czasie i składały się z wielu etapów. Pomiędzy nimi realizowane były różne inne, mniejsze tematy. Wielokrotnie służyłem radą i pomocą, czy to w formie werbalnych dyskusji, czy będąc recenzentem w Merge Requestach. Realizowałem masę drobnych usprawnień dotyczących stosowanych narzędzi czy procesów, których nie ma sensu opisywać, bo i trudno byłoby je sobie wszystkie przypomnieć 😉

Trwające projekty

Kierunek: Kubernetes!

Wszystkie wspomniane powyżej prace z Dockerfile i resztą powiązanych z buildem plików miały jeden cel: migrację aplikacji na klaster Kubernetes. Używamy intensywnie klastrów Kubernetesa na etapie deweloperskim (środowiska testowe, runnery Gitlaba) i częściowo produkcyjnie. Jak wspomniałem, aplikacja GetResponse produkcyjnie nie wykorzystuje Dockera (a tym bardziej k8s), ale jesteśmy już blisko tego celu!

Być może jeszcze w tym miesiącu uda nam się uruchomić instancję na klastrze i skierować tam część ruchu. Nie będzie to jednak koniec prac, bo infrastruktura GR jest bardziej złożona — proces migracji na k8s składa się z wielu etapów i jestem jednym z koordynatorów tego procesu 😁

Road to Cloud

W międzyczasie zostałem zaszczycony rolą Chief Architecta w projekcie Road to Cloud, którego celem jest migracja usług GR do chmury. Przed objęciem przeze mnie tej roli kilka drobnych aplikacji zostało już tam przeniesionych, ale w skali całej organizacji to była tylko rozgrzewka. Obdarzono mnie zaufaniem, które bardzo doceniam, bo nie ukrywajmy — nie mam w tym zakresie dużego doświadczenia, dlatego że nie miałem wcześniej okazji korzystać z rozwiązań chmurowych. Na szczęście to nie jest tak, że sam muszę dokonać tej migracji — współpracuję z zespołem DevOps oraz deweloperami koordynując prace, organizując spotkania, spisując notatki, tworząc i realizując zadania oraz zarządzając roadmapą. Projekt jest wymagający i czasochłonny, a trzeba go pogodzić z innymi bieżącymi zadaniami, więc różnie bywa z postępami prac.

Wspomniana migracja aplikacji GetResponse na Kubernetes jest tak naprawdę etapem projektu Road to Cloud, po prostu chcąc ruszyć do chmury, chcemy mieć sprawdzone rozwiązanie oparte o Dockera. Ułatwi nam to również migrację do PHP8, ponieważ mając środowisko uruchomieniowe opakowane w obraz, możemy je dowolnie zmieniać nie wychodząc poza proces dewelopmentu (wdrożenie to tylko podmiana obrazu, niewymagane są prace związane z infrastrukturą).

Ciekawostki liczbowe

  • Do tej pory zmerdżowanych zostało 125 moich merge requestów na Gitlabie (nie znam liczby MRów na Crucible, bo został już wyłączony), kilkanaście dodatkowych prowadziłem w imieniu Renovate Bota (w przypadku aktualizacji PHPStan często wymagane były dodatkowe zmiany)
  • W ok. 60 merge requestach na Gitlabie brałem udział jako recenzent (ponownie nie znam liczby z Crucible, ale było to na prawdopodobnie drugie tyle, albo i więcej), dodając niezliczoną liczbę komentarzy 😉
  • Stworzyłem 182 zadania w Jira (z czego 106 zostało już zrealizowanych)
  • 1 raz pracuję na MacBooku, a przez te 12 miesięcy miałem ich aż 3 🤪

Podsumowanie

To był bardzo udany rok! Nie wszystko udało się tak, jak bym oczekiwał. Nie wszystko zrobiłem tak, jak powinienem. Jednak patrząc na całokształt, biorąc pod uwagę te wszystkie rzeczy, które udało się zrealizować, mogę śmiało powiedzieć, że jestem zadowolony 🙂