{"id":13480,"date":"2022-04-19T07:00:58","date_gmt":"2022-04-19T05:00:58","guid":{"rendered":"https:\/\/sii.pl\/blog\/?p=13480"},"modified":"2023-05-08T16:13:32","modified_gmt":"2023-05-08T14:13:32","slug":"continuous-integration-i-continuous-delivery-dobre-praktyki","status":"publish","type":"post","link":"https:\/\/sii.pl\/blog\/continuous-integration-i-continuous-delivery-dobre-praktyki\/","title":{"rendered":"Continuous Integration i Continuous Delivery \u2013 Dobre praktyki"},"content":{"rendered":"\n<p>Jednym z najwi\u0119kszych wyzwa\u0144 w rozwoju oprogramowania jest dostarczanie wysokiej jako\u015bci rozwi\u0105za\u0144 programistycznych w mo\u017cliwie kr\u00f3tkim czasie. Dbanie o jako\u015b\u0107 w ca\u0142ym projekcie jest najcz\u0119\u015bciej rol\u0105 Quality Assurance (QA). Piastuj\u0105c rol\u0119 QA, nale\u017cy budowa\u0107 strategi\u0119 i podejmowa\u0107 w\u0142a\u015bciwe decyzje odno\u015bnie sposobu zapewnienia odpowiedniego poziomu jako\u015bci kodu.<\/p>\n\n\n\n<p>Wprowadzaj\u0105c i nadzoruj\u0105c procesy, trzeba pami\u0119ta\u0107, \u017ce konieczna jest bliska wsp\u00f3\u0142praca \u015brodowisk programistycznych i zespo\u0142\u00f3w testerskich. Do wsparcia nale\u017cy zaanga\u017cowa\u0107 zespo\u0142y DevOps, kt\u00f3re bazuj\u0105c na do\u015bwiadczeniu, mog\u0105 zaproponowa\u0107 i zbudowa\u0107 odpowiednie \u015brodowisko. <\/p>\n\n\n\n<p>W celu spe\u0142niania tych wymaga\u0144 proponuj\u0119 wdro\u017cenie CI\/CD, o kt\u00f3rym opowiem w niniejszym artykule.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Wdro\u017cenie CI\/CD<\/strong><\/h2>\n\n\n\n<p><strong>Ci\u0105g\u0142a Integracja (ang. Continuous Integration, CI<\/strong>) i <strong>Ci\u0105g\u0142e Dostarczanie (ang. Continuous Delivery)<\/strong> to zbi\u00f3r zasad, wytycznych, kultura pracy i kolekcja dobrych praktyk zwi\u0105zanych z pracy nad projektami informatycznymi.<\/p>\n\n\n\n<p>W teorii sprowadza si\u0119 ona do zasad, w kt\u00f3rych zesp\u00f3\u0142 developer\u00f3w jest zobligowany do cz\u0119stszego dostarczania pewnych, przetestowanych i sprawdzonych zmian w kodzie.<\/p>\n\n\n\n<p>Implementacja tych zasad nazywana jest procesem CI\/CD i jest uwa\u017cana za <strong>jeden z najlepszych oraz najefektywniejszych sposob\u00f3w pracy nad projektami informatycznymi.<\/strong><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Ci\u0105g\u0142a integracja<\/strong><\/h2>\n\n\n\n<p>Ci\u0105g\u0142a integracja to praktyka polegaj\u0105ca na mo\u017cliwie cz\u0119stym i regularnym wprowadzaniu zmian w kodzie do g\u0142\u00f3wnego repozytorium, a tak\u017ce ka\u017cdorazowej weryfikacji zmian poprzez zbudowanie projektu oraz wykonaniu test\u00f3w jednostkowych. Przydatna jest r\u00f3wnie\u017c statyczna analiza kodu, kt\u00f3ra ma\u0142ym kosztem szybko wykryje b\u0142\u0119dy. <strong>Znaczenie ci\u0105g\u0142ej integracji ro\u015bnie wraz z wielko\u015bci\u0105 zespo\u0142u programistycznego.<\/strong><\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Repozytorium<\/strong><\/h3>\n\n\n\n<p>Repozytorium mo\u017cna postrzega\u0107 jako wielk\u0105 ksi\u0119g\u0119. Ka\u017cdy programista kopiuje j\u0105 i dopisuje (czasami usuwa) w\u0142asne tre\u015bci. Po zako\u0144czeniu swoich prac, ksi\u0119g\u0119 trzeba opublikowa\u0107 i scali\u0107, aby mogli pracowa\u0107 na niej inni programi\u015bci. Wpisy mog\u0105 odbywa\u0107 si\u0119 r\u00f3wnocze\u015bnie przez wiele os\u00f3b, a do porz\u0105dkowania wpis\u00f3w wykorzystuje si\u0119 systemy kontroli wersji (np. git).<\/p>\n\n\n\n<p>Je\u017celi jednak programista wprowadzi jednorazowo zbyt du\u017ce zmiany, nie zwracaj\u0105c uwagi na tre\u015bci wprowadzone w mi\u0119dzyczasie przez innych programist\u00f3w, <strong>mog\u0105\u00a0pojawi\u0107 si\u0119 problemy z integracj\u0105<\/strong>, potocznie nazywane \u201e<strong>piek\u0142em integracji<\/strong>\u201d (ang. <strong>merge hell<\/strong>). W praktyce zdarza si\u0119, \u017ce rozwiazywanie tych problem\u00f3w mo\u017ce trwa\u0107 d\u0142u\u017cej, ni\u017c przygotowanie wprowadzonej zmiany.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>TDD<\/strong><\/h3>\n\n\n\n<p>Ci\u0105g\u0142a integracja zwi\u0105zana jest z wykonywaniem zautomatyzowanych test\u00f3w jednostkowych zgodnie z metodologi\u0105 <strong>TDD (Test Driven Development<\/strong>). Przed wprowadzeniem zmian do repozytorium nale\u017cy przetestowa\u0107 sw\u00f3j kod lokalnie. Rozwi\u0105zanie to pomaga utrzyma\u0107 repozytorium w nale\u017cytym stanie. W przypadku pracy nad wi\u0119ksz\u0105 funkcjonalno\u015bci\u0105 nale\u017cy \u2013 mimo niezako\u0144czonej pracy \u2013<strong>wprowadza\u0107 zmiany do repozytorium mo\u017cliwie cz\u0119sto<\/strong>, korzystaj\u0105c z za\u015blepek i nie rezygnuj\u0105c z test\u00f3w jednostkowych.<\/p>\n\n\n\n<p>Kompilacja \u017ar\u00f3de\u0142 powinna odbywa\u0107 si\u0119 cyklicznie np. codziennie, a najlepiej nawet po ka\u017cdej zmianie do repozytorium.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Zalety Ci\u0105g\u0142ej integracji<\/strong><\/h3>\n\n\n\n<p>Wprowadzenie powy\u017cszych praktyk przynosi wiele korzy\u015bci m.in.:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><strong>Zmniejszenie koszt\u00f3w i nak\u0142ad\u00f3w pracy<\/strong> niezb\u0119dnej do \u0142\u0105czenia prac wykonanych przez r\u00f3\u017cne osoby.<\/li><li>Implementacja prawid\u0142owego procesu pozwala na wczesne wykrywanie usterek.<\/li><li>Przy wi\u0119kszych projektach zmniejsza frustracj\u0119 w\u015br\u00f3d programist\u00f3w.<\/li><\/ul>\n\n\n\n<p>Czym wi\u0119kszy zesp\u00f3\u0142 programistyczny, tym wi\u0119ksza jest korzy\u015b\u0107 z wprowadzenia rozwi\u0105zania.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Ci\u0105g\u0142e dostarczanie<\/strong><\/h2>\n\n\n\n<p><strong>Ci\u0105g\u0142e dostarczanie<\/strong> to podej\u015bcie, w kt\u00f3rym zespo\u0142y wytwarzaj\u0105 oprogramowanie w kr\u00f3tkich cyklach, zapewniaj\u0105c, \u017ce oprogramowanie mo\u017ce by\u0107 wydane w spos\u00f3b niezawodny w dowolnym momencie, a sam proces jest wykonywany ca\u0142kowicie automatycznie. Celem jest tworzenie, testowanie oraz wydawanie oprogramowania z wi\u0119ksz\u0105 szybko\u015bci\u0105 i cz\u0119stotliwo\u015bci\u0105.\u00a0Podej\u015bcie to pomaga <strong>zredukowa\u0107 koszty, czas i ryzyko<\/strong> wprowadzania zmian poprzez zwi\u0119kszenie liczby przyrostowych aktualizacji aplikacji w \u015brodowisku produkcyjnym.\u00a0<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Algorytm dla CD<\/strong><\/h3>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/05\/SchematBlokowy.png\"><img decoding=\"async\" width=\"968\" height=\"273\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/05\/SchematBlokowy.png\" alt=\"Algorytm Continuous Delivery\" class=\"wp-image-21456\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/05\/SchematBlokowy.png 968w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/05\/SchematBlokowy-300x85.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/05\/SchematBlokowy-768x217.png 768w\" sizes=\"(max-width: 968px) 100vw, 968px\" \/><\/a><figcaption>Ryc. 1 Algorytm Continuous Delivery<\/figcaption><\/figure><\/div>\n\n\n\n<ol class=\"wp-block-list\" type=\"1\"><li>Najwa\u017cniejszym elementem algorytmu jest sprz\u0119\u017cenie zwrotne, kt\u00f3re umo\u017cliwia reakcj\u0119 zespo\u0142u developerskiego w razie potrzeby. Kontrola wersji powinna by\u0107 nadzorowana przez code review. W ten spos\u00f3b jako\u015b\u0107 commitowanego kodu jest podnoszona, a <strong>dobre nawyki programistyczne s\u0105 propagowane w zespole.<\/strong><\/li><li>Po wprowadzeniu zmian do repozytorium nast\u0119puje budowanie aplikacji lub jej cz\u0119\u015bci, czyli przygotowanie kompilacji paczek z niezb\u0119dnymi komponentami np. na r\u00f3\u017cne systemy operacyjne.<\/li><li>Po kompilacji i zbudowaniu paczek nale\u017cy przeprowadzi\u0107 Podstawowe testy akceptacyjne (BAT), dzi\u0119ki temu mamy pierwsze podstawowe informacje o statusie produktu. Takie testy nazywane s\u0105 r\u00f3wnie\u017c \u201e<strong>smoke testami<\/strong>\u201d.<\/li><li>Kolejnym etapem jest walidacja i przeprowadzenie szerokiego zakresu test\u00f3w w tym test\u00f3w akceptacyjnych u\u017cytkownika. W zale\u017cno\u015bci od g\u0142\u0119boko\u015bci test\u00f3w i potrzeb mog\u0105 to by\u0107 testy nocne (nightly), kt\u00f3re pozwalaj\u0105 na zebranie wynik\u00f3w o poranku nast\u0119pnego dnia.<\/li><li>Je\u017celi jest taka potrzeba, mo\u017cna przeprowadza\u0107 d\u0142u\u017csze testy kt\u00f3re zawieraj\u0105 testy obci\u0105\u017ceniowe i wydajno\u015bciowe. Nale\u017cy w\u00f3wczas uwzgl\u0119dni\u0107 fakt, \u017ce ten rodzaj testu mo\u017ce trwa\u0107 kilka dni.<\/li><li>Na podstawie wynik\u00f3w wszystkich test\u00f3w nast\u0119puje decyzja o wydaniu produktu. Kandydata mo\u017ce cechowa\u0107 wysoka stabilno\u015b\u0107 b\u0105d\u017a implementacja nowych funkcjonalno\u015bci. <strong>Poprawne przygotowanie przypadk\u00f3w testowych pozwala na eliminacj\u0119 defekt\u00f3w ju\u017c we wcze\u015bniej fazie testowania.<\/strong><\/li><li>Dobrym zwyczajem, w przypadku wykrycia nowego defektu jest przygotowywanie nowego testu, kt\u00f3ry umo\u017cliwi wykrycie problemu w przysz\u0142o\u015bci.<\/li><\/ol>\n\n\n\n<p>Niew\u0105tpliw\u0105 zalet\u0105 tego CD jest szybsze dostarczanie rozwi\u0105za\u0144 na rynek, wi\u0119ksza produktywno\u015b\u0107 i wydajno\u015b\u0107 pracy programist\u00f3w i zespo\u0142\u00f3w powi\u0105zanych.<\/p>\n\n\n\n<p>Zauwa\u017calne jest zwi\u0119kszenie niezawodno\u015bci produktu \u2013 cz\u0119ste testowanie i rozwijanie bazy test\u00f3w powoduje dostarczenie produktu o wysokiej jako\u015bci.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Ale kto si\u0119 tym zajmie?<\/strong><\/h2>\n\n\n\n<p>Celem pracy w zespole programistycznym jest wydanie produktu. Konieczne jest zaanga\u017cowanie ca\u0142ego zespo\u0142u deweloperskiego, manager\u00f3w produktu raz manager\u00f3w projektu. Jedn\u0105 z kluczowych r\u00f3l w takim procesie odgrywa zesp\u00f3\u0142 DevOps.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/05\/DevOps_image.png\"><img decoding=\"async\" width=\"644\" height=\"690\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/05\/DevOps_image.png\" alt=\"DevOps i Manager Produktu \u2013 relacja\" class=\"wp-image-21458\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/05\/DevOps_image.png 644w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/05\/DevOps_image-280x300.png 280w\" sizes=\"(max-width: 644px) 100vw, 644px\" \/><\/a><figcaption>Ryc. 2 DevOps i Manager Produktu \u2013 relacja<\/figcaption><\/figure><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>DevOps \u2013 rola w projekcie<\/strong><\/h2>\n\n\n\n<p>DevOps (nazwa powsta\u0142a z po\u0142\u0105czenia s\u0142\u00f3w <strong>dev<\/strong>elopment i <strong>op<\/strong>erations) jest kultur\u0105 organizacyjn\u0105, maj\u0105c\u0105 za zadanie stworzy\u0107 synergi\u0119 pomi\u0119dzy dzia\u0142ami wytwarzania oprogramowania (Dev) i zarz\u0105dzania systemami (Ops). Ruch DevOps promuje p\u0142ynn\u0105 komunikacj\u0119 pomi\u0119dzy wszystkimi firmowymi zespo\u0142ami technicznymi odpowiedzialnymi za tworzenie produktu i wsp\u00f3lne dostarczanie warto\u015bci dla klienta. Dzi\u0119ki temu <strong>zmniejsza jednocze\u015bnie tarcia, do kt\u00f3rych cz\u0119sto dochodzi w klasycznych organizacjach<\/strong> z wyra\u017anym podzia\u0142em na ludzi tworz\u0105cych oprogramowanie i administrator\u00f3w system\u00f3w, kt\u00f3rzy mozolnie wdra\u017caj\u0105 stworzone oprogramowanie.<\/p>\n\n\n\n<p><strong>DevOps powinien mie\u0107 obszern\u0105 wiedz\u0105 administracyjn\u0105 jak i programistyczn\u0105.<\/strong> Musi wiedzie\u0107, jak dzia\u0142a sprawny proces CI\/CD, a jego wiedza powinna bazowa\u0107 na do\u015bwiadczeniu. Do zada\u0144 nale\u017cy przygotowanie tzw. Pipline procesu. DevOps musi przygotowa\u0107 infrastruktur\u0119 sieciow\u0105 i sprz\u0119tow\u0105, narz\u0119dzia do monitorowania, budowania. Wa\u017cny jest wyb\u00f3r narz\u0119dzi testuj\u0105cych (Test Tools). Przy konsultacji z zespo\u0142em wymagane s\u0105 wdro\u017cenia specjalistycznych rozwi\u0105za\u0144 np. do sprawdzania pokrycia testami kodu, rozwi\u0105za\u0144 antyplagiatowych, audytu \u017ar\u00f3de\u0142 kodu czy antywirus\u00f3w. Musi bra\u0107 pod uwag\u0119 cechy specyficzne projektu i pod nie projektowa\u0107 kolejne etapy.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Dobre nawyki przy wprowadzaniu CI\/CD<\/strong><\/h2>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><img decoding=\"async\" width=\"612\" height=\"289\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/05\/CICD.png\" alt=\"P\u0142ynne przechodzenie CI w CD\" class=\"wp-image-21460\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/05\/CICD.png 612w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/05\/CICD-300x142.png 300w\" sizes=\"(max-width: 612px) 100vw, 612px\" \/><figcaption>Ryc. 3 P\u0142ynne przechodzenie CI w CD<\/figcaption><\/figure><\/div>\n\n\n\n<p>Do dobrych nawyk\u00f3w nale\u017cy:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Przynajmniej raz dziennie wprowadza\u0107 zmian\u0119 na g\u0142\u00f3wne repozytorium.<\/li><li>Stara\u0107 si\u0119 wprowadza\u0107 zmiany w mo\u017cliwie ma\u0142ych blokach.<\/li><li>Oznacza\u0107 flagami znacz\u0105ce nowe funkcjonalno\u015bci.<\/li><li>Polega\u0107 na automatyzacji stabilnych test\u00f3w.<\/li><li>Naprawa buildu ma najwy\u017cszy priorytet.<\/li><li>U\u017cywa\u0107 za\u015blepek, je\u015bli nie uda\u0142o si\u0119 przygotowa\u0107 ca\u0142ej funkcjonalno\u015bci.<\/li><li>Wsp\u00f3\u0142pracowa\u0107 przy przegl\u0105dzie wprowadzanego kodu (Code Review).<\/li><li>Budowanie oraz BAT nie powinny trwa\u0107 d\u0142u\u017cej ni\u017c godzin\u0119.<\/li><li>Ka\u017cdy defekt powinien by\u0107 pokryty przypadkiem testowym.<\/li><li>Wyniki testu powinny jasno przekaza\u0107 istot\u0119 odnalezionego problemu.<\/li><li>Je\u017celi build nie dzia\u0142a, nikt nie powinien wprowadza\u0107 nowych zmian.<\/li><li>Zesp\u00f3\u0142 mo\u017ce zadecydowa\u0107, kiedy odrzuci\u0107 psuj\u0105c\u0105 zmian\u0119, a kiedy oflagowa\u0107 i wy\u0142\u0105czy\u0107 funkcjonalno\u015b\u0107.<\/li><li>Utrzymanie zdrowego procesu jest obowi\u0105zkiem wszystkich u\u017cytkownik\u00f3w procesu.<\/li><li>Wszystkie powtarzalne r\u0119cznie operacje powinny by\u0107 automatyzowane.<\/li><li>CI\/CD jest procesem, co oznacza, \u017ce zawsze jest mo\u017cliwo\u015b\u0107 udoskonalenia.<\/li><li>Je\u017celi jest wiele do udoskonalenia, nale\u017cy zacz\u0105\u0107 od najprostszych rzeczy.<\/li><\/ul>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Trudno\u015bci realizacyjne<\/strong><\/h3>\n\n\n\n<p>Oczywi\u015bcie, wprowadzenie kolejki (pipline) ma te\u017c par\u0119 wad.<\/p>\n\n\n\n<p>Szczeg\u00f3lnie w du\u017cych korporacjach samo projektowanie procesu mo\u017ce zaj\u0105\u0107 du\u017co czasu. Chocia\u017c podstawy s\u0105 podobne, to nie da si\u0119 przygotowa\u0107 jednego uniwersalnego procesu dla ka\u017cdego projektu.<\/p>\n\n\n\n<p>R\u00f3wnie\u017c przygotowanie test\u00f3w mo\u017ce by\u0107 czasoch\u0142onne. Konieczna jest analiza wymaga\u0144 projektowych, kt\u00f3re mog\u0105 by\u0107 wsparciem dla zespo\u0142u przygotowuj\u0105cego testy. Dodatkowo, trudna jest zmiana nawyk\u00f3w programist\u00f3w. Cz\u0119ste commity czy code review mog\u0105 wydawa\u0107 si\u0119 nadmiarow\u0105 prac\u0105. A pe\u0142na automatyzacja mo\u017ce zabra\u0107 prac\u0119 testerom manualnym.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Kilka s\u0142\u00f3w na koniec<\/strong><\/h2>\n\n\n\n<p>Zesp\u00f3\u0142 musi pami\u0119ta\u0107, \u017ce ka\u017cdy jest cz\u0119\u015bci\u0105 CI\/CD i na dbaniu o sprawne utrzymanie procesu korzystaj\u0105 wszyscy. Warto po\u015bwi\u0119ca\u0107 chwil\u0119 na codziennych spotkaniach (Daily) i porusza\u0107 status kolejki test\u00f3w.<\/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;13480&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;11&quot;,&quot;legendonly&quot;:&quot;&quot;,&quot;readonly&quot;:&quot;&quot;,&quot;score&quot;:&quot;4.9&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;4.9\\\/5 ( votes: 11)&quot;,&quot;size&quot;:&quot;18&quot;,&quot;title&quot;:&quot;Continuous Integration i Continuous Delivery \u2013 Dobre praktyki&quot;,&quot;width&quot;:&quot;136.6&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: 136.6px;\">\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            4.9\/5 ( votes: 11)    <\/div>\n    <\/div>\n","protected":false},"excerpt":{"rendered":"<p>Jednym z najwi\u0119kszych wyzwa\u0144 w rozwoju oprogramowania jest dostarczanie wysokiej jako\u015bci rozwi\u0105za\u0144 programistycznych w mo\u017cliwie kr\u00f3tkim czasie. Dbanie o jako\u015b\u0107 &hellip; <a class=\"continued-btn\" href=\"https:\/\/sii.pl\/blog\/continuous-integration-i-continuous-delivery-dobre-praktyki\/\">Continued<\/a><\/p>\n","protected":false},"author":251,"featured_media":13488,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_editorskit_title_hidden":false,"_editorskit_reading_time":5,"_editorskit_is_block_options_detached":false,"_editorskit_block_options_position":"{}","inline_featured_image":false,"footnotes":""},"categories":[1316],"tags":[154,1246,698,825,146],"class_list":["post-13480","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-development-na-miekko","tag-devops","tag-continuous-delivery","tag-continuous-integration","tag-dobre-praktyki","tag-testing"],"acf":[],"aioseo_notices":[],"republish_history":[],"featured_media_url":"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/04\/CI-i-CD.png","category_names":["Development na mi\u0119kko"],"_links":{"self":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts\/13480"}],"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\/251"}],"replies":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/comments?post=13480"}],"version-history":[{"count":2,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts\/13480\/revisions"}],"predecessor-version":[{"id":21462,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts\/13480\/revisions\/21462"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/media\/13488"}],"wp:attachment":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/media?parent=13480"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/categories?post=13480"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/tags?post=13480"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}