Situații tipice în integrarea continuă

Ai învățat comenzile Git, dar vrei să înțelegi cum se desfășoară integrarea continuă (Continuous Integration, CI) în realitate? Sau poate vrei să îți optimizezi acțiunile zilnice? Acest curs îți va oferi abilități practice în integrarea continuă folosind un repository pe GitHub. Cursul nu este conceput ca un simplu ghid care poate fi parcurs fără apropierea reală; din contră, vei efectua aceleași acțiuni pe care le fac oamenii în mod normal la locul de muncă, exact cum le fac ei. Îți voi explica teoria pe măsură ce parcurgi pașii relevanți.

Ce vom face?

Pe măsură ce avansăm, vom crea treptat o listă a pașilor standard pentru CI, ceea ce reprezintă o modalitate excelentă de a reține această listă. Cu alte cuvinte, vom construi o listă de acțiuni pe care dezvoltatorii le execută atunci când realizează integrarea continuă. De asemenea, vom folosi un set simplu de teste pentru a aduce procesul nostru CI cât mai aproape de realitate.

Acest GIF ilustrează, schematic, commit-urile din repository-ul tău pe măsură ce parcurgi cursul. După cum vezi, nu este nimic complicat și este doar esențialul.

Situații tipice în integrarea continuă

Vei parcurge scenarii standard pentru CI:

  • Lucrul la o caracteristică;
  • Aplicarea testelor automate pentru asigurarea calității;
  • Implementarea unei sarcini prioritare;
  • Rezolvarea unui conflict la unirile ramurilor (merge conflict);
  • Apariția unei erori în mediul de producție.

Ce vei învăța?

Vei putea răspunde la întrebările:

  • Ce este integrarea continuă (CI)?
  • Ce tipuri de teste automate sunt utilizate în CI și în urma căror acțiuni sunt lansate?
  • Ce este un pull request și când sunt necesare?
  • Ce este dezvoltarea bazată pe teste (Test Driven Development, TDD) și cum se corelează cu CI?
  • Să facem un merge sau să aplicăm modificările (rebase)?
  • Să facem un rollback sau să reparăm în versiunea următoare?

La început, am tradus toate termenii precum "pull request", dar în final am decis să păstrez unele fraze în engleză pentru a reduce gradul de confuzie din text. Uneori voi folosi "suroiul de programator" cum ar fi neobișnuitul verb "a comite" acolo unde oamenii îl folosesc în realitate.

Ce este integrarea continuă?

Integrare continuă, sau CI, este o practică tehnică care constă în faptul că fiecare membru al echipei integrează codul său într-un repository comun cel puțin o dată pe zi, iar codul rezultat trebuie să se compileze fără erori.

Există ambiguități cu privire la acest termen

Subiectul disputei este frecvența integrării. Unii susțin că a integra cod doar o dată pe zi nu este suficient, iar integrarea ar trebui să fie continuă. Un exemplu este o echipă în care toți preiau codul proaspăt dimineața și se integrează o dată seara. Deși aceasta este o obiecție rezonabilă, se consideră în general că definiția „o dată pe zi” este suficient de practică, specifică și se potrivește cu echipe de diferite dimensiuni.

O altă obiecție este că C++ nu mai este singurul limbaj folosit în dezvoltare, iar simpla cerință de a se compila fără erori, ca metodă de validare, este slabă. Un set de teste (de exemplu, teste unitare, care se execută local) ar trebui, de asemenea, să aibă succes. În prezent, comunitatea tinde să considere aceasta o cerință obligatorie, iar în viitor,

Integrare continuă este diferit de livrarea continuă (Continuous Delivery, CD) prin faptul că nu necesită un release candidate după fiecare ciclu de integrare.

Lista pașilor pe care o vom folosi pe parcursul cursului

  1. Trageți codul cel mai recent. Creați o ramură din master. Începeți să lucrați.
  2. Creați commit-uri pe noua dumneavoastră ramură. Compilați și testați local. A trecut? Mergeți la pasul următor. A eșuat? Corectați erorile sau testele și încercați din nou.
  3. Trimiteți în repository-ul dumneavoastră remote sau în ramura remote.
  4. Creează un pull request. Discutați modificările, adăugați mai multe commit-uri pe măsură ce discuția continuă. Faceți testele să treacă pe ramura de caracteristică.
  5. Fuzionați/rebazați commit-urile din master. Faceți testele să treacă pe rezultatul fuziunii.
  6. Desfășurați din ramura de caracteristică în producție.
  7. Dacă totul este în regulă în producție pentru o anumită perioadă de timp, fuzionați modificările în master.

Situații tipice în integrarea continuă

️ Pregătire

Asigurați-vă că aveți software-ul necesar

Pentru a urma acest curs veți avea nevoie de Node.js și un client Git.

Puteți folosi orice client Git, dar eu voi oferi comenzi doar pentru linia de comandă.

Asigurați-vă că aveți instalat un client Git care suportă linia de comandă

Dacă nu aveți încă instalat un client Git care să suporte linia de comandă, puteți găsi instrucțiuni de instalare aici.

Pregătiți repository-ul

Va trebui să creați o copie personală(fork) a repository-ului template cu codul pentru curs pe GitHub. Să convenim să numim această copie personală repository-ul cursului.

Ați terminat? Dacă nu ați schimbat setările implicite, depozitul cursului dumneavoastră se numește cel mai probabil continuous-integration-team-scenarios-students, este în contul dumneavoastră de GitHub și URL-ul arată astfel

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

Voi numi această adresă simplu <URL репозитория>.

Parantezele unghiulare ca <тут> vor însemna că trebuie să înlocuiți o astfel de expresie cu valoarea corespunzătoare.

Asigurați-vă că GitHub actions sunt activate pentru acest depozit de curs. Dacă nu sunt activate, vă rog să le activați apasând pe butonul mare din mijlocul paginii, la care puteți accesa făcând clic pe Actions în interfața GitHub.

Nu veți putea urma cursul, conform instrucțiunilor mele, dacă GitHub Actions nu sunt activate.

Situații tipice în integrarea continuă

Puteți folosi întotdeauna capacitatea GitHub de a afișa Markdown pentru a vedea starea curentă a listei pe care o compunem aici

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

Despre răspunsuri

Deși cea mai bună modalitate de a finaliza acest curs este să faceți totul de la zero, este posibil să întâmpinați dificultăți.

Dacă simțiți că nu înțelegeți ce trebuie să faceți și nu puteți continua, puteți arunca o privire în ramura solution, care există în depozitul dumneavoastră de pornire.
Vă rog să nu efectuați fuziuni solution în master în timpul cursului. Puteți folosi această ramură pentru a înțelege ce trebuie să faceți, sau pentru a compara codul dumneavoastră cu cel original, folosind toate funcționalitățile pe care ni le oferă Git. Dacă v-ați pierdut complet, puteți înlocui complet ramura dumneavoastră master cu ramura solution și apoi să resetați directorul dumneavoastră de lucru la pasul cursului de care aveți nevoie.

Folosiți aceasta doar dacă este absolut necesar

Comiteți (commit) codul dumneavoastră

git add .
git commit -m "Backup al muncii mele"

Aceste comenzi

  • își schimbă numele în master în master-backup;
  • își schimbă numele în solution în master;
  • schimbă (checkout) pe o nouă ramură master și rescriu conținutul directorului de lucru;
  • crează o ramură "solution" din "master" (care a fost anterior "solution") în cazul în care aveți nevoie de ramura "solution" în viitor.

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

După aceste acțiuni, puteți folosi git log master pentru a afla ce commit este necesar pentru dumneavoastră.
Puteți reseta directorul dumneavoastră de lucru la acest commit astfel:

git reset --hard

Dacă sunteți mulțumit de rezultat, la un moment dat va trebui să publicați versiunile dumneavoastră ale repositoariului într-un repository la distanță. Nu uitați să specificați clar ramura la distanță atunci când faceți acest lucru.

git push --force origin master

Vă rugăm să rețineți că folosim git push --force. Probabil că nu veți dori să acționați astfel foarte des, dar avem un scenariu foarte specific cu un utilizator al repositoariului care, în plus, înțelege ce face.

Începem lucrul

Situații tipice în integrarea continuă

Să începem să creăm lista noastră de pași CI. De obicei, începeți acest pas cu extragerea celei mai recente versiuni a codului din repository-ul la distanță, dar nu avem încă un repository local, așa că în loc de asta, îl clonăm din cel la distanță.

️ Sarcină: actualizați repository-ul local, creați o ramură din master, începeți lucrul

  1. Clonați repositoariul cursului din <URL репозитория>.
  2. Rulați npm install în directorul repositoariului cursului; ne trebuie pentru a instala Jest, pe care îl folosim pentru a rula teste.
  3. Creați o ramură și numiți-o feature. Comutati pe această ramură.
  4. Adăugați cod de testare în ci.test.js între comentariile care vă cer să faceți acest lucru.

    it('1. extrageți cel mai recent cod', () => {
      expect(/.*pull.*\/ig.test(fileContents)).toBe(true);
    });
    
    it('2. adăugați commit-uri', () => {
      expect(/.*commit.*\/ig.test(fileContents)).toBe(true);
    });
    
    it('3. împingeți către ramura la distanță cu același nume', () => {
      expect(/.*push.*\/ig.test(fileContents)).toBe(true);
    });
    
    it('4. creați o cerere de extragere și continuați lucrul', () => {
      expect(/.*pulls+request.*\/ig.test(fileContents)).toBe(true);
    });

  5. Adăugați text cu primele 4 pași în fișier ci.md.
    1. Extrageți cel mai recent cod. Creați o ramură din `master`. Începeți lucrul.    
    2. Creați commit-uri pe noua dumneavoastră ramură. Compilați și testați local.  
    Funcționează? Mergeți la pasul următor. Nu funcționează? Remediați erorile sau testele și încercați din nou.  
    3. Împingeți către repositoariul dumneavoastră la distanță sau ramura la distanță.  
    4. Creați o cerere de extragere. Discutați modificările, adăugați mai multe commit-uri  
    pe măsură ce discuția continuă. Faceți testele să treacă pe ramura de funcții.  

    Comenzi

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

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

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

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

Creați commit-uri pe noua ramură, compilați și testați local

Ne pregătim să configurăm testele pentru a se rula înainte de commit, iar apoi să facem commit codul.

Scenarii tipice în care testele sunt rulate automat

  • Local:
    • Constant sau ca răspuns la modificările relevante ale codului;
    • La salvare (pentru limbaje interpretate sau compilate JIT);
    • La compilare (când este necesară compilarea);
    • La commit;
    • La publicarea în repository-ul comun.

  • Pe serverul de construcție sau în mediu de construcție:
    • Când codul este publicat într-o ramură/repository personală.
    • Codul este testat în această ramură.
    • Rezultatul potențial al fuziunii este testat (de obicei cu master).
    • Ca etap al integrării continue/funcționării continue a livrării

În general, cu cât setul de teste este executat mai rapid, cu atât mai des îți poți permite să-l rulezi. O distribuție tipică pe etape ar putea arăta astfel.

  • Teste unitare rapide — la compilare, în pipeline-ul CI
  • Teste unitare lente, teste de componente rapide și teste de integrare — la commit, în pipeline-ul CI
  • Teste de componente și de integrare lente — în pipeline-ul CI
  • Teste de securitate, teste de încărcare și alte teste de lungă durată sau costisitoare — în pipeline-urile CI/CD, dar doar în anumite moduri/etape/pipeline-uri de compilare, de exemplu, când se pregătește un release candidate sau când se rulează manual.

️ Sarcină

Îți propun să rulezi mai întâi testele manual, folosind comanda npm test. După aceea, să adăugăm un git hook pentru a rula testele noastre la commit. Există o problemă: Git hooks nu sunt considerate parte a repository-ului și, prin urmare, nu pot fi clonat de pe GitHub împreună cu restul materialelor cursului. Pentru a instala hook-ul, trebuie să rulezi install_hook.sh sau să copiezi fișierul repo/hooks/pre-commit în directorul local .git/hooks/.
La commit, vei vedea că testele sunt rulate și acestea verifică dacă anumite cuvinte cheie sunt prezente în listă.

  1. Rulează testele manual, executând comanda npm test în folderul repository-ului cursului tău. Asigură-te că testele au fost executate.
  2. Instalează hook-ul la commit (pre-commit hook), rulând install_hook.sh.
  3. Comite modificările în repository-ul local.
  4. Asigură-te că testele sunt rulate înainte de commit.

Repository-ul tău ar trebui să arate astfel după ce ai realizat aceste acțiuni.
Situații tipice în integrarea continuă

Comenzi

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

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

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

Publică codul în repository-ul îndepărtat sau în ramura îndepărtată

După ce ai terminat de lucrat local, dezvoltatorii își fac de obicei codul public, astfel încât acesta să poată fi integrat la final cu codul comun. Cu ajutorul GitHub, acest lucru este de obicei realizat prin publicarea muncii fie într-o copie personală a repository-ului (fork), fie într-o ramură personală.

  • At the use of forks, a developer clones a remote shared repository, creating their personal remote copy, also known as a fork. After that, they clone this personal repository to work on it locally. When the work is completed and commits are made, they push them to their fork, where they are available to others and can be integrated into the main repository. This approach is commonly used in open-source projects on GitHub. It is also used in my advanced course [Team Work and CI with Git]http://devops.redpill.solutions/).
  • Another approach is to use only one remote repository and consider only the branch master of the shared repository as "protected". In this scenario, individual developers publish their code to branches of the remote repository for others to review; if everything is in order, they can merge with master the main repository.

In this particular course, we will use a workflow that utilizes branches.

Let's publish our code.

️ Sarcină

  • Publish the changes to a remote branch with the same name as your working branch

Comenzi

git push --set-upstream origin feature

Create a pull request

Create a pull request named Steps review. Set feature as the "head branch" and master as the "base branch."

Make sure to set master în propriul său the fork of the repository as the "base branch," I will not respond to change requests in the repository with course materials.

In GitHub slang, the "base branch" is the branch on which you base your work, while the "head branch" is the branch that contains the proposed changes.

Discuss the changes, add new commits as the discussion continues

Pull request (PR)

Pull request (PR) is a way to discuss and document code, as well as to conduct a code review. Pull requests are named after the common way of integrating individual changes into the main code. Typically, a person clones the remote official repository of the project and works on the code locally. After this, they push the code to their personal remote repository and ask the maintainers of the official repository to pullpull) their code into their local repositories, where they can review and possibly integratemerge) it. This concept is also known by other names, such as, cerere de îmbinare.

În realitate, nu este obligatoriu să folosești funcția pull request de pe GitHub sau platforme similare. Echipele de dezvoltatori pot utiliza alte modalități de comunicare, inclusiv întâlniri față în față, apeluri telefonice sau e-mailuri, însă există totuși o serie de motive pentru a folosi pull requests de tip discuție pe forum. Iată câteva dintre ele:

  • discuții organizate legate de modificări specifice ale codului;
  • ca loc pentru a revizui feedbackul referitor la munca neterminată, atât de la teste automate, cât și de la colegi;
  • formalizarea verificărilor de cod;
  • pentru a putea afla ulterior motivele și considerațiile din spatele unei anumite porțiuni de cod.

De obicei, creezi un pull request atunci când trebuie să discuți ceva sau să obții feedback. De exemplu, dacă lucrezi la o funcție care poate fi implementată în mai multe moduri, poți crea o cerere de modificare chiar înainte de a scrie prima linie de cod, pentru a-ți împărtăși ideile și a discuta planurile cu colaboratorii. Dacă munca este mai simplă, pull requestul este deschis când ceva este deja finalizat, evaluat și poate fi discutat. În unele scenarii, poți deschide un PR doar din motive de control al calității: pentru a rula teste automate sau a iniția verificarea codului. Indiferent de decizia ta, nu uita să @menționezi persoanele ale căror aprobat este necesar în pull request-ul tău.

De obicei, când creezi un PR, urmezi pașii următori.

  • Indici că ce propui să schimbi și unde.
  • Scrii o descriere care explică scopul modificărilor. Poți dori:
    • să adaugi ceva important care nu este evident din cod, sau ceva util pentru înțelegerea contextului, cum ar fi problemele # și numerele commit-urilor corespunzătoare;
    • @menționezi pe toți cei cu care vrei să colaborezi, sau poți să îi @menționezi în comentarii mai târziu;
    • să ceri colegilor să te ajute cu ceva sau să verifice ceva anume.

După ce deschizi PR-ul, se rulează teste configurate pentru a porni în astfel de situații. În cazul nostru, acesta va fi același set de teste pe care l-am rulat local, dar în proiectul real ar putea fi teste și verificări suplimentare.

Vă rugăm să așteptați până la finalizarea testelor. Puteți vizualiza statusul testelor în partea de jos a discuției PR în interfața GitHub. Continuați când testele vor fi finalizate.

️ Adăugați o observație cu privire la arbitrarietatea listei de pași CI

Lista utilizată în acest curs este arbitrară și subiectivă; trebuie să adăugăm o notă despre acest lucru.

️ Sarcină: crearea unui pull request pentru această observație

  1. Comutați pe ramura master.
  2. Creează un branch cu numele corectare de buguri.
  3. Adăugați textul observației la sfârșitul fișierului ci.md.
    > **GitHub flow** este uneori folosit ca un nume alternativ pentru o variantă de dezvoltare bazată pe trunchi  
     când codul este deployat direct din feature branches. Această listă este doar o interpretare  
     pe care o folosesc în cursurile mele [DevOps](http://redpill.solutions).  
     Tutorialul oficial este [aici](https://guides.github.com/introduction/flow/).
  4. Comiteți modificările.
  5. Publicați branch-ul corectare de buguri în repository-ul remote.
  6. Creează un pull request cu numele Adăugând o observație cu branch-ul principal corectare de buguri și branch-ul de bazămaster.

Make sure to set master în propriul său the fork of the repository as the "base branch," I will not respond to change requests in the repository with course materials.

Iată cum ar trebui să arate repository-ul dvs.
Situații tipice în integrarea continuă

Comenzi

# Переключитесь на ветку 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 как описано выше

Aprobati pull request-ul "Adăugând o observație"

️ Sarcină

  1. Creează un pull request.
  2. Apăsați "Merge pull request".
  3. Apăsați "Confirm merge".
  4. Apăsați "Delete branch"; nu ne mai trebuie.

Aceasta este diagrama commit-urilor după fuziune.
Situații tipice în integrarea continuă

️ Continuați să lucrați și să adăugați teste

Colaborarea pe un pull request duce adesea la necesitatea unor lucrări suplimentare. De obicei, acest lucru este rezultatul revizuirii codului sau al discuției, dar în cursul nostru vom simula acest lucru adăugând elemente noi la lista noastră de pași CI.

În integrarea continuă, de obicei se aplică o acoperire de teste. Cerințele pentru acoperirea testelor variază și sunt de obicei într-un document numit "ghid pentru contribuabili" (contribution guidelines). Vom proceda simplu și vom adăuga câte un test pentru fiecare rând din lista noastră de verificare.

Când completați sarcinile, încercați mai întâi să comiteți testele. Dacă ați configurat corect hook-ul pre-commit anterior, testul nou adăugat va rula, nu va trece și nimic nu va fi comis. Rețineți: așa vom afla că testele noastre verifică într-adevăr ceva. Curios, dacă am fi început cu codul înainte de teste, trecerea testelor ar putea însemna fie că codul funcționează așa cum ne așteptam, fie că testele în sine nu verifică nimic. În plus, dacă nu am fi scris testele de la bun început, am putea să le uităm complet, deoarece nimic nu ne-ar aminti de acestea.

Dezvoltare prin teste (TDD)

TDD recomandă scrierea testelor înainte de cod. Procesul obișnuit de lucru folosind TDD arată astfel.

  1. Adăugați un test.
  2. Rulați toate testele și asigurați-vă că noul test nu trece cu succes.
  3. Scrieți cod.
  4. Rulați testele, asigurați-vă că toate testele trec cu succes.
  5. Faceți refactorizarea codului.
  6. Repetați.

Deoarece rezultatele testelor care nu au fost finalizate cu succes sunt de obicei afișate în roșu, iar cele finalizate cu succes în verde, ciclul este, de asemenea, cunoscut sub numele de "roșu-verde-refactorizare" (red-green-refactor).

️ Sarcină

Încercați mai întâi să comiteți testele și să le lăsați să eșueze, apoi adăugați și comiteți textul listei de pași CI. Veți vedea că testele trec ("verzi").
Apoi publicați noul cod în repository-ul remote și observați cum se execută testele în interfața GitHub din partea de jos a discuției cererii de pull, și cum se actualizează statutul PR.

  1. Comutați pe ramura feature.
  2. Adăugați aceste teste în ci.test.js după ultima apelare it (...);.

    it('5. Fuzionați/rebazați comit-uri din master. Faceți testele să treacă pe rezultatul fuziunii.', () => {
      expect(/.*merge.*commits.*testss+pass.*/ig.test(fileContents)).toBe(true);
    });
    
    it('6. Desplasați de pe ramura de caracteristică în producție.', () => {
      expect(/.*Deploy.*tos+production.*/ig.test(fileContents)).toBe(true);
    });
    
    it('7. Dacă totul este bine în producție pentru o perioadă de timp, fuzionați modificările în master.', () => {
      expect(/.*merge.*tos+master.*/ig.test(fileContents)).toBe(true);
    });

  3. Încercați să comiteți testele. Dacă hook-ul pre-commit hook-ul este setat, încercarea de commit va eșua.
  4. Apoi adăugați acest text în ci.md.
    5. Fuzionați/rebazați comit-uri din master. Faceți testele să treacă pe rezultatul fuziunii.  
    6. Desplasați de pe ramura de caracteristică cu un bug ascuns în producție.
    7. Dacă totul este bine în producție pentru o perioadă de timp, fuzionați modificările în master. 
  5. Faceți și comiteți modificările local.
  6. Publicați modificările în ramura feature.

Acum ar trebui să aveți ceva de genul acesta
Situații tipice în integrarea continuă

Comenzi


# Переключительна ветку 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

Conflict de fuziune

Mergeți la cererea de pull Steps review.

Deși nu am făcut nimic greșit și testele pentru codul nostru au trecut cu succes, tot nu putem realiza fuziunea ramurii feature și master. Acest lucru se datorează faptului că o altă ramură corectare de buguri a fost fuzionată cu master în timp ce lucram la acest PR.
Aceasta creează o situație în care ramura remote master are o versiune mai nouă decât cea pe care ne-am bazat ramura feature. Din această cauză, nu putem doar să derulăm HEAD master până la capătul ramurii feature. În această situație, trebuie să realizăm fie o fuziune (merge), fie să aplicăm comit-uri feature peste (rebase) master. GitHub poate efectua în mod automat fuziuni, dacă nu există conflicte. Din păcate, în situația noastră, ambele ramuri au modificări concurente în fișier. ci.md. Această situație este cunoscută sub numele de conflict de fuziune (merge conflict) și trebuie să o rezolvăm manual.

Merge sau rebase

Merge

  • Creează un commit de fuziune (merge commit) suplimentar și păstrează istoricul muncii.
    • Păstrează commiturile originale ale ramurilor cu marcaje de timp și autori originale.
    • Păstrează SHA commiturile și referințele la acestea în discuțiile cererilor de modificare.
  • Necesită rezolvarea conflictelor o singură dată.
  • Face istoricul non-liniar.
    • Istoricul poate fi greu de citit din cauza numărului mare de ramuri (seamănă cu un cablu IDE).
    • Complică depanarea automată, de exemplu, face git bisect mai puțin util — acesta va găsi doar commitul de fuziune.

Rebase

  • Reprodusează commit-uri din ramura curentă deasupra bazei, unul câte unul.
    • Se formează commituri noi cu SHA noi, rezultând că commiturile din GitHub se corelează cu cererile de pull originale, dar nu cu comentariile corespunzătoare.
    • Commiturile pot fi recombinate și modificate în proces sau chiar combinate într-unul singur.
  • Ar putea fi necesară rezolvarea mai multor conflicte.
  • Permite menținerea unui istoric liniar.
    • Istoricul poate fi mai ușor de citit, cu condiția să nu fie prea lung fără un motiv întemeiat.
    • Depanarea automată și rezolvarea problemelor sunt puțin mai simple: permite git bisect, poate face revertările automate mai clare și predictibile.
  • Este necesară publicarea ramurii cu commituri mutate cu flagul --force când este utilizat cu cererile de modificare.

De obicei, echipele agreesc să folosească întotdeauna aceeași strategie atunci când trebuie să unifice modificările. Aceasta poate fi o fuziune "curată" sau o aplicare "curată" a commiturilor deasupra, sau ceva intermediar, cum ar fi efectuarea aplicării commiturilor într-un mod interactiv (git rebase -i) local pentru ramuri, care nu sunt publicate în depozitul comun, dar fuziunea (merge) pentru ramuri "publice".

Aici vom folosi fuziunea.

️ Sarcină

  1. Asigurați-vă că codul din ramura locală master este actualizat din depozitul remote.
  2. Comutați pe ramura feature.
  3. Inițiați fuziunea cu ramura master. Vor fi raportate conflictele de fuziune legate de modificările concurente din. ci.md.
  4. Rezolvați conflictul astfel încât să rămână în text atât lista noastră de pași CI, cât și observația referitoare la aceasta.
  5. Publicați commit-ul de fuziune în ramura remote. feature.
  6. Verificați starea pull request-ului în interfața utilizatorului GitHub, așteptați până când fuziunea este rezolvată.

Comenzi

# Убедитесь, что код в локальное ветке `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, дождитесь пока слияние не будет разрешено.

Bravo pentru muncă!

Ați terminat lucrul la listă și acum trebuie să aprobați pull request-ul în master.

️ Sarcina: Aprobați pull request-ul "Revizuirea pașilor"

  1. Deschideți pull request-ul.
  2. Apăsați "Merge pull request".
  3. Apăsați "Confirm merge".
  4. Apăsați "Șterge ramura", deoarece nu o mai avem nevoie.

Acesta este repo-ul dvs. în acest moment.
Situații tipice în integrarea continuă

Eroare în producție.

Se spune că "testarea poate fi utilizată pentru a demonstra existența erorilor, dar niciodată pentru a demonstra absența lor". Deși am avut teste și acestea nu ne-au arătat nicio eroare, o eroare perfidă s-a strecurat în producție.

Într-un astfel de scenariu, trebuie să ne ocupăm de:

  • ce este desfășurat în producție;
  • codul din ramura master cu eroarea, de unde dezvoltatorii pot începe o nouă muncă.

Să revenim sau să corectăm în următoarea versiune?

"Revenirea" (rolling back) este desfășurarea unei versiuni anterioare, știută ca având fixuri, în mediu de producție și anularea (revert) commit-urilor care conțin eroare. "Corectarea în următoarea versiune" (fixing forward) este adăugarea unei corecții în master și desfășurarea unei noi versiuni cât mai curând posibil. Deoarece API-urile și schemele de baze de date se schimbă pe măsură ce codul este desfășurat în mediu de producție, în cazul livrării continue și cu o acoperire bună de teste, revenirea este, de obicei, mult mai complicată și riscantă decât corectarea în următoarea versiune.

Deoarece revenirea nu prezintă în cazul nostru niciun risc, vom merge pe acest drum, deoarece ne permite

  • să corectăm eroarea în producție cât mai repede posibil;
  • să facem codul din master imediat utilizabil pentru a începe o nouă muncă.

️ Sarcină

  1. Comutați pe ramura master local.
  2. Actualizați repository-ul local din repo-ul remote.
  3. Anulați commit-ul de fuziune PR. Steps review în master.
  4. Publicați modificările în repo-ul remote.

Aceasta este istoricul repo-ului cu commit-ul de fuziune anulat.
Situații tipice în integrarea continuă

Comenzi

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

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

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

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

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

️ Auto-verificare

Asigurați-vă că ci.md nu mai conține textul "sneaky bug" după anularea commit-ului de fuziune.

Corectați lista de pași CI și returnați-o în master.

Am anulat complet commit-ul de fuziune al ramurii feature. Vestea bună este că acum nu mai avem o eroare în master. Vestea proastă este că lista noastră prețioasă de pași pentru integrarea continuă a dispărut. Așadar, în mod ideal, trebuie să aplicăm o corecție la commit-urile din feature și să le returnăm în master împreună cu corecția.

Putem aborda sarcina în moduri diferite:

  • anulând (revert) commit-ul care inversează fuziunea feature de master;
  • mutând commit-urile din fosta feature.

Diverse echipe de dezvoltare în acest caz folosește abordări diferite, noi vom muta commit-urile utile într-o ramură separată și vom crea o cerere de tragere separată pentru această nouă ramură.

️ Sarcină

  1. Creează o ramură numită feature-fix și comută pe ea.
  2. Mută toate commit-urile din fosta ramură feature în noua ramură. Rezolvă conflictele de fuziune care au apărut în timpul mutării.

    Situații tipice în integrarea continuă

  3. Adaugă un test regresiv în ci.test.js:

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

  4. Execută testele local pentru a te asigura că nu se finalizează cu succes.
  5. Șterge textul " with a sneaky bug" din ci.md.
  6. Adaugă în index modificările testelor și modificările din lista de pași și comite-le.
  7. Publică ramura în depozitul remote.

Ca rezultat, ar trebui să ai ceva similar
Situații tipice în integrarea continuă

Comenzi

# Создайте ветку под названием 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

Creează un pull request.

Create a pull request named Fixing the feature. Set feature-fix ca "head branch", iar master as the "base branch."
Te rog să aștepți până când testele se finalizează. Poți vedea statusul testelor în partea de jos a discuției PR.

Make sure to set master în propriul său the fork of the repository as the "base branch," I will not respond to change requests in the repository with course materials.

Aprobă cererea de tragere "Fixing the feature"

Mulțumesc pentru corectare! Te rog aprobă modificările în master din cererea de tragere.

️ Sarcină

  1. Apăsați "Merge pull request".
  2. Apăsați "Confirm merge".
  3. Apăsați "Șterge ramura", deoarece nu o mai avem nevoie.

Aceasta este ceea ce ar trebui să ai în acest moment
Situații tipice în integrarea continuă

Felicitări!

Ai efectuat toate acțiunile pe care oamenii le fac de obicei în procesul de integrare continuă.

Dacă ai observat vreo problemă cu cursul sau știi cum să îl îmbunătățești, creează o problemă în depozitul cu materialele cursului. Acest curs are de asemenea o version interactivă folosind GitHub Learning Lab ca platformă.

Sursa: habr.com

Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS 🔥 Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS | ProHoster