5 powodów, czemu GitLab CI w 2026 jest cieniem GitHub Actions

GitLab CI odstaje od GitHub Actions w ważnych obszarach: w integracji z narzędziami AI, automatyzacji pracy z komentarzami, bezpieczeństwie kluczy API.

Jak CI to GitLab? Taka była prawda 10 lat temu. Może nawet była to prawda 5 lat temu. Ale na tym koniec. Czas zaktualizować wiedzę.

Miałem bardzo duży sentyment do GitLaba, odkąd uwolnił mnie od konieczności zadawania się z Jenkinsem czy jeszcze gorszymi potworkami. Jeśli, podobnie jak do niedawna ja, myślisz pozytywnie o GitLabie, ten artykuł jest dla ciebie. Pokażę, czemu w 2026 roku nie ma sensu opierać komercyjnego lub opensource’owego Continuous Integration o tę platformę.

Nie będę pisał, który YAML jest bardziej estetyczny albo łatwiejszy do czytania. W dalszej części podam 5 obiektywnych obszarów, gdzie GitHub Actions daje konkretne przewagi: przy integracji z narzędziami AI, nie-AI-owej automatyzacji pull/merge requestów, bezpieczeństwie kluczy API, albo po prostu na minutach pracy chmury obliczeniowej kompilującej nasz kod.

To krótki artykuł. O porównaniu wszystkich możliwości platform CI można by pisać książki. Ja zwracam uwagę tylko na wycinek, ale moim zdaniem bardzo znaczący.

Czytaj dalej „5 powodów, czemu GitLab CI w 2026 jest cieniem GitHub Actions”

Mistral Vibe: szybki, tani i europejski AI

Francuski Mistral AI wydał w grudniu 2025 ciekawe modele Devstral do pracy z kodem. Większy dorównuje DeepSeekowi, mimo 5-krotnie mniejszego rozmiaru. Taki rozmiar pozwala oferować konkurencyjne ceny. Mistral stworzył też Vibe, własne narzędzie do pracy agentowej, działające w terminalu oraz z IntelliJ. Opowiem o moich odczuciach z korzystania.

Ludowa mądrość mówi, że „Europa nie jest innowacyjna”, a w AI liczy się tylko Ameryka, oraz ewentualnie Chińczycy. Zapomnijmy o takich bzdurach i spójrzmy na fakty. Wiedzieliście, że jest europejska firma rozwijająca całą gamę zastosowań sztucznej inteligencji, od rozpoznawania głosu i tekstu po kodowanie? Francuski Mistral AI upublicznił w grudniu 2025 ciekawe modele Devstral. Większy dorównuje w testach DeepSeekowi, mimo 5-krotnie mniejszego rozmiaru. Mniejszy Devstral też ma przyzwoite wyniki, a jest 28-krotnie mniejszy od tak często wspominanego w mediach chińskiego modelu.

Możecie się spytać, co z tego wynika dla waszej codziennej pracy, którą jest pisanie kodu, a nie przerzucanie się plotkami z działki AI.

Otóż tak mały rozmiar modeli pozwala Mistralowi oferować bardzo konkurencyjne ceny, na poziomie tego, czym działają na wyobraźnię chińscy dostawcy. Czasy odpowiedzi mają też być bardzo krótkie.

Jeśli płacicie za AI pomagający w kodowaniu z własnej kieszeni, oto nowa możliwość. Możecie dostać produkt nieodstający możliwościami od średniej, za atrakcyjną cenę, a wasze pieniądze zostaną na kontynencie, podobnie jak wasze dane. Pewnie też nie słyszeliście, że Mistral inwestuje we własne serwery w Szwecji, żeby europejskie prompty nie musiały latać po chmurze pana Bezosa, na obcej ziemi? To już wiecie.

Zamiast lajkować posty o budowaniu europejskiej suwerenności cyfrowej, możecie coś praktycznego zrobić w tym kierunku. Do tego oszczędzając sporo grosza w porównaniu z używaniem amerykańskich rozwiązań, wytrenowanych między innymi na pobranej bez pozwolenia (i bez płacenia) europejskiej własności intelektualnej.

Wracając do kwestii technicznych. Mistral stworzył też Vibe, własne narzędzie do pracy agentowej z AI. Startowanie tak późno od zera do walki z Claude CLI? Brzmi jak szaleństwo, ale po kilku dniach z Vibe stwierdziłem, że choć to dość prosty program, to robi co trzeba i jest imponująco szybki. Bez zarzutu łączy się z IntelliJ (tak, to przytyk do was, twórcy Copilota!).

To nie jest tekst sponsorowany. Nie mam też kodów zniżkowych ani gadżetów – piszę, bo lubię, nie ma tu ukrytych haczyków.

W dalszej części tekstu pokażę w dużym skrócie, jak wygląda Vibe samodzielnie w terminalu oraz zintegrowany z IntelliJ. Opowiem o odczuciach względem Devstrala z punktu widzenia człowieka przyzwyczajonego do flagowych modeli typu Claude Opus. Postaram się też przejrzyście pokazać, na ile atrakcyjna jest cena w porównaniu z konkurencją.

Czytaj dalej „Mistral Vibe: szybki, tani i europejski AI”

Nowy BIOS naprawił pracę na baterii i… klawiaturę

Lubicie aktualizować BIOS? Myślę, że dla wielu to czynność równie ekscytująca jak wizyta u dentysty. Może więc zaciekawi was historia, gdzie aktualizując BIOS w moim laptopie HP EliteBook nie tylko pozbyłem się freeze’ów przy pracy na baterii, ale też rozwiązałem problem, którego nigdy w życiu bym nie podejrzewał o związek z jakimikolwiek łatkami w oprogramowaniu. Wbudowana klawiatura ponownie zaczęła nadawać się do użytku. Do pozytywnych niespodzianek dorzucam pracę wyświetlacza, który w moim subiektywnym odczuciu daje czystszy obraz przy pracy z okienkami.

Co ciekawe, BIOS (a dokładniej UEFI) dał się zaktualizować bardzo szybko i wygodnie, nie był potrzebny nawet pendrive.

Czytaj dalej „Nowy BIOS naprawił pracę na baterii i… klawiaturę”

Spring Kafka z obsługą Retry-After

Biblioteka Spring Kafka umożliwia obsługę błędów przez sprawdzony mechanizm exponential back-off. Jednak jeśli błędem jest HTTP 429 „Too Many Requests” (czyli rate limiting), zwykłe wykładnicze zwiększanie przerw między kolejnymi próbami jest trochę jak atak brute force: marnujemy zasoby na próbowanie przed czasem, albo marnujemy czas czekając za długo. Lepiej byłoby czekać dokładnie tyle, ile wysyła serwer.

W dalszej części pokażę, jak podejść do implementacji. W dużym skrócie, wystarczy napisanie jednej nieskomplikowanej klasy.

Czytaj dalej „Spring Kafka z obsługą Retry-After”

Wyciszanie śmiecących logów Springa przy kończeniu testów

Wielowątkowe testy (takie jak używające Kafki) są źródłem kłopotów. Na przykład zaśmiecają przebieg buildu w Gradle’u.

Normalnie Gradle przechwytuje stdout i stderr z testów, przerzuca je do raportów HTML-owych, a terminal zachowuje czysty:

> Task :my-module:testClasses
> Task :my-module:test

Moduły korzystające ze Springa i uruchamiające wiele wątków potrafią kompletnie zabić czytelność terminala:

> Task :my-module:testClasses
INFO [ntainer#0-0-C-1] o.a.k.c.c.internals.ConsumerCoordinator  : [Consumer clientId=consumer-my.event-2, groupId=my.event] Revoke previously assigned partitions my.event-0, my.event-1, my.event-2
20
ERROR [sson-netty-1-15] i.n.u.c.D.rejectedExecution             : Failed to submit a listener notification task. Event loop shut down?
java.util.concurrent.RejectedExecutionException: event executor terminated
	at io.netty.util.concurrent.SingleThreadEventExecutor.reject(SingleThreadEventExecutor.java:934)
> Task :my-module:test

Łatwo może się zdarzyć, że dostaniemy ponad 100 niechcianych śmieciowych linii.

W dalszej części artykułu objaśnię, co w działaniu biblioteki spring-test powoduje taki zgrzyt w integracji z Gradle’em. Zaproponuję też obejście problemu za pomocą specjalnego beana wyłączającego część logowania.

Czytaj dalej „Wyciszanie śmiecących logów Springa przy kończeniu testów”

Pułapki transakcji Springa dla programistów Kotlina

Wydaje się, że Spring i Kotlin to dobre połączenie. Z jednej strony najbardziej popularny framework dla Javy, ale deklarujący wsparcie dla języka od JetBrains. Z drugiej Kotlin został zaprojektowany dla jak największej kompatybilności z Javą. Na papierze i w ogłoszeniach na social mediach wszystko gra. Tyle że w rzeczywistości można bardzo nieprzyjemnie się zaskoczyć, niestety zazwyczaj dopiero na produkcji.

Problem będący głownym bohaterem tego artykułu leży w różnym podejściu do wyjątków w obu światach.

Pisząc w Kotlinie można zapomnieć o dyskusjach programistów Javy, czy wyjątek ma być checked czy nie. Jeśli w repozytorium piszemy wyłącznie w jednym języku, wszystko nam jedno i nie trzeba sobie tym zawracać głowy. Chyba że kod działa w Springu. Wtedy brak uwagi kończy się zobaczeniem UnexpectedRollbackException: Transaction silently rolled back because it has been marked as rollback-only. Zgodnie ze słowami 'unexpected’ i 'silent’, jest to sytuacja zaskakująca, a do tego upierdliwa w zdiagnozowaniu.

Czytaj dalej „Pułapki transakcji Springa dla programistów Kotlina”

ArchUnit czy Konsist: testy architektury dla Kotlina

Posiadanie w projekcie testów architektury (architecture tests) powoli staje się czymś oczekiwanym. Użytkownicy Kotlina od niedawna mają problem bogactwa wyboru. Mogą użyć biblioteki ArchUnit, już ustabilizowanej, całkiem szeroko znanej, stworzonej dla Javy, ale działającej też dla Kotlina. Pojawiła się jednak alternatywa. Konsist to narzędzie napisane specjalnie pod Kotlina, o krótszej historii, ale zdobywające popularność.

W dalszej części artykułu porównam ze sobą te biblioteki. Nie będę kopiował haseł reklamowych: zawodowo używam obu od ponad roku, więc mam sporo obserwacji natury praktycznej.

Po lekturze będziesz (mam nadzieję) wiedzieć, czy do twojej sytuacji bardziej będzie pasować ArchUnit, czy też Konsist, a może potrzebujesz obu.

Moim celem jest porównanie, więc nie omówię wszystkich cech obu narzędzi i będę się streszczał. Spragnionym szczegółów na temat konkretnej biblioteki polecam moje wcześniejsze artykuły: wprowadzenie do ArchUnita, wprowadzenie do Konsista.

Artykuł jest skierowany do programistów Kotlina. Jeśli programujesz tylko w Javie, to z Konsista nie skorzystasz, bo obsługuje tylko język od JetBrains. Mimo wszystko, polecam pod uwagę wyliczenie niedostatków ArchUnita – nie podaję tu lepszego narzędzia do Javy, ale moim zdaniem lepiej znać wady swojego narzędzia, niż ich nie znać.

Czytaj dalej „ArchUnit czy Konsist: testy architektury dla Kotlina”

Konsist – rzut oka na nowe testy architektury dla Kotlina

Biblioteka Konsist to nowy gracz na rynku narzędzi dla Kotlina. Umożliwia tworzenie testów architektury, ale zarówno sposób pisania, jak i zasada działania różnią się mocno od najpopularniejszego dotychczas narzędzia w świecie JVM, czyli ArchUnita. W tym artykule pokażę krótko, jak wygląda używanie Konsista w praktyce.

Nie lubię nazwy „testy architektury”, bo kojarzy mi się z architektem-mądralą, który pilnuje, czy warstwy zgadzają się z jego podręcznikiem, albo czymś równie oderwanym od realnych problemów. Jednak innej nazwy nie mamy, więc zostaje mi tylko zapewnienie, że takie testy mogą mieć bardzo konkretne, życiowe użycie, a pisać może je każdy, nawet jeśli nie ma „principal senior lead architect” w tytule zawodowym. To taki linter z regułami, które sami piszemy. Warto umieć je pisać, nawet jeśli jest się juniorem.

Nie będę kopiował strony domowej Konsista. Moje przykłady pochodzą z prawdziwych, zawodowych projektów, jakie tworzę. Są tylko trochę uproszczone.

Ten artykuł ma zamiar być krótkim wprowadzeniem, żebyście lepiej zrozumieli, co bierzecie albo czego będziecie odtąd unikać. Nie będę porównywał Konsista z ArchUnitem. Napisałem o tym osobny tekst. Nie będę też omawiał każdej możliwości Konsista. Od tego macie oficjalną dokumentację.

Czytaj dalej „Konsist – rzut oka na nowe testy architektury dla Kotlina”

ArchUnit – praktyczne zastosowanie

W artykule o podstawach ArchUnita przedstawiłem, jak i po co pisać testy architektury. Być może znasz temat, ale wciąż nie jesteś do końca przekonany (-a). Lub takie testy masz, ale nie są rozwijane, a nikt nie wie, co i w jakim celu do nich dodawać.

Poniższy tekst dostarcza konkretne, życiowe przykłady użycia. Są to zastosowania z innej bajki niż to, co podaje jako „use cases” oficjalna strona ArchUnita albo clickbaitowe „tutoriale” w stylu tych na Baeldungu (nie linkuję, nic nowego nie wnoszą).

Pokażę, jak stosuję ArchUnita do wykrywania pomyłek w testach. Oraz do wykluczania kodu, który źle działa w Kotlinie: Optional.orElse oraz adnotacji z jakarta.annotation.

Mam nadzieję, że te przykłady pomogą ci lepiej zrozumieć potencjał testów architektury, oraz dostarczą nowych inspiracji do pisania własnych, dostosowanych do potrzeb twojego projektu. Możesz też podany tu kod po prostu skopiować do siebie (udostępniam go na licencji MIT).

Czytaj dalej „ArchUnit – praktyczne zastosowanie”

Quartz czyli scheduling ze śmietnika historii

Quartz to narzędzie, które jest niestety popularnym wynikiem przy wyszukiwaniu haseł „scheduler”, „job”, „Java”. Strona domowa projektu tytułuje się „Enterprise Job Scheduler”. „Enterprise” ma sugerować, że to rozwiązanie poważne, więcej: skalowalne na duże projekty. W ramach wzbogacenia dyskusji chciałbym dorzucić inną opinię: że Quartz to niebezpieczny szrot, którego nieusuwalne wady mogą zarżnąć waszą produktywność i spowodować incydenty na produkcji.

Przejdziemy od kodu z błędami N+1 zapytań, przez alarmujący stan projektu, do architektury z single point of failure.

Czytaj dalej „Quartz czyli scheduling ze śmietnika historii”
Creative Commons License
Except where otherwise noted, the content by Piotr Kubowicz is licensed under a Creative Commons Attribution 4.0 International License.