Już dostępny

Program Szkoleniowy Java Developer dostępny 🔥💪 tylko TERAZ za 1299 zł  Sprawdź szczegóły i agendę

Zakres

Monitoring • Apache Kafka • Clean Code Testowanie • Hibernate • Systemy kolejkowe Sprawdź szczegóły i agendę

Zakres

14 modułów  /  ponad 40h nagrań  /  230 lekcji  /  dożywotni dostęp  /  Sprawdź szczegóły i agendę

Zero-click deployment dzięki Trunk-based development i Conventional Commits

utworzone przez 3 marca 2024Java, Tip and Tricks

[Szybkie info]: Startujemy z IV edycją Programu Szkoleniowego Java Developera 🚀. To MEGA piguła wiedzy o Java 🔥💪

  • 14 tygodniowy program szkoleniowy online,
  • 230 lekcji w formie video (40 godzin materiału)
  • z dożywotnim dostępem
  • Case Studies, masz dostęp do kodu i obrazów Dockerowych
  • zamknięta grupa mentorzy + uczestnicy i webinary na żywo

W agendzie znajdziesz: Mikroserwisy, Systemy kolejnowe, Apache Kafka, Caching, Hibernate/MyBatis/Spring Data, techniki efektywnych Testów kodu, Clean Code i Maven.

Tylko teraz dołączysz z 50% rabatem to 2699 zł 1299 zł (+VAT). I nigdy już nie będzie taniej. Poniżej dowiesz się więcej:

Zobacz więcej

A teraz przechodzimy do artykułu:

Wyobraź sobie, że wprowadzasz commit do repozytorium, a następnie automatycznie produkuje się paczka oraz wdraża się na środowisko testowe, albo produkcyjne.

Piszesz git commit, git push, a resztę załatwia automatyzacja.

W dzisiejszym wpisie podzielę się, jak techniki trunk-based development, conventional commits i automatyczne wdrażanie wyprodukowanej wersji pozwoli Ci poprawić efektywność Twojej pracy.

W blogpoście o Fail fast przeczytasz o:

  • Ułożeniu procesu deploymentu
  • Trunk-based development i Conventional Commits
  • Projekcie Semantic Release

Ułożenie procesu

W jednym z poprzednich wpisów wspomniałem o technice Trunk-based development – do lektury zachęcam tutaj. Generalna idea polega na tym, że wszelkie wprowadzane zmiany trafiają od razu na główną gałąź w git. Unikamy wtedy utrzymywania gałęzi, na których przez dłuższy czas rozwijamy pewną funkcjonalność, jednocześnie wprowadzając mechanizmy umożliwiające wyłączenie jeszcze w pełni nieukończonej pracy.

Zaletą tego podejścia są bardzo częste integracje kodu z innymi developerami. Można nawet dzielić się pracą i wydzielając punkty integracji w postaci zdefiniowanych klas, czy interfejsów, wspólnie kontrybuować do jednej większej całości, aby szybciej dostarczyć wartość.

Dzięki częstej integracji kodu i uruchamianym testom otrzymujemy bardzo szybki feedback, czy system nadal działa, czy nie. Jeżeli kod działa jako całość, czemu już tego nie wrzucić na produkcję, lub przynajmniej środowisko testowe?

Przyznasz, że to odważne i daleko posunięte podejście.

Jak to od razu na produkcję? Albo na środowisko testowe? Przecież mogę coś popsuć.

To nie psuj 😉

Żeby czuć się pewnie, musimy mieć dobrze zbudowaną siatkę bezpieczeństwa w postaci:

  • dobrze napisanych, automatycznych testów,
  • procesu rollbacku — tak szybko jak możesz wdrażać, masz możliwość szybko wycofywać zmiany.

Jeżeli masz pewność, że kod jest dobrej jakości, testy są dobrej jakości oraz proces rollbacku działa stabilnie — pozbędziesz się swoich obaw przed częstym wdrażaniem.

W dalszej części wpisu zaproponuję pipeline, który pozwoli automatycznie wdrożyć zmianę na środowisko.

Krok 1. Testy

Kluczowym i niezbędnym aspektem w ciągłym wdrażaniu jest dobrze skonstruowany zestaw testów. Możesz skorzystać z piramidy testów, aby wprowadzić je na różnych poziomach – od unit testów, po componentowe i aplikacyjne. Ważne jest to, żeby testując kod, klasy były skonfigurowane ze sobą rzeczywiście w taki sam sposób, jak będą na produkcji. Możesz wspomóc się metryką Code-coverage, aby wychwycić niepokryte testami fragmenty kodu.

Dobrej jakości, szybko uruchamiające się testy są niewątpliwie jednym z podstawowych i niezbędnych kroków pipeline wydawania oprogramowania, zatem zwróć na ich jakość szczególną uwagę.

Zanim commit jednak trafi na główną gałąź, powinien przejść code review w postaci pull request’a. Oprócz komentarzy od współautorów projektu, na pull requeście uruchamiany jest zestaw testów. Tylko przy pozytywnym przebiegu testów kod powinien móc być dopuszczony do głównej gałęzi.

Psst… Interesujący artykuł?

Jeżeli podoba Ci się ten artykuł i chcesz takich więcej – dołącz do newslettera. Nie ominą Cię materiały tego typu.

.

Krok 2. Wydawanie oprogramowania

Wydanie wersji może następować w różny sposób, na przykład ręczne kliknięcie uruchamiający pipeline, który stworzy wersję i tag. Jest to jednak manualny proces. Na pierwszy rzut oka może nie wymagać wiele pracy, lecz wymaga ręcznej interakcji.

Jeżeli chcesz uzyskać prawdziwą ciągłość wdrażania, dobrze by było, aby wydanie wersji wydarzyło się automatycznie, bez interakcji.

Musiałby istnieć sposób, aby wydać wersję w sposób automatyczny, na przykład na podstawie wiadomości umieszczonej w commicie.

Conventional Commits

I z pomocą przychodzi technika Conventional Commits. To specyfikacja, która zakłada, że odpowiednio nazywasz commity w gicie według ustalonej konwencji, na przykład:

  • feat: email address valication
    Opisuje, że wprowadzasz nową funkcjonalność
  • fix: email address validation with dashes
    Opisuje, że poprawiasz jakąś funkcjonalność.
  • Dodając dopisek BREAKING CHANGE oznajmiasz, że zmieniasz funkcjonalność tracąc kompatybilność wsteczną.

Odpowiednio nazywając commit w git według ustalonej konwencji nie tylko poprawisz czytelność logu (musząc zastanowić się, jaką zmianę tak naprawdę wprowadza commit), ale możesz też skorzystać z automatycznego wyznaczenia kolejnej wersji zgodnie z Semantic Version (MAJOR.MINOR.PATCH) oraz wygenerowania Release notes.

Projekt Semantic Release

Conventional Commits to jedynie specyfikacja. Projekt Semantic Release automatyzuje proces wydawania oprogramowania i oferuje:

  • automatyczne wyznaczenie następnej wersji na podstawie zastosowanego commit message według konwencji Conventional Commit oraz poprzednią wersję
  • stworzenie git tag
  • wygenerowanie release notes

Weźmy na przykład poniższe scenariusze wydania oprogramowania odpowiednio nazywając nasz commit message w git:

git commit messageTyp release
feat: email address validationminor
przykład 1.1.0 → 1.2.0
fix: email address validation with dashespatch
przykład: 1.2.0 → 1.2.1
feat: email address is now an user’s name

BREAKING CHANGE: api now accepts the single parameter which is email address, and username is dropped


lub:

feat!: email address is now an user’s name
major
przykład 1.2.0 → 2.0.0

Żeby wykorzystać projekt Semantic Release w swoim contineous integration, wystarczy zainstalować paczkę i wykonać komendę:

semantic-release

Zerknij na przygotowane przykłady dla różnych platform contineous integration tutaj.

Po uruchomieniu zostanie stworzony tag o nazwie z kolejną wersją. Na ten moment nasz pipeline wygląda tag:

Do tej pory mamy przetestowaną wersję i założony tag w git.

W dalszej części możemy przystąpić do stworzenia paczki dystrybucyjnej i przesłania go do repozytorium paczek. W zależności od tego jak dytrybuujesz swój projekt, może być to jar wysyłany do Nexus, albo obraz docker przesyłany do container registry. Wówczas nasz pipeline reagujący na stworzenie taga mógłby wyglądać w następujący sposób:

Warto dodać, że projekt Semantic Release posiada zestaw pluginów. Jednymi z nich są pluginy ułatwiające integrację z platformami, na których budujemy kod (np. GitHub, czy GitLab, zamykające issues, CircleCI). Inne odpowiadają za różnego rodzaju powiadomienia (np. Slack, Telegram), inne integrują się z narzędziami (np. Gradle). Zajrzyj tam, jeżeli czegoś potrzebujesz, ale w prostocie pipeline tkwi siła.

Psst… Interesujący artykuł?

Jeżeli podoba Ci się ten artykuł i chcesz takich więcej – dołącz do newslettera. Nie ominą Cię materiały tego typu.

.

Krok 3. Continuous Deployment and Rollback

Mając zbudowaną paczkę z automatycznie stworzonego taga, możemy ją wdrożyć na nasze środowisko. Może być to środowisko testowe, albo produkcyjne.

Wówczas nasz pipeline będzie wyglądał tak:

Wdrożenia na środowisko polega na podmianie obecnej wersji na właśnie zbudowaną. Nasz proces powinien być wyposażony w mechanizm rollbacku, np. można pamiętać poprzednią wersję i umożliwić ręczny rollback, lub wpisać jedną z poprzednich wersji, jeżeli chcemy cofnąć się jeszcze dalej.

Podsumowanie

W rezultacie otrzymaliśmy w pełni automatyczny pipeline, który umożliwia zbudowanie projektu, wydanie wersji oraz jej wdrożenie poprzez umieszczenie jednego commita w gicie. Commit ten przechodzi code review, zestaw automatycznych testów, aby finalnie zostać włączonym na główną gałąź projektu.

Dzięki Trunk-based development wszystkie zmiany trafiają na główną gałąź. Nazywając commity wg konwencji Conventional Commits możemy automatycznie wyliczyć kolejną wersję, którą można później automatycznie wdrożyć.

To tak, jakby releasować kod prosto z gita, prawda?

Podoba Ci się ten artykuł? Weź więcej.

Jeżeli uważasz ten materiał za wartościowy i chcesz więcej treści tego typu – nie przegap ich i otrzymuj je prosto na swoją skrzynkę. Nawiążmy kontakt.

.

Dyskusja