Tipične situacije u kontinuiranoj integraciji

Naučili ste se Git naredbe, ali želite razumjeti kako kontinuirana integracija (Continuous Integration, CI) funkcionira u stvarnosti? Ili možda želite optimizirati svoje svakodnevne aktivnosti? Ovaj tečaj će vam pružiti praktične vještine kontinuirane integracije koristeći repozitorij na GitHub-u. Ovaj tečaj nije zamišljen kao neki čarobnjak koji možete jednostavno kliknuti, naprotiv, radit ćete iste aktivnosti koje ljudi zapravo rade na poslu, na isti način na koji to oni rade. Objašnjavat ću teoriju dok prolazite korake koji se odnose na nju.

Što ćemo raditi?

Kako napredujemo, postupno ćemo kreirati popis tipičnih CI koraka, što je odličan način za pamćenje tog popisa. Drugim riječima, stvorit ćemo popis radnji koje programeri poduzimaju prilikom provođenja kontinuirane integracije. Također ćemo koristiti jednostavan skup testova kako bismo naš CI proces približili stvarnom.

Ovaj GIF ilustrira commitove u vašem repozitoriju dok napredujete tečajem. Kao što vidite, nema tu ništa komplicirano, samo najvažnije.

Tipične situacije u kontinuiranoj integraciji

Proći ćete kroz standardne CI scenarije:

  • Rad na značajci;
  • Primjena automatskih testova za osiguranje kvalitete;
  • Implementacija prioritetnog zadatka;
  • Rješavanje sukoba prilikom spajanja grana (merge conflict);
  • Pojava greške u produkcijskom okruženju.

Što ćete naučiti?

Moći ćete odgovoriti na sljedeća pitanja:

  • Što je kontinuirana integracija (CI)?
  • Koje vrste automatskih testova se koriste u CI i na koje radnje se pokreću?
  • Što je pull request i kada su potrebni?
  • Što je razvoj vođen testovima (Test Driven Development, TDD) i kako se odnosi na CI?
  • Provoditi merge ili primijeniti promjene (rebase)?
  • Vratiti ili popraviti u sljedećoj verziji?

Isprva sam svugdje prevodio izraze kao što su "pull request", ali na kraju sam odlučio povratiti fraze na engleski na nekim mjestima kako bih smanjio ludilo u tekstu. Ponekad ću koristiti "programerski žargon" poput čudnog glagola "zakommitati" tamo gdje ga ljudi zapravo koriste na poslu.

Što je kontinuirana integracija?

Kontinuirana integracija, ili CI, je tehnička praksa koja se sastoji od toga da svaki član tima integrira svoj kod u zajednički repozitorij barem jednom dnevno, pri čemu rezultantni kod mora biti sposoban za kompilaciju bez grešaka.

Postoje nesuglasice oko ovog termina

Predmet spora je učestalost integracije. Neki tvrde da je spajanje koda samo jednom dnevno nedovoljno i da bi se zapravo trebalo integrirati kontinuirano. Kao primjer se navodi tim u kojem svi preuzimaju svježi kod ujutro i integriraju ga jednom uvečer. Iako je to razumna prigovor, u cjelini se smatra da je definicija "jednom dnevno" dovoljno praktična, konkretna i odgovara timovima različitih veličina.

Druga prigovor se odnosi na to da C++ davno nije jedini jezik koji se koristi u razvoju, a jednostavan zahtjev za kompilaciju bez grešaka kao način validacije je slab. Određeni set testova (npr. modulskih, koji se izvršavaju lokalno) također bi trebao uspješno završiti. Trenutno, zajednica se naginje ka tome da taj zahtjev bude obavezan, a u budućnosti bi "kompilacija + modularni testovi" mogla postati općeprihvaćena, ako to već nije.

Kontinuirana integracija razlikuje se od kontinuirane isporuke (Continuous Delivery, CD) po tome što ne zahtijeva kandidata za izdavanje nakon svakog ciklusa integracije.

Popis koraka koje ćemo koristiti tijekom kursa

  1. Preuzmite najnoviji kod. Stvorite granu od master. Počnite raditi.
  2. Kreirajte izmjene na novoj grani. Izgradite i testirajte lokalno. Je li uspješno? Idite na sljedeći korak. Ako nije, ispravite greške ili testove i pokušajte ponovo.
  3. Pushed u svoj udaljeni repozitorij ili udaljenu granu.
  4. Stvorite zahtjev za povlačenje. Raspravite o promjenama, dodajte još izmjena kako diskusija bude trajala. Učinite testove uspješnima na grani s funkcijom.
  5. Spojite/rebazirajte izmjene iz mastera. Učinite testove uspješnima na rezultatu spajanja.
  6. Implementirajte s grane funkcije na proizvodnju.
  7. Ako je sve u redu u proizvodnji tokom nekog razdoblja, spojite izmjene u master.

Tipične situacije u kontinuiranoj integraciji

️ Priprema

Provjerite imate li potrebni softver

Da biste prošli ovaj tečaj, trebat će vam Node.js i Git klijent.

Možete koristiti bilo koji Git klijent, ali ću davati naredbe samo za komandnu liniju.

Provjerite imate li instaliran Git klijent koji podržava komandnu liniju

Ako još niste instalirali Git klijent koji podržava komandnu liniju, možete pronaći upute za instalaciju ovdje.

Pripremite repozitorij

Trebate stvoriti osobnu kopiju(fork) repozitorija s šablonom koda za tečaj na GitHubu. Dogovorimo se da nazivamo ovu osobnu kopiju repozitorijem tečaja.

Jeste li to učinili? Ako niste mijenjali zadane postavke, vaš tečajni repozitorij vjerojatno se zove continuous-integration-team-scenarios-students, nalazi se u vašem GitHub računu, a URL izgleda ovako

https://github.com//continuous-integration-team-scenarios-students

Nazvat ću ovu adresu jednostavno <URL репозитория>.

Okrugli zagrade kao <тут> znače da trebate zamijeniti takav izraz odgovarajućom vrijednošću.

Provjerite da su GitHub akcije omogućene za ovaj tečajni repozitorij. Ako nisu uključene, molim vas uključite ih klikom na veliki gumb u sredini stranice, do kojeg možete doći klikom na Akcije u GitHub sučelju.

Nećete moći proći tečaj slijedeći moje upute ako GitHub Akcije nisu omogućene.

Tipične situacije u kontinuiranoj integraciji

Uvijek možete koristiti mogućnost GitHuba za prikazivanje Markdowa kako biste vidjeli trenutno stanje popisa koji sastavljamo ovdje

https://github.com//continuous-integration-team-scenarios-students/blob/master/ci.md

O odgovorima

Iako je najbolji način da završite tečaj raditi sve samostalno, mogu se pojaviti i poteškoće.

Ako osjećate da ne razumijete što raditi i ne možete nastaviti, možete zaviriti u granu solution, koja postoji u vašem početnom repozitoriju.
Molim vas, ne radite spajanje solution u master tijekom tečaja. Možete koristiti ovu granu kako biste shvatili što raditi, ili kako biste usporedili svoj kod s autorovim, koristeći sve mogućnosti koje nam Git pruža. Ako ste se skroz izgubili, možete potpuno zamijeniti svoju granu master s granom solution i zatim resetirati svoj radni direktorij na onaj korak tečaja koji vam je potreban.

Koristite ovo samo ako vam je to zaista potrebno

Commitajte svoj kod

git add .
git commit -m "Backup mog rada"

Ove komande

  • preimenuju master u master-backup;
  • preimenuju solution u master;
  • prebacuju(checkout) na novu granu master i prepisuju sadržaj radnog direktorija;
  • stvaraju granu "solution" iz "master" (koja je ranije bila "solution") u slučaju da vam u budućnosti zatreba grana "solution".

git branch -m master master-backup
git branch -m solution master
git checkout master -f
git branch solution

Nakon ovih radnji možete koristiti git log master da biste utvrdili koji commit vam je potreban.
Možete resetirati svoj radni direktorij na ovaj commit ovako:

git reset --hard

Ako ste zadovoljni rezultatom, u nekom trenutku ćete morati objaviti svoju verziju repozitorija na udaljeni repozitorij. Ne zaboravite izričito navesti udaljenu granu kada to radite.

git push --force origin master

Molimo obratite pažnju da koristimo git push --force. Vjerojatno nećete često htjeti tako postupati, ali ovdje imamo izuzetno specifičan scenarij s jednim korisnikom repozitorija koji uz to zna što radi.

Započnimo s radom

Tipične situacije u kontinuiranoj integraciji

Zapocinje sastavljanje našeg popisa koraka CI. Obično ovaj korak započinjete povlačenjem najnovije verzije koda iz udaljenog repozitorija, ali još uvijek nemamo lokalni repozitorij, pa umjesto toga kloniramo iz udaljenog.

️ Zadatak: ažurirajte lokalni repozitorij, stvorite granu iz master, započnite raditi

  1. Klonirajte repozitorij tečaja iz <URL репозитория>.
  2. Pokrenite npm install u direktoriju repozitorija tečaja; potreban nam je za instalaciju Jesta, kojeg koristimo za pokretanje testova.
  3. Stvorite granu i nazovite je feature. Prebacite se na ovu granu.
  4. Dodajte testni kod u ci.test.js između komentara s molbom da se to učini.

    it('1. povući najnoviji kod', () => {
      expect(/.*pull.*/ig.test(fileContents)).toBe(true);
    });
    
    it('2. dodaj commit-e', () => {
      expect(/.*commit.*/ig.test(fileContents)).toBe(true);
    });
    
    it('3. gurni na udaljenu granu s istim imenom', () => {
      expect(/.*push.*/ig.test(fileContents)).toBe(true);
    });
    
    it('4. stvori pull request i nastavi raditi', () => {
      expect(/.*pulls+request.*/ig.test(fileContents)).toBe(true);
    });

  5. Dodajte tekst s prva 4 koraka u datoteku ci.md.
    1. Povuci najnoviji kod. Stvori granu iz `master`. Započni rad.    
    2. Stvori commit-e na svojoj novoj grani. Izgradi i testiraj lokalno.  
    Prošlo? Idite na sljedeći korak. Ne? Ispravite greške ili testove i pokušajte ponovo.  
    3. Gurni na svoj udaljeni repozitorij ili udaljenu granu.  
    4. Stvori pull request. Raspravljaj o promjenama, dodaj više commit-a  
    dok rasprava traje. Osiguraj da testovi prolaze na grani s funkcionalnostima.  

    Naredbe

# Клонируйте репозиторий курса
git clone <repository URL>
cd <repository name>

# Выполните npm install в каталоге репозитория курса; он установит Jest, который мы используем для запуска тестов.
npm install

# Создайте ветку и назовите ее feature. Переключитесь на эту в ветку.
git checkout -b feature

# Отредактируйте ci.test.js как описано выше.
# Отредактируйте ci.md как описано выше

Stvarajte commit-e u novoj grani, gradite i testirajte lokalno

Planiramo postaviti testove da se pokreću prije commita, a zatim commitati kod.

Uobičajeni scenariji kada se testovi pokreću automatski

  • Lokalno:
    • Neprekidno ili kao odgovor na relevantne promjene koda;
    • Prilikom spremanja (za interpretirane ili JIT-kompajlirane jezike);
    • Prilikom izgradnje (kada je potrebno prevesti);
    • Prilikom commita;
    • Prilikom objavljivanja javnom repozitoriju.

  • Na serveru za izgradnju (build server) ili u okruženju za izgradnju:
    • Kada se kod objavljuje u osobnu granu / repozitorij.
    • Kod se testira u toj grani.
    • Testira se potencijalni rezultat spajanja (obično s master).
    • Kao dio kontinuirane integracije / kontinuiranog isporučivanja

Općenito, što je brži set testova, to ga češće možete pokretati. Tipična raspodjela po fazama može izgledati ovako.

  • Brzi modularni testovi — pri izradi, u CI cjevovodu
  • Sporiji modularni testovi, brzi komponentni i integracijski testovi — pri commitu, u CI cjevovodu
  • Sporiji komponentni i integracijski testovi — u CI cjevovodu
  • Testiranje sigurnosti, opterećenja i drugi dugotrajni ili skupi testovi — u CI/CD cjevovodima, ali samo u određenim režimima / fazama / cjevovodima izrade, na primjer, prilikom pripreme kandidata za izdanje ili pokretanja ručno.

️ Zadatak

Predlažem da prvo ručno pokrenemo testove koristeći naredbu npm test. Nakon toga dodajmo git hook za pokretanje naših testova prilikom commita. Ima jedna caka: Git hookovi se ne smatraju dijelom repozitorija i stoga se ne mogu klonirati s GitHub-a zajedno s ostalim materijalima tečaja. Da biste postavili hook, trebate pokrenuti install_hook.sh ili kopirati datoteku repo/hook/pre-commit u lokalni direktorij .git/hooks/.
Prilikom commita vidjet ćete kako se testovi izvode i provjeravaju da li su određene ključne riječi prisutne na popisu.

  1. Pokrenite testove ručno, izvršavajući naredbu npm test u mapi repozitorija vašeg tečaja. Pobrinite se da su testovi provedeni.
  2. Postavite hook za commit (pre-commit hook) pokretanjem install_hook.sh.
  3. Napravite commit promjena u lokalni repozitorij.
  4. Pobrinite se da se testovi izvršavaju prije commita.

Vaš repozitorij trebao bi izgledati ovako nakon izvršavanja ovih radnji.
Tipične situacije u kontinuiranoj integraciji

Naredbe

# Установите pre-commit hook выполнив install_hook.sh.  

# Закоммитьте изменения в локальный репозиторий. Используйте "Add first CI steps" в качестве сообщения при коммите.
git add ci.md ci.test.js
git commit -m "Add first CI steps"

# Убедитесь, что тесты запускаются перед коммитом.  

Objavite kod u udaljeni repozitorij ili udaljenu granicu

Nakon što završe s lokalnim radom, programeri obično svoje kodove učine javno dostupnima kako bi se na kraju mogli integrirati s zajedničkim. Uz GitHub, to se obično postiže objavljivanjem rada ili u osobnoj kopiji repozitorija (personal fork, fork) ili u osobnoj grani.

  • Kada se koriste forkovi, programer klonira udaljeni javni repozitorij, stvarajući svoju osobnu udaljenu kopiju, poznatu kao fork. Nakon toga, klonira ovaj osobni repozitorij kako bi radio s njim lokalno. Kada je rad završen i dodaci su napravljeni, smješta ih u svoj fork, gdje su dostupni drugima i mogu se integrirati u zajednički repozitorij. Ovaj pristup obično se koristi u projektima s otvorenim izvorom na GitHubu. Također se koristi u mom naprednom tečaju [Team Work and CI with Git]http://devops.redpill.solutions/).
  • Drugi pristup je koristiti samo jedan udaljeni repozitorij i smatrati samo grananje master zajedničkog repozitorija "zaštićenim". U ovom scenariju pojedinačni programeri objavljuju svoj kod u granama udaljenog repozitorija, kako bi drugi mogli pregledati taj kod; ako je sve u redu, spajaju s master zajedničkog repozitorija.

U ovom konkretnom tečaju koristit ćemo radni proces koji koristi grane.

Objavimo naš kod.

️ Zadatak

  • Objavite promjene u udaljenoj grani s istim imenom kao vaša radna grana

Naredbe

git push --set-upstream origin feature

Izradite pull request

Izradite pull request s nazivom Steps review. Postavite feature kao "head branch" i master kao "base branch".

Pobrinite se da ste postavili master u svom fork repozitorija kao "base branch"; neću razmatrati zahtjeve za promjenama u repozitorij s materijalima tečaja.

Na slengu GitHub-a, "base branch" je grana na kojoj temeljite svoj rad, dok je "head branch" grana koja sadrži predložene promjene.

Razgovarajte o promjenama, dodajte nove dodatke dok se rasprava nastavlja

Pull request (PR)

Pull request (PR) je način da se raspravi i dokumentira kod, kao i da se provede pregled koda (code review). Pull request nazvani su prema uobičajenom načinu integracije pojedinačnih promjena u zajednički kod. Obično osoba klonira udaljeni službeni repozitorij projekta i radi na kodu lokalno. Nakon toga, smješta kod u svoj osobni udaljeni repozitorij i traži od odgovornih za službeni repozitorij da preuzmuomogućuju objavu artefakata ili preuzimanje postojećih artefakata iz udaljenog registra. Pokušajmo objaviti politiku koju smo stvorili u lokalni Docker registar pomoću) njegov kod u svoje lokalne repozitorije, gdje ga pregledavaju i, možda, integrirajumerge) ga. Ova koncepcija poznata je i pod drugim nazivima, na primjer, merge request.

Zapravo, nije potrebno koristiti funkciju pull request na GitHubu ili sličnim platformama. Timovi programera mogu koristiti druge načine komunikacije, uključujući osobne razgovore, telefonske pozive ili e-poštu, ali postoje brojni razlozi zašto koristiti pull requestove kao oblik rasprave. Evo nekoliko od njih:

  • organizirane rasprave vezane uz specifične izmjene u kodu;
  • kao mjesto za pregled povratnih informacija o nedovršenom radu, kako od automatskih testova, tako i od kolega;
  • formalizacija provjera koda;
  • kako bi se kasnije mogli razjasniti razlozi i razmišljanja koja stoje iza određenog dijela koda.

Obično kreirate pull request kada trebate nešto raspraviti ili dobiti povratnu informaciju. Na primjer, ako radite na funkciji koja se može implementirati na više načina, možete otvoriti zahtjev za promjenu čak i prije nego što napišete prvu liniju koda, kako biste podijelili svoje ideje i raspravljali o svojim planovima s koautorima. Ako je rad jednostavniji, pull request se otvara kada je nešto već učinjeno, zabilježeno i može se raspraviti. U nekim scenarijima možete otvoriti PR samo iz razloga kontrole kvalitete: kako biste pokrenuli automatske testove ili inicirali provjeru koda. Što god odlučili, ne zaboravite @spomenuti ljude čije odobrenje je potrebno u vašem pull requestu.

Obično, kada kreirate PR, radite sljedeće.

  • Navedite što predlažete promijeniti i gdje.
  • Napišite opis koji objašnjava svrhu izmjena. Možda biste željeli:
    • dodati nešto važno što nije očito iz koda, ili nešto korisno za razumijevanje konteksta, na primjer, povezane #greške i brojeve commitova;
    • @spomenuti sve s kojima želite započeti suradnju, ili ih možete @spomenuti u komentarima kasnije;
    • zatražiti pomoć kolega s nečim ili provjeru nečega konkretnog.

Nakon što otvorite PR, pokreću se testovi koji su postavljeni da se izvršavaju u tim slučajevima. U našem slučaju, to će biti isti set testova koje smo pokretali lokalno, ali u pravom projektu mogu postojati dodatni testovi i provjere.

Molimo vas, pričekajte dok testovi završe. Status testova možete vidjeti na dnu rasprave PR u interfejsu GitHub. Nastavite kada testovi budu završeni.

️ Dodajte napomenu o proizvoljnosti popisa koraka CI

Popis korišten u ovom tečaju je proizvoljan i subjektivan, trebamo dodati napomenu o tome.

️ Zadatak: kreiranje pull requesta za ovu napomenu

  1. Prebacite se na granu master.
  2. Kreirajte granu s imenom bugfix.
  3. Dodajte tekst napomene na kraj datoteke ci.md.
    > **GitHub flow** se ponekad koristi kao nadimak za varijantu razvoja temeljenog na trunku  
    kada se kod postavlja izravno iz grana značajki. Ovaj popis je samo interpretacija  
    koju koristim u svojim [DevOps tečajevima](http://redpill.solutions).  
    Službeni vodič je [ovdje](https://guides.github.com/introduction/flow/).
  4. Zakažite promjene.
  5. Objavite granu bugfix na udaljeni repozitorij.
  6. Kreirajte pull request s imenom Dodavanje napomene s glavnom granom bugfix i osnovnom granommaster.

Pobrinite se da ste postavili master u svom fork repozitorija kao "base branch"; neću razmatrati zahtjeve za promjenama u repozitorij s materijalima tečaja.

Evo kako bi vaš repozitorij trebao izgledati.
Tipične situacije u kontinuiranoj integraciji

Naredbe

# Переключитесь на ветку master. Создайте ветку bugfix.
git checkout master

# Создайте ветку bugfix-remark.
git checkout -b bugfix

# Добавьте текст примечания внизу ci.md.

# Закоммитьте изменения
git add ci.md
git commit -m "Add a remark about the list being opinionated"

# Опубликуйте ветку bugfix в удалённый репозиторий.
git push --set-upstream origin bugfix

# Создайте pull request при помощи интерфейса GitHub как описано выше

Odobrite pull request "Dodavanje napomene"

️ Zadatak

  1. Kreirajte pull request.
  2. Kliknite "Spoji pull request".
  3. Kliknite "Potvrdi spajanje".
  4. Kliknite "Izbriši granu", više nam nije potrebna.

Ovo je dijagram komita nakon spajanja.
Tipične situacije u kontinuiranoj integraciji

️ Nastavite raditi i dodavati testove

Suradnja na pull requestu često dovodi do potrebe za dodatnim radom. Obično je to rezultat revizije koda ili rasprave, ali u našem tečaju simulirat ćemo to dodajući nove stavke u naš popis koraka CI.

U kontinuiranoj integraciji obično se primjenjuje određeno testno pokriće. Zahtjevi za pokrićem testovima variraju i obično se nalaze u dokumentu s naslovom poput "vodič za autore" (contribution guidelines). Postupit ćemo jednostavno i dodati po jedan test za svaki redak u našem kontrolnom popisu.

Kada izvršavate zadatke, prvo pokušajte zakompitirati testove. Ako ste ispravno postavili pre-commit hook ranije, tek dodani test će se pokrenuti, neće proći i ništa neće biti zakompitirano. Imajte na umu: tako saznajemo da naši testovi zaista nešto provjeravaju. Zanimljivo je da, ako bismo počeli s kodom prije testova, prolaznost testova mogla bi značiti ili da kod radi kako se očekuje, ili da testovi zapravo ništa ne provjeravaju. Osim toga, ako ne bismo napisali testove u prvom redu, mogli bismo ih potpuno zaboraviti, jer nam ništa ne bi pripominjalo o tome.

Razvoj kroz testiranje (TDD)

TDD preporučuje pisanje testova prije koda. Uobičajeni radni proces korištenja TDD-a izgleda ovako.

  1. Dodajte test.
  2. Pokrenite sve testove i uvjerite se da novi test ne prolazi uspješno.
  3. Napišite kod.
  4. Pokrenite testove, provjerite jesu li svi testovi prošli uspješno.
  5. Izvršite refaktoring koda.
  6. Ponovite.

Budući da rezultati testova koji nisu prošli uspješno obično su prikazani crvenom, a uspješni zelenom, ciklus je također poznat kao "crveno-zeleno-refaktoring".

️ Zadatak

Prvo pokušajte napraviti commit testova i dopustite im da ne uspiju, zatim dodajte i commitajte tekst popisa CI koraka. Vidjet ćete kako testovi prolaze ("zeleni").
Zatim objavite novi kod na udaljeni repozitorij i gledajte kako se testovi provode u sučelju GitHub na dnu rasprave o zahtjevu za povlačenje, a status PR se ažurira.

  1. Prebacite se na granu feature.
  2. Dodajte te testove u ci.test.js poslije zadnjeg poziva it (...);.

    it('5. Spojiti/rebase-ati commit-ove s mastera. Osigurati da testovi prolaze na rezultatu merge-a.', () => {
      expect(/.*merge.*commits.*testss+pass.*/ig.test(fileContents)).toBe(true);
    });
    
    it('6. Uvesti s feature grane u produkciju.', () => {
      expect(/.*Deploy.*tos+production.*/ig.test(fileContents)).toBe(true);
    });
    
    it('7. Ako je sve dobro u produkciji tijekom nekog razdoblja vremena, spojite promjene s masterom.', () => {
      expect(/.*merge.*tos+master.*/ig.test(fileContents)).toBe(true);
    });

  3. Pokušajte napraviti commit testova. Ako pre-commit hook je postavljen, pokušaj commit-a će završiti greškom.
  4. Zatim dodajte ovaj tekst u ci.md.
    5. Spojiti/rebase-ati commit-ove s mastera. Osigurati da testovi prolaze na rezultatu merge-a.  
    6. Uvesti s feature grane s tajnim bugom u produkciju.
    7. Ako je sve dobro u produkciji tijekom nekog razdoblja vremena, spojite promjene s masterom. 
  5. Izvršite i commitajte promjene lokalno.
  6. Objavite promjene u granu feature.

Sada bi trebali imati nešto poput ovoga
Tipične situacije u kontinuiranoj integraciji

Naredbe


# Переключительна ветку feature
git checkout feature

# Добавить тесты в ci.test.js как описано выше

# Добавьте в индекс ci.test.js чтобы позже закоммитить
git add ci.test.js

# Попытайтесь закоммитить тесты. Если pre-commit hook установлены, коммит не произойдёт.
git commit

# Теперь добавьте текст в ci.md как описано выше

# Внесите изменения и закоммитьте их
git add ci.md
git commit -m "Add the remaining CI steps"

# Опубликуйте изменения в ветку feature
git push

Sukob tijekom spajanja

Idite na zahtjev za povlačenje Steps review.

Iako nismo učinili ništa loše, i testovi za naš kod su prošli uspješno, još uvijek ne možemo izvršiti spajanje grane feature i master. To je zato što je druga grana bugfix bila spojena s master dok smo radili na ovom PR-u.
To stvara situaciju gdje udaljena grana master ima noviju verziju od one na kojoj smo bazirali granu feature. Zbog toga ne možemo jednostavno vratiti HEAD master do kraja grane feature. U ovoj situaciji trebamo ili izvršiti spajanje (merge), ili primijeniti commit-e feature na vrhu (rebase) masterGitHub zapravo može izvršiti automatsko spajanje ako nema sukoba. Nažalost, u našoj situaciji obje grane imaju konkurentske izmjene u datoteci ci.mdOva situacija je poznata kao sukob pri spajanju (merge conflict) i trebamo je riješiti ručno.

Merge ili rebase

Merge

  • Stvara dodatni merge commit i zadržava povijest rada.
    • Zadržava izvorne commit-e grana s izvorim vremenskim oznakama i autorima.
    • Zadržava SHA commit-a i reference na njih u diskusijama o zahtjevima za promjene.
  • Zahteva jednokratno rješavanje sukoba.
  • Čini povijest nonlinearom.
    • Povijest može biti teška za čitanje zbog velikog broja grana (podsjeća na IDE kablove).
    • Onemogućava automatsko debagiranje, na primjer, čini git bisect manje korisnim — on će samo pronaći merge commit.

Rebase

  • Reproducira commit-e iz trenutne grane preko osnove jedan za drugim.
    • Formiraju se novi commiti s novim SHA, što rezultira time da se commit-i u GitHub-u odnose na izvorne pull zahtjeve, ali ne na odgovarajuće komentare.
    • Commit-i se mogu rekombinirati i izmijeniti tijekom procesa ili čak spojiti u jedan.
  • Može biti potrebno riješiti nekoliko sukoba.
  • Omogućuje održavanje linearne povijesti.
    • Povijest može biti lakša za čitanje, osim ako nije previše dugačka bez razumnih razloga.
    • Automatsko debagiranje i rješavanje problema su donekle lakši: omogućuje git bisect, može učiniti automatske povratke jasnijima i predvidljivijima.
  • Potrebno je objavljivanje grane s premještenim commit-ima s oznakom --force prilikom korištenja s zahtjevima za promjene.

Obično timovi pristaju uvijek koristiti istu strategiju kada trebaju kombinirati promjene. To može biti "čista" fuzija ili "čisto" primjena commit-a iznad ili nešto posredno, kao što je izvođenje primjene commit-a iznad u interaktivnom režimu (git rebase -i) lokalno za grane koje nisu objavljene u zajedničkom repozitoriju, ali spajanje za "javne" grane.

Ovdje ćemo koristiti spajanje.

️ Zadatak

  1. Provjerite da je kod u lokalnoj grani master ažuriran iz udaljenog repozitorija.
  2. Prebacite se na granu feature.
  3. Pokrenite spajanje s granom master. Bit će obaviješteno o sukobu spajanja vezanom uz konkurentske izmjene u ci.md.
  4. Dopustite sukob tako da u tekstu ostane i naš popis koraka CI, i napomena o njemu.
  5. Objavite spojni commit u udaljenu granu feature.
  6. Provjerite status pull request-a u korisničkom sučelju GitHuba, pričekajte da se spajanje okonča.

Naredbe

# Убедитесь, что код в локальное ветке `master` обновлён из удалённого репозитория.
git checkout master
git pull

# Переключитесь на ветку feature
git checkout feature

# Инициируйте слияние с веткой master 
git merge master

# A merge conflict related to concurrent changes to ci.md will be reported
# => Auto-merging ci.md
#    CONFLICT (content): Merge conflict in ci.md
#    Automatic merge failed; fix conflicts and then commit the result.

# Разрешите конфликт так, чтобы и наш список шагов CI, и замечание о нем остались в тексте.
# отредактируйте ci.md чтоб он не содержал маркеров конфликта слияния
git add ci.md
git merge --continue
# при коммите можете оставить сообщение по умолчанию

# Опубликуйте коммит слияния в удаленную ветку feature.
git push

# Проверьте статус запроса на изменения в пользовательском интерфейсе GitHub, дождитесь пока слияние не будет разрешено.

Odličan posao!

Završili ste s popisom, a sada trebate odobriti pull request u master.

️ Zadatak: Odobrite pull request "Pregled koraka"

  1. Otvorite pull request.
  2. Kliknite "Spoji pull request".
  3. Kliknite "Potvrdi spajanje".
  4. Kliknite na "Obriši granu", jer nam više nije potrebna.

To je vaš repozitorij u ovom trenutku
Tipične situacije u kontinuiranoj integraciji

Greška u produkciji

Kažu da "testiranje može pokazati prisutnost grešaka, ali nikad ne može pokazati njihovu odsutnost." Iako smo imali testove koji nisu prikazali nikakve greške, podla greška se ušuljala u produkciju.

U sličnom scenariju moramo voditi računa o:

  • onome što je implementirano u produkciji;
  • kod koji je na grani master s greškom, s kojeg programeri mogu započeti novi posao.

Vratiti ili ispraviti u sljedećoj verziji?

"Vraćanje" (rolling back) je implementacija unaprijed ispravne ranije verzije u produkcijsko okruženje i opoziv (revert) commitova koji sadrže grešku. "Ispravka u sljedećoj verziji" (fixing forward) je dodavanje ispravke u master i implementacija nove verzije što je prije moguće. Kako se API i sheme baza podataka mijenjaju prilikom implementacije koda u produkcijsko okruženje, kod kontinuirane isporuke i dobrog pokrivanja testovima, vraćanje je obično mnogo složenije i rizičnije od ispravke u sljedećoj verziji.

Budući da vraćanje ne nosi nikakvu opasnost u našem slučaju, krenut ćemo tim putem, jer nam to omogućuje

  • da ispravimo grešku u produkciji što je prije moguće;
  • da kod u master odmah bude spreman za započinjanje novog posla.

️ Zadatak

  1. Prebacite se na granu master lokalno.
  2. Ažurirajte lokalni repozitorij iz udaljenog repozitorija.
  3. Opozovite spojni commit PR-a Steps review u master.
  4. Objavite promjene u udaljeni repozitorij.

Ovo je povijest repozitorija s opozvanim spojnim commitom
Tipične situacije u kontinuiranoj integraciji

Naredbe

# Переключитесь на ветку master.
git checkout master

# Обновите локальный репозиторий из удалённого репозитория.
git pull

# Отмените коммит слияния PR Steps review в master.
# Мы отменяем коммит слияния, поэтому нам нужно выбрать ветку истории, которую мы захотим оставить
git show HEAD

# предположим, что коммит, который был последним в ветке master до слияния, был отображён предыдущей командой первым
git revert HEAD -m 1
# можете не менять сообщения коммитов

# Опубликуйте изменения в удалённый репозиторий
git push

️ Samo-provjera

Osigurajte da ci.md više ne sadrži tekst "sneaky bug" nakon opoziva spojnog commita.

Ispravite popis koraka CI i vratite ga u master

Potpuno smo opozvali spojni commit grane feature. Dobre vijesti su da sada nemamo grešku u masterLoša vijest je da je nestala naša dragocjena lista koraka kontinuirane integracije. Dakle, idealno bi bilo da primijenimo ispravak na commitima iz feature i vratimo ih u master zajedno s ispravkom.

Možemo pristupiti zadatku na različite načine:

  • ponovno otkazati (revert) commit koji poništava spajanje feature s master;
  • premjestiti commit-e iz bivše feature.

Različiti razvojni timovi u ovom slučaju koriste različite pristupe, mi ćemo premjestiti korisne commit-e u novu granu i kreirati zaseban pull request za tu novu granu.

️ Zadatak

  1. Kreirajte granu pod imenom feature-fix i prebacite se na nju.
  2. Premjestite sve commit-e iz bivše grane feature u novu granu. Riješite konflikte spajanja koji su se pojavili prilikom premještanja.

    Tipične situacije u kontinuiranoj integraciji

  3. Dodajte regresijski test u ci.test.js:

    it('does not contain the sneaky bug', () => {
    expect( /.*sneakys+bug.*/gi.test(fileContents)).toBe(false);
    });

  4. Pokrenite testove lokalno kako biste osigurali da ne završavaju uspješno.
  5. Izbrišite tekst " with a sneaky bug" u ci.md.
  6. Dodajte promjene testova i promjene na listu koraka u indeks i commit-ujte ih.
  7. Objavite granu u udaljeni repozitorij.

Na kraju biste trebali imati nešto slično
Tipične situacije u kontinuiranoj integraciji

Naredbe

# Создайте ветку под названием feature-fix и переключитесь на нее.
git checkout -b feature-fix

# Перенесите все коммиты из бывшей ветки feature в новую ветку. Разрешите конфликты слияния, которые возникли при переносе.
# используйте историю чтобы узнать хэши коммитов:
# - предшествующего коммиту с первой частью списка: C0
# - добавляющего последние элементы списка: C2
git log --oneline --graph
git cherry-pick C0..C2
# разрешите конфликты слияния
# - отредактируйте ci.md и/или ci.test.js
# - добавьте файлы в индекс
# - выполните "git cherry-pick --continue", можете не менять сообщение коммита

# Добавьте регрессионный тест в ci.test.js
# Запустите тесты локально, чтобы убедиться, что они не завершаются успешно.

# Удалите текст " with a sneaky bug" в ci.md.

# Добавьте в индекс изменения тестов и в списке шагов и закоммитьте их.
git add ci.md ci.test.js
git commit -m "Fix the bug in steps list"

# Опубликуйте ветку в удалённый репозиторий.
git push --set-upstream origin feature-fix

Kreirajte pull request.

Izradite pull request s nazivom Fixing the feature. Postavite feature-fix kao "head branch", a master kao "base branch".
Molimo vas da pričekate dok testovi završe. Status testova možete vidjeti na dnu rasprave PR-a.

Pobrinite se da ste postavili master u svom fork repozitorija kao "base branch"; neću razmatrati zahtjeve za promjenama u repozitorij s materijalima tečaja.

Odobrite pull request "Fixing the feature"

Hvala na ispravljanju! Molimo odobrite promjene u master iz pull requesta.

️ Zadatak

  1. Kliknite "Spoji pull request".
  2. Kliknite "Potvrdi spajanje".
  3. Kliknite na "Obriši granu", jer nam više nije potrebna.

To je ono što biste trebali imati u ovom trenutku
Tipične situacije u kontinuiranoj integraciji

Čestitam!

Izvršili ste sve radnje koje ljudi obično poduzimaju tijekom procesa kontinuirane integracije.

Ako primijetite bilo kakve probleme s tečajem ili znate kako ga poboljšati, otvorite issue u repozitoriju s materijalima tečaja. Ovaj tečaj također ima interaktivnu verziju koja koristi GitHub Learning Lab kao platformu.

Izvor: habr.com

Kupite pouzdan hosting za web stranice s DDoS zaštitom, VPS VDS servere 🔥 Kupite pouzdan hosting za web stranice s DDoS zaštitom, VPS VDS servere | ProHoster