{"id":27532,"date":"2024-05-07T05:00:00","date_gmt":"2024-05-07T03:00:00","guid":{"rendered":"https:\/\/sii.pl\/blog\/?p=27532"},"modified":"2024-05-02T11:10:22","modified_gmt":"2024-05-02T09:10:22","slug":"wykorzystanie-gitlab-ci-we-wdrozeniu-ci-cd","status":"publish","type":"post","link":"https:\/\/sii.pl\/blog\/wykorzystanie-gitlab-ci-we-wdrozeniu-ci-cd\/","title":{"rendered":"Wykorzystanie Gitlab CI we wdro\u017ceniu CI\/CD"},"content":{"rendered":"\n<p>W zespo\u0142ach developerskich stawiaj\u0105cych na szybkie i cz\u0119ste dostarczanie oraz testowanie oprogramowania jedn\u0105 z pierwszych rzeczy, kt\u00f3ra powinna zosta\u0107 wdro\u017cona, jest proces ci\u0105g\u0142ej integracji i ci\u0105g\u0142ego dostarczania, czyli ang. <a aria-label=\" (opens in a new tab)\" href=\"https:\/\/sii.pl\/blog\/continuous-integration-i-continuous-delivery-dobre-praktyki\/\" target=\"_blank\" rel=\"noreferrer noopener\" class=\"ek-link\">Continuous Integration\/Continuous Delivery (CI\/CD)<\/a>.<\/p>\n\n\n\n<p>W du\u017cym skr\u00f3cie \u2013 powinni\u015bmy stworzy\u0107 automat, kt\u00f3ry w czasie rzeczywistym b\u0119dzie reagowa\u0142 na operacje zachodz\u0105ce w naszym repozytorium i w oparciu o najnowsz\u0105 wersj\u0119 kodu wykona kolejne kroki, takie jak:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>kompilacja,<\/li>\n\n\n\n<li>testy,<\/li>\n\n\n\n<li>wdro\u017cenie na \u015brodowiska,<\/li>\n\n\n\n<li>powiadomienie o ewentualnych b\u0142\u0119dach autora wprowadzanej zmiany.<\/li>\n<\/ul>\n\n\n\n<p>Oczywi\u015bcie, proces ten powinien inaczej reagowa\u0107 na zmiany w repozytorium g\u0142\u00f3wnym, deweloperskim, a jeszcze inaczej w ga\u0142\u0119ziach pobocznych \u2013 to wszystko trzeba najpierw dok\u0142adnie om\u00f3wi\u0107 wewn\u0105trz zespo\u0142u projektowego, uwzgl\u0119dniaj\u0105c ustalony wcze\u015bniej flow, aby w nast\u0119pnym kroku poprawnie skonfigurowa\u0107 w narz\u0119dziu do CI\/CD.<\/p>\n\n\n\n<p>Z artyku\u0142u dowiecie si\u0119, jak i dlaczego warto w tym procesie wykorzysta\u0107 Gitlab CI.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Implementacja procesu<\/strong><\/h2>\n\n\n\n<p>Jest wiele aplikacji, takich jak Jenkins czy TeamCity, kt\u00f3re \u015bwietnie radz\u0105 sobie z implementacj\u0105 procesu i ka\u017cda z nich ma swoich zwolennik\u00f3w. Jednak wszystkie \u0142\u0105czy <strong>wsp\u00f3lna wada<\/strong> \u2013 s\u0105 kolejnym narz\u0119dziem w naszym stacku technologicznym i b\u0119d\u0105 wymaga\u0142y dodatkowych zasob\u00f3w, czyli czasu osoby, kt\u00f3ra zadba o poprawn\u0105 integracj\u0119 z repozytorium kodu, we\u017amie na siebie nadawanie odpowiednich uprawnie\u0144 dla u\u017cytkownik\u00f3w, czy wreszcie b\u0119dzie musia\u0142a zaj\u0105\u0107 si\u0119 monitorowaniem i utrzymywaniem maszyny, na kt\u00f3rej ta aplikacja b\u0119dzie uruchomiona.<\/p>\n\n\n\n<p>I tutaj pojawia si\u0119 alternatywa: je\u017celi kod przechowywany jest w repozytorium GitLab, to zamiast poszukiwa\u0107 zewn\u0119trznych rozwi\u0105za\u0144, mo\u017cna skorzysta\u0107 z wbudowanego narz\u0119dzia do ci\u0105g\u0142ej integracji zwanego GitLab CI.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/05\/CICD.png\"><img decoding=\"async\" width=\"612\" height=\"289\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/05\/CICD.png\" alt=\"P\u0142ynne przechodzenie CI w CD\" class=\"wp-image-27551\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/05\/CICD.png 612w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/05\/CICD-300x142.png 300w\" sizes=\"(max-width: 612px) 100vw, 612px\" \/><\/a><figcaption class=\"wp-element-caption\">Ryc. 1 <a href=\"https:\/\/sii.pl\/blog\/continuous-integration-i-continuous-delivery-dobre-praktyki\/\" target=\"_blank\" aria-label=\"P\u0142ynne przechodzenie CI w CD (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\">P\u0142ynne przechodzenie CI w CD<\/a><\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Gitlab CI<\/strong><\/h2>\n\n\n\n<p>Skoro Gitlab CI nie wymaga dodatkowej integracji z repozytorium kodu, to sk\u0105d projekt \u201ewie\u201d, \u017ce ma go u\u017cywa\u0107? Poniewa\u017c <strong>CI samo w sobie jest cz\u0119\u015bci\u0105 projektu<\/strong>, a dok\u0142adniej plik gitlab-ci ,napisany w j\u0119zyku formalnym YAML u\u017cywanym te\u017c mi\u0119dzy innymi do pisania manifest\u00f3w Kubernetesa czy Ansible.<\/p>\n\n\n\n<p>Plik ten umieszczony w katalogu g\u0142\u00f3wnym definiuje ca\u0142\u0105 list\u0119 krok\u00f3w wykonywanych przy okazji ka\u017cdej zmiany kodu \u017ar\u00f3d\u0142owego w projekcie \u2013 oczywi\u015bcie w oparciu o odpowiednie regu\u0142y. Jest to spore u\u0142atwienie, kt\u00f3re dodatkowo pozwala na wersjonowanie zmian samego CI\/CD wraz z ca\u0142ym projektem i sprawia, \u017ce w bardzo \u0142atwy spos\u00f3b mo\u017ce by\u0107 on migrowany i wsp\u00f3\u0142dzielony.<\/p>\n\n\n\n<p>Dodatkowo GitLab udost\u0119pnia w swoim GUI edytor pipeline\u2019\u00f3w, kt\u00f3ry jest po prostu edytorem tekstowym naszego pliku yaml i ma sprawi\u0107, \u017ce praca nad CI\/CD b\u0119dzie \u0142atwa, szybka i przyjemna, pomimo zachowania wszelkich regu\u0142 obowi\u0105zuj\u0105cych w repozytorium kodu. Sama konfiguracja gitlab-ci mo\u017ce te\u017c pom\u00f3c w utrzymywaniu standard\u00f3w wytwarzania oprogramowania w obr\u0119bie organizacji poprzez include przygotowanego wcze\u015bniej wsp\u00f3lnego pliku przechowywanego w globalnym repozytorium. Jednak na tym etapie skupi\u0119 si\u0119 na mo\u017cliwie jak najprostszym przypadku.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/05\/templates.png\"><img decoding=\"async\" width=\"682\" height=\"98\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/05\/templates.png\" alt=\"Gitlab CI GUI\" class=\"wp-image-27554\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/05\/templates.png 682w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/05\/templates-300x43.png 300w\" sizes=\"(max-width: 682px) 100vw, 682px\" \/><\/a><figcaption class=\"wp-element-caption\">Ryc. 2 Gitlab CI GUI<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Konfiguracja Gitlab CI<\/strong><\/h2>\n\n\n\n<p>W pliku gitlab-ci.yaml opisujemy kolejne etapy procesu CI\/CD, czyli tak zwany pipeline, kt\u00f3rego zawarto\u015b\u0107 odczytywana jest w momencie wykonania w repozytorium polecenia git push.<\/p>\n\n\n\n<p>Podstawow\u0105 jednostk\u0105 opisuj\u0105c\u0105 ten proces jest zadanie (ang. job), czyli definicja jednego lub kilku polece\u0144 wraz z warunkami, w jakich zostan\u0105 one uruchomione. Polecenia te, zawarte w sekcji scripts, mog\u0105 by\u0107 na przyk\u0142ad:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>uruchomieniem narz\u0119dzi typu maven czy docker,<\/li>\n\n\n\n<li>poleceniem systemowym,<\/li>\n\n\n\n<li>przypisaniem zmiennej \u015brodowiskowej.<\/li>\n<\/ul>\n\n\n\n<p>W przypadku komend s\u0142u\u017c\u0105cych do przygotowania \u015brodowiska warto dodatkowo stworzy\u0107 sekcj\u0119 before_script, kt\u00f3ra zostanie wykonana przed w\u0142a\u015bciwym skryptem.<\/p>\n\n\n\n<p>Kiedy mamy ju\u017c zdefiniowane zadania, mo\u017cemy je pogrupowa\u0107 w kolejne etapy (ang. stages), takie jak:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>build,<\/li>\n\n\n\n<li>test,<\/li>\n\n\n\n<li>deploy.<\/li>\n<\/ul>\n\n\n\n<p>B\u0119d\u0105 one uruchomione w kolejno\u015bci, w jakiej zosta\u0142y zdefiniowane.<\/p>\n\n\n\n<p>Za\u0142\u00f3\u017cmy, \u017ce mamy ju\u017c w\u0142asne skrypty do kompilowania, testowania i deploymentu i chcemy je wykorzysta\u0107 w naszym procesie CI\/CD. Plik gitlab-ci.yaml m\u00f3g\u0142by wygl\u0105da\u0107 nast\u0119puj\u0105co:<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/05\/editor.png\"><img decoding=\"async\" width=\"816\" height=\"745\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/05\/editor.png\" alt=\"Plik gitlab-ci.yaml\" class=\"wp-image-27556\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/05\/editor.png 816w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/05\/editor-300x274.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/05\/editor-768x701.png 768w\" sizes=\"(max-width: 816px) 100vw, 816px\" \/><\/a><figcaption class=\"wp-element-caption\">Ryc. 3 Plik gitlab-ci.yaml<\/figcaption><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Kolejne kroki<\/strong><\/h3>\n\n\n\n<p>Tak jak wspomnia\u0142em, ka\u017cdy poprawnie napisany pipeline, powinien <strong>rozr\u00f3\u017cnia\u0107 dzia\u0142ania<\/strong>, jakie ma podj\u0105\u0107 w zale\u017cno\u015bci od brancha, w jakim si\u0119 znajduje. Jako \u017ce gitlab-ci.yaml jest integraln\u0105 cz\u0119\u015bci\u0105 projektu, nie b\u0119dzie przechowywa\u0107 kilku r\u00f3\u017cnych wersji w zale\u017cno\u015bci od tego, w kt\u00f3rej ga\u0142\u0119zi si\u0119 znajduje, a w zamian za to u\u017cyje warunku uruchomienia dla ka\u017cdego etapu.<\/p>\n\n\n\n<p><strong>Opcja \u201eonly\u201d<\/strong> s\u0142u\u017cy do okre\u015blenia, \u017ce ma by\u0107 uruchomiony tylko wtedy, gdy spe\u0142nione s\u0105 warunki, co w po\u0142\u0105czeniu z <strong>warunkiem \u201erefs\u201d<\/strong> pozwala nam zdefiniowa\u0107 zale\u017cno\u015b\u0107, aby dany etap by\u0142 uruchomiony tylko dla okre\u015blonej ga\u0142\u0119zi. Jego przeciwie\u0144stwem jest <strong>opcja \u201eexpect\u201d<\/strong>, kt\u00f3ra pozwala wykluczy\u0107 nasz etap z listy.<\/p>\n\n\n\n<p>Samo <strong>warunkowanie ma du\u017co szersze zastosowanie<\/strong>. Mamy mo\u017cliwo\u015b\u0107 np.: uruchomienia danego etapu tylko w przypadku ustawienia odpowiedniej zmiennej \u015brodowiskowej albo jedynie, gdy nast\u0105pi zmiana w okre\u015blonych plikach. Zamiast ogranicza\u0107 za pomoc\u0105 nazwy ga\u0142\u0119zi mo\u017cemy tak\u017ce u\u017cy\u0107 tag\u00f3w, w\u0142\u0105czaj\u0105c w to wyra\u017cenia regularne.<\/p>\n\n\n\n<p>Dodajmy zatem do naszego pipeline\u2019a nast\u0119puj\u0105ce warunki:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Ka\u017cdy etap uruchamia si\u0119 jedynie w przypadku zmian w plikach z rozszerzeniem .py.<\/li>\n\n\n\n<li>Skrypt testuj\u0105cy uruchamiamy tylko w przypadku brancha \u201emaster\u201d.<\/li>\n\n\n\n<li>\u201eDeployment\u201d startuje tylko wtedy, kiedy warto\u015b\u0107 DEPLOYMENT jest prawdziwa.<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Runnery<\/strong><\/h3>\n\n\n\n<p>Czy to oznacza, \u017ce od posiadania pe\u0142noprawnego CI\/CD dzieli nas ju\u017c tylko wpisanie (albo wklejenie) w edytor kilkunastu linijek kodu? I tak i nie, poniewa\u017c GitLab CI do uruchomienia potrzebuje runner\u00f3w, czyli <strong>niezale\u017cnych host\u00f3w<\/strong>, na kt\u00f3rych b\u0119d\u0105 uruchamiane wszystkie zdefiniowane przez nas kroki.<\/p>\n\n\n\n<p>W GitLab CI mo\u017cemy korzysta\u0107 zar\u00f3wno z <strong>runner\u00f3w publicznych<\/strong>, jak i prywatnych. Pierwsze rozwi\u0105zanie b\u0119dzie oczywi\u015bcie szybsze, natomiast je\u017celi zale\u017cy nam na odpowiedniej konfiguracji do potrzeb projektu, w\u0142\u0105czaj\u0105c w to w\u0142a\u015bciwy system operacyjny oraz wszystkie niezb\u0119dne aplikacje i rozszerzenia, kt\u00f3rych u\u017cywamy do budowania i wdra\u017cania projektu, powinni\u015bmy mie\u0107 <strong>runner prywatny<\/strong>. Albo u\u017cy\u0107 odpowiedniego <strong>obrazu Dockera<\/strong>, do czego jeszcze wr\u00f3c\u0119.<\/p>\n\n\n\n<p>Wi\u0119cej o tym, jak skonfigurowa\u0107 runnery, znajdziemy tutaj [<a aria-label=\"link do dokumentacji (opens in a new tab)\" href=\"https:\/\/docs.gitlab.com\/runner\/\" target=\"_blank\" rel=\"noreferrer noopener\" class=\"ek-link\" rel=\"nofollow\" >link do dokumentacji<\/a>].<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/05\/runners.png\"><img decoding=\"async\" width=\"1024\" height=\"543\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/05\/runners-1024x543.png\" alt=\"Ekran runner\u00f3w\" class=\"wp-image-27558\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/05\/runners-1024x543.png 1024w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/05\/runners-300x159.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/05\/runners-768x407.png 768w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/05\/runners-1536x814.png 1536w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/05\/runners.png 1564w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Ryc. 4 Ekran runner\u00f3w<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Uruchomienie<\/strong><\/h2>\n\n\n\n<p>Skoro mamy ju\u017c gotowy pipeline (oraz przygotowane runnery), to najwy\u017csza pora, aby go uruchomi\u0107 i sprawdzi\u0107, czy rzeczywi\u015bcie wykonuje dok\u0142adnie to, co sobie w nim zdefiniowali\u015bmy.<\/p>\n\n\n\n<p>Gitlab udost\u0119pnia graficzn\u0105 wizualizacj\u0119 pipeline\u2019\u00f3w, kt\u00f3ra pozwala na \u0142atwe zrozumienie tego, co dzieje si\u0119 w ramach naszego CI\/CD oraz informuje nas o statusie ka\u017cdego z etap\u00f3w.<\/p>\n\n\n\n<p>Ka\u017cdy etap jest reprezentowany przez osobn\u0105 kolumn\u0119 i poza list\u0105 zdefiniowanych w nim zada\u0144, udost\u0119pnia takie informacje jak czas ich wykonywania oraz nazwy maszyn wirtualnych, na kt\u00f3rych zosta\u0142y uruchomione.<\/p>\n\n\n\n<p>Z poziomu wizualizacji mo\u017cemy te\u017c \u0142atwo uruchamia\u0107 lub anulowa\u0107 poszczeg\u00f3lne pipeline\u2019y, a tak\u017ce analizowa\u0107 logi, czy sprawdza\u0107 warto\u015bci zwracane przez nasze skrypty, co mo\u017ce by\u0107 szczeg\u00f3lnie pomocne przy szybkiej identyfikacji ewentualnych problem\u00f3w i b\u0142\u0119d\u00f3w pojawiaj\u0105cych si\u0119 wraz ze wzrostem z\u0142o\u017cono\u015bci projektu.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Docker jako alternatywa<\/h2>\n\n\n\n<p>Na koniec wr\u00f3c\u0119 jeszcze do runner\u00f3w, poniewa\u017c aby jakakolwiek komenda zdefiniowana w jobie wykona\u0142a si\u0119 poprawnie, musi by\u0107 znana w \u015brodowisku, w kt\u00f3rym si\u0119 wykonuje. Je\u017celi zatem chcemy uruchomi\u0107 nasze skrypty, to musz\u0105 si\u0119 one znajdowa\u0107 na naszym runnerze, podobnie jak ka\u017cde inne potrzebne narz\u0119dzia oraz biblioteki.<\/p>\n\n\n\n<p>W przypadku posiadania ograniczonej puli runner\u00f3w i wi\u0119kszej liczby projekt\u00f3w robi si\u0119 to nieco k\u0142opotliwe, dlatego dobrym rozwi\u0105zaniem mog\u0105 okaza\u0107 si\u0119 obrazy dockerowe, kt\u00f3re po skonfigurowaniu i dodaniu do pliku konfiguracyjnego b\u0119d\u0105 u\u017cywane w procesie CI\/CD.<\/p>\n\n\n\n<p>Mog\u0105 to by\u0107 standardowe obrazy typu node:10, albo, je\u017celi mamy specyficzne wymagania dotycz\u0105ce \u015brodowiska budowania, w\u0142asne \u2013 pod warunkiem, \u017ce zostan\u0105 one wcze\u015bniej zarejestrowane w zdalnym repozytorium takim jak np. Docker Hub.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/05\/pipeline.png.png\"><img decoding=\"async\" width=\"642\" height=\"240\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/05\/pipeline.png.png\" alt=\"Graficzna wizualizacja pipeline\" class=\"wp-image-27560\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/05\/pipeline.png.png 642w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/05\/pipeline.png-300x112.png 300w\" sizes=\"(max-width: 642px) 100vw, 642px\" \/><\/a><figcaption class=\"wp-element-caption\">Ryc. 5 Graficzna wizualizacja pipeline<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/05\/pipeline1.png\"><img decoding=\"async\" width=\"1024\" height=\"244\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/05\/pipeline1-1024x244.png\" alt=\"Graficzna wizualizacja pipeline\" class=\"wp-image-27562\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/05\/pipeline1-1024x244.png 1024w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/05\/pipeline1-300x71.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/05\/pipeline1-768x183.png 768w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/05\/pipeline1-1536x365.png 1536w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/05\/pipeline1.png 1736w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Ryc. 6 Graficzna wizualizacja pipeline<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Podsumowanie<\/strong><\/h2>\n\n\n\n<p>Podsumowuj\u0105c, Gitlab CI to wszechstronne i elastyczne narz\u0119dzie do zarz\u0105dzania procesem Continuous Integration\/Continuous Delivery, kt\u00f3re dzi\u0119ki bezpo\u015bredniej integracji z platform\u0105 GitLab umo\u017cliwia \u0142atwe zarz\u0105dzanie projektem i wsp\u00f3\u0142prac\u0119 zespo\u0142u. <strong>Jest intuicyjne, \u0142atwe w konfiguracji<\/strong>, a jednocze\u015bnie daje <strong>du\u017ce mo\u017cliwo\u015bci do debuggowania i monitorowania pipeline\u2019\u00f3w<\/strong>, dlatego warto si\u0119 nim zainteresowa\u0107, gdy planujemy wprowadzi\u0107 proces CI\/CD w naszym projekcie.<\/p>\n\n\n\n<p>***<\/p>\n\n\n\n<p>Je\u015bli interesuj\u0105 Ci\u0119 <a href=\"https:\/\/sii.pl\/blog\/continuous-integration-i-continuous-delivery-dobre-praktyki\/\" target=\"_blank\" aria-label=\"dobre praktyki we wdro\u017ceniu CI\/CD (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\">dobre praktyki we wdro\u017ceniu CI\/CD<\/a>, zajrzyj koniecznie r\u00f3wnie\u017c do innego artyku\u0142u autorstwa naszego specjalisty. <\/p>\n\n\n<div class=\"kk-star-ratings kksr-auto kksr-align-left kksr-valign-bottom\"\n    data-payload='{&quot;align&quot;:&quot;left&quot;,&quot;id&quot;:&quot;27532&quot;,&quot;slug&quot;:&quot;default&quot;,&quot;valign&quot;:&quot;bottom&quot;,&quot;ignore&quot;:&quot;&quot;,&quot;reference&quot;:&quot;auto&quot;,&quot;class&quot;:&quot;&quot;,&quot;count&quot;:&quot;4&quot;,&quot;legendonly&quot;:&quot;&quot;,&quot;readonly&quot;:&quot;&quot;,&quot;score&quot;:&quot;5&quot;,&quot;starsonly&quot;:&quot;&quot;,&quot;best&quot;:&quot;5&quot;,&quot;gap&quot;:&quot;11&quot;,&quot;greet&quot;:&quot;&quot;,&quot;legend&quot;:&quot;5\\\/5 ( votes: 4)&quot;,&quot;size&quot;:&quot;18&quot;,&quot;title&quot;:&quot;Wykorzystanie Gitlab CI we wdro\u017ceniu CI\\\/CD&quot;,&quot;width&quot;:&quot;139.5&quot;,&quot;_legend&quot;:&quot;{score}\\\/{best} ( {votes}: {count})&quot;,&quot;font_factor&quot;:&quot;1.25&quot;}'>\n            \n<div class=\"kksr-stars\">\n    \n<div class=\"kksr-stars-inactive\">\n            <div class=\"kksr-star\" data-star=\"1\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"2\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"3\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"4\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"5\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n    <\/div>\n    \n<div class=\"kksr-stars-active\" style=\"width: 139.5px;\">\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n    <\/div>\n<\/div>\n                \n\n<div class=\"kksr-legend\" style=\"font-size: 14.4px;\">\n            5\/5 ( votes: 4)    <\/div>\n    <\/div>\n","protected":false},"excerpt":{"rendered":"<p>W zespo\u0142ach developerskich stawiaj\u0105cych na szybkie i cz\u0119ste dostarczanie oraz testowanie oprogramowania jedn\u0105 z pierwszych rzeczy, kt\u00f3ra powinna zosta\u0107 wdro\u017cona, &hellip; <a class=\"continued-btn\" href=\"https:\/\/sii.pl\/blog\/wykorzystanie-gitlab-ci-we-wdrozeniu-ci-cd\/\">Continued<\/a><\/p>\n","protected":false},"author":629,"featured_media":27537,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_editorskit_title_hidden":false,"_editorskit_reading_time":0,"_editorskit_is_block_options_detached":false,"_editorskit_block_options_position":"{}","inline_featured_image":false,"footnotes":""},"categories":[1316],"tags":[2201,1546,1512,1246,698],"class_list":["post-27532","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-development-na-miekko","tag-gitlab-ci","tag-przeglad-narzedzi","tag-poradnik","tag-continuous-delivery","tag-continuous-integration"],"acf":[],"aioseo_notices":[],"republish_history":[],"featured_media_url":"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/04\/Wykorzystanie-Gitlab-CI-we-wdrozeniu-CICD.jpg","category_names":["Development na mi\u0119kko"],"_links":{"self":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts\/27532"}],"collection":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/users\/629"}],"replies":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/comments?post=27532"}],"version-history":[{"count":2,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts\/27532\/revisions"}],"predecessor-version":[{"id":27564,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts\/27532\/revisions\/27564"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/media\/27537"}],"wp:attachment":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/media?parent=27532"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/categories?post=27532"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/tags?post=27532"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}