GitHub Flow

Problémák a git-flow-val

Mindenfelé járok, ahol Git-et tanítok az embereknek, és szinte minden órán és workshopon, ahol mostanában részt vettem, megkérdezték tőlem, mit gondolok a git-flow-ról. Mindig azt válaszolom, hogy szerintem nagyszerű – fogott egy rendszert (Git), amelynek millió lehetséges munkafolyamata van, és dokumentált egy jól tesztelt, rugalmas munkafolyamatot, amely sok fejlesztő számára meglehetősen egyszerű módon működik. Valamiféle szabvány lett belőle, így a fejlesztők projekt vagy vállalat között mozoghatnak, és ismerik ezt a szabványosított munkafolyamatot.

Mégis vannak problémái. Számos olyan véleményt hallottam az emberektől, hogy nem tetszik, hogy az új funkciók ágai a develop-ról indulnak, nem pedig a master-ről, vagy ahogyan a hotfixeket kezeli, de ezek meglehetősen jelentéktelenek.

Az egyik nagyobb probléma számomra az, hogy bonyolultabb, mint amire szerintem a legtöbb fejlesztőnek és fejlesztőcsapatnak valójában szüksége van. Elég bonyolult ahhoz, hogy egy nagy segédszkriptet fejlesztettek ki, hogy segítsen érvényesíteni az áramlást. Bár ez klassz, a probléma az, hogy ezt nem lehet Git GUI-ban érvényesíteni, csak parancssoron, így az egyetlenek, akiknek igazán jól meg kell tanulniuk a bonyolult munkafolyamatot, mert minden lépést manuálisan kell elvégezniük, ugyanazok az emberek, akik nem ismerik eléggé a rendszert ahhoz, hogy parancssorból használják. Ez óriási probléma lehet.

Ezek a problémák mindegyike könnyen megoldható lenne, ha sokkal egyszerűbb lenne a folyamat. A GitHubon nem használjuk a git-flowt. Mi egy sokkal egyszerűbb Git-munkafolyamatot használunk, és mindig is használtunk.

Egyszerűsége számos előnnyel jár. Az egyik, hogy az emberek számára könnyen érthető, ami azt jelenti, hogy gyorsan elsajátítják, és ritkán, ha egyáltalán elrontják, vagy vissza kell vonniuk a rosszul elvégzett lépéseket. A másik, hogy nincs szükségünk wrapper szkriptre, ami segít az érvényesítésében vagy követésében, így a GUI-k és hasonlók használata nem jelent problémát.

GitHub Flow

Szóval, miért nem használjuk a git-flowt a GitHubon? Nos, a fő probléma az, hogy állandóan telepítünk. A git-flow folyamatot nagyrészt a “kiadás” köré tervezték. Nálunk nem igazán vannak “kiadások”, mert minden nap telepítünk a termelésbe – gyakran naponta többször is. Ezt a csevegőrobotunkon keresztül tudjuk megtenni, ami ugyanaz a hely, ahol a CI eredményeink is megjelennek. Igyekszünk a tesztelés és a szállítás folyamatát a lehető legegyszerűbbé tenni, hogy minden alkalmazott kényelmesen végezze azt.

A rendszeres telepítésnek számos előnye van. Ha néhány óránként telepítünk, szinte lehetetlen nagyszámú nagy hibát bevezetni. Apró problémák ugyan bevezethetők, de aztán nagyon gyorsan kijavíthatók és újra telepíthetők. Normális esetben “hotfixet” vagy valamit kellene csinálni a normál folyamaton kívül, de ez egyszerűen a normál folyamat része – a GitHub-áramlásban nincs különbség egy hotfix és egy nagyon kis funkció között.

A másik előnye a folyamatos telepítésnek, hogy gyorsan tudunk kezelni mindenféle problémát. Hihetetlenül gyorsan tudunk reagálni a tudomásunkra jutott biztonsági problémákra, vagy hihetetlenül gyorsan tudunk apró, de érdekes funkciókéréseket megvalósítani, ugyanakkor pontosan ugyanazt a folyamatot használhatjuk ezeknek a változásoknak a kezelésére, mint a normál vagy akár a nagy funkciók fejlesztésére. Az egész ugyanaz a folyamat, és az egész nagyon egyszerű.

Hogyan csináljuk

Szóval, mi is az a GitHub Flow?

  • Minden, ami a master ágban van, telepíthető
  • Ha valami új dolgon akarsz dolgozni, hozz létre egy leíró nevű ágat a master ágból (pl: new-oauth2-scopes)
  • Commitálj ebbe az ágba lokálisan, és rendszeresen tedd át a munkádat a szerveren lévő ugyanilyen nevű ágba
  • Ha visszajelzésre vagy segítségre van szükséged, vagy úgy gondolod, hogy az ág készen áll az egyesítésre, nyiss egy pull requestet
  • Miután valaki más is átnézte és aláírta a funkciót, beolvaszthatod a masterbe
  • Mihelyt beolvasztották és a “master”-be tolták, azonnal telepítheted és telepítened is kell

Ez a teljes folyamat. Nagyon egyszerű, nagyon hatékony, és meglehetősen nagy csapatoknál is működik – a GitHubon most 35 alkalmazott dolgozik, akik közül talán 15-20-an dolgoznak egyszerre ugyanazon a projekten (github.com). Azt hiszem, hogy a legtöbb fejlesztőcsapat – olyan csoportok, amelyek egyszerre dolgoznak ugyanazon a logikai kódon, ami konfliktusokat okozhat – körülbelül ekkora vagy kisebb. Különösen azok, amelyek elég progresszívek ahhoz, hogy gyors és következetes telepítéseket végezzenek.

Nézzük tehát sorban az egyes lépéseket.

#1 – bármi, ami a master ágban van, telepíthető

Ez lényegében a rendszer egyetlen kemény szabálya. Csak egyetlen ág van, amelynek van valamilyen konkrét és következetes jelentése, és ezt neveztük el master-nek. Számunkra ez azt jelenti, hogy már telepítve van, vagy legrosszabb esetben órákon belül telepítve lesz. Hihetetlenül ritka, hogy ezt visszatekerik (az ágat visszaviszik egy régebbi commitra, hogy visszaállítsák a munkát) – ha probléma van, a commitokat visszafordítják, vagy új commitokat vezetnek be, amelyek kijavítják a problémát, de magát az ágat szinte soha nem tekerik vissza.

A master ág stabil, és mindig, mindig biztonságos róla telepíteni vagy új ágakat létrehozni róla. Ha olyasmit tolsz a masterbe, ami nincs tesztelve, vagy megtöri a buildet, akkor megszeged a fejlesztőcsapat társadalmi szerződését, és általában elég rosszul érzed magad emiatt. Minden ágon, amit tolunk, lefuttatjuk a teszteket, és jelentjük a chatszobában, így ha nem futtattad le őket helyben, akkor egyszerűen tolhatsz egy témaágra (akár egy ágra is, amin csak egy commit van) a szerveren, és várhatod, hogy a Jenkins megmondja neked, hogy minden átment-e.

Lehetne egy deployed ág, ami csak akkor frissül, amikor telepítesz, de mi nem ezt tesszük. Egyszerűen csak kitesszük az éppen telepített SHA-t magán a webappon keresztül és curl azt, ha szükségünk van egy összehasonlítás elvégzésére.

#2 – hozzunk létre leíró ágakat a masterről

Ha bármin elkezdünk dolgozni, hozzunk létre egy leíró nevű ágat a stabil master ágról. Néhány példa a GitHub kódbázisban jelenleg a user-content-cache-key, submodules-init-task vagy redis2-transition lenne. Ennek több előnye is van – az egyik, hogy amikor lekérdezed, láthatod azokat a témákat, amelyeken mindenki más is dolgozott. A másik, hogy ha egy időre elhagyunk egy ágat, és később visszamegyünk hozzá, viszonylag könnyen megjegyezhetjük, hogy mi volt az.

Ez azért jó, mert amikor a GitHub áglista oldalára lépünk, könnyen láthatjuk, hogy mely ágakon dolgoztak mostanában, és nagyjából mennyi munka van rajtuk.

github branch list

Majdnem olyan, mint egy lista a készülő funkciókról az aktuális durva státusszal. Ez az oldal fantasztikus, ha nem használod – csak azokat az ágakat mutatja meg, amelyeken az aktuálisan kiválasztott ágadhoz képest egyedi munka van, és úgy rendezi őket, hogy a legutóbb dolgozottak legyenek a tetején. Ha nagyon kíváncsi vagyok, akkor az ‘Összehasonlítás’ gombra kattintva megnézhetem, hogy mi a tényleges egységes diff és commit lista, ami az adott ághoz tartozik.

Az írás pillanatában tehát 44 olyan ág van a tárolónkban, amin még nincs beolvasztott munka, de azt is látom, hogy ezek közül csak körülbelül 9 vagy 10 ágba került beolvasztás az elmúlt héten.

#3 – push to named branches constantly

Egy másik nagy különbség a git-flow-hoz képest, hogy mi folyamatosan pusholunk a szerveren lévő megnevezett ágakba. Mivel az egyetlen dolog, ami miatt tényleg aggódnunk kell, az master a telepítés szempontjából, a szerverre való pusholás senkit sem zavar össze, vagy zavarja össze a dolgokat – minden, ami nem master, az egyszerűen csak valami, amin dolgozunk.

Ez azt is biztosítja, hogy a munkánkról mindig legyen biztonsági mentés laptopvesztés vagy merevlemez meghibásodás esetén. Ami még ennél is fontosabb, hogy mindenkit folyamatos kommunikációba hoz. Egy egyszerű ‘git fetch’ alapvetően egy TODO listát ad arról, hogy jelenleg ki min dolgozik.

$ git fetchremote: Counting objects: 3032, done.remote: Compressing objects: 100% (947/947), done.remote: Total 2672 (delta 1993), reused 2328 (delta 1689)Receiving objects: 100% (2672/2672), 16.45 MiB | 1.04 MiB/s, done.Resolving deltas: 100% (1993/1993), completed with 213 local objects.From github.com:github/github * charlock-linguist -> origin/charlock-linguist * enterprise-non-config -> origin/enterprise-non-config * fi-signup -> origin/fi-signup 2647a42..4d6d2c2 git-http-server -> origin/git-http-server * knyle-style-commits -> origin/knyle-style-commits 157d2b0..d33e00d master -> origin/master * menu-behavior-act-i -> origin/menu-behavior-act-i ea1c5e2..dfd315a no-inline-js-config -> origin/no-inline-js-config * svg-tests -> origin/svg-tests 87bb870..9da23f3 view-modes -> origin/view-modes * wild-renaming -> origin/wild-renaming

A GitHub Branch List oldalát megnézve mindenki láthatja, hogy a többiek min dolgoznak, így mindenki ellenőrizheti, hogy akar-e segíteni valamiben.

#4 – bármikor nyiss pull request-et

A GitHubnak van egy csodálatos kódellenőrzési rendszere, a Pull Requests, amiről attól tartok, nem elég ember tud. Sokan használják nyílt forráskódú munkára – forkolnak egy projektet, frissítik a projektet, küldenek egy pull requestet a karbantartónak. Azonban könnyen használható belső kódellenőrzési rendszerként is, amit mi is csinálunk.

Ténylegesen inkább ági beszélgetés nézetként használjuk, mint pull requestként. A GitHubban egy (nyilvános vagy privát) projektben az egyik ágból a másikba küldhetsz pull requesteket, így a “Kérlek, egyesítsd ezt” mellett arra is használhatod, hogy azt mondd: “Segítségre vagy felülvizsgálatra van szükségem ezzel kapcsolatban”.

early pr message

Itt láthatod, hogy Josh cc’ing Brianhez felülvizsgálatra, Brian pedig az egyik kódsorral kapcsolatos tanácsokkal érkezik. Lejjebb láthatjuk, hogy Josh elismeri Brian aggályait, és több kódot tol be, hogy megoldja azokat.

több megbeszélés

Végül láthatjuk, hogy még mindig a próba fázisban vagyunk – ez még nem egy telepítésre kész ág, a Pull Requesteket használjuk a kód felülvizsgálatára, jóval azelőtt, hogy ténylegesen be akarjuk olvasztani master a telepítéshez.

Ha elakadtál a funkció vagy ág haladásában, és segítségre vagy tanácsra van szükséged, vagy ha fejlesztő vagy, és szükséged van egy tervezőre, hogy átnézze a munkádat (vagy fordítva), vagy akár ha kevés vagy semmilyen kódod van, de van néhány screenshot comps vagy általános ötleted, akkor nyiss egy pull requestet. A GitHub rendszerében a @felhasználónév hozzáadásával cc-ezhetsz embereket, így ha konkrét emberek véleményét vagy visszajelzését szeretnéd, egyszerűen cc-ezheted őket a PR-üzenetben (ahogy Josh tette fentebb).

Ez azért jó, mert a Pull Request funkció lehetővé teszi, hogy az egyesített diff egyes sorait, egyes commitokat vagy magát a pull requestet kommentáld, és mindent egy vonalban, egyetlen beszélgetési nézetbe vonszol.Azt is lehetővé teszi, hogy továbbra is az ágba tolj, így ha valaki megjegyzi, hogy elfelejtettél valamit csinálni, vagy van egy hiba a kódban, kijavíthatod és tolhatod az ágba, a GitHub megmutatja az új commitokat a beszélgetés nézetben, és így tovább iterálhatsz egy ágon.

Ha az ág már túl régóta nyitva van, és úgy érzed, hogy kezd elszakadni a master ággal, akkor a master ágat beolvaszthatod a témaágadba, és folytathatod. A pull request megbeszélésen vagy a commit listán könnyen láthatod, hogy az ág mikor volt utoljára naprakész a “master”-rel.

master merge

Ha már tényleg és igazán minden elkészült az ágon, és úgy érzed, hogy készen áll a telepítésre, akkor továbbléphetsz a következő lépésre.

#5 – egyesítés csak a pull request felülvizsgálata után

Nem egyszerűen csak közvetlenül a master vagy egy témaágon dolgozunk, és akkor egyesítjük, amikor úgy gondoljuk, hogy kész – megpróbáljuk megszerezni a cégen belül valaki más aláírását. Ez általában egy +1 vagy emoji vagy “:shipit:” megjegyzés, de megpróbáljuk, hogy valaki más is ránézzen.

shipit comment

Ha ezt megkaptuk, és az ág átmegy a CI-n, akkor beolvaszthatjuk a masterbe a telepítéshez, ami automatikusan lezárja a Pull Requestet, amikor pusholjuk.

#6 – telepítés azonnal a felülvizsgálat után

Végre elkészült a munkád és beolvadt a master ágba. Ez azt jelenti, hogy még ha most nem is telepíted, az emberek új munkát fognak alapozni rá, és a következő telepítés, ami valószínűleg néhány órán belül megtörténik, ki fogja tolni. Mivel tehát tényleg nem akarod, hogy valaki más toljon be valamit, amit te írtál, ami tönkretesz dolgokat, az emberek hajlamosak meggyőződni arról, hogy tényleg stabil, amikor beolvad, és az emberek hajlamosak a saját változtatásaikat is betolni.

A tábortűz botunk, a hubot, bármelyik alkalmazott számára képes telepítést végezni, így egy egyszerű:

hubot depoy github to production

a kódot telepíti és nulla leállással újraindítja az összes szükséges folyamatot. A GitHubon láthatod, hogy ez mennyire gyakori:

a campfire naplóink

Láthatod, hogy 6 különböző ember (köztük egy supportos és egy tervező) egy nap alatt körülbelül 24 alkalommal telepített.

Egyetlen egysoros módosítást tartalmazó commitot tartalmazó ágaknál csináltam ezt. A folyamat egyszerű, egyértelmű, skálázható és hatékony. Megcsinálhatod 50 commitot tartalmazó feature branchekkel, amelyeken 2 hétig tartott, vagy 1 commit 10 percig tartott. Ez egy olyan egyszerű és súrlódásmentes folyamat, hogy nem bosszantja az embert, hogy még 1 commit esetében is meg kell tennie, ami azt jelenti, hogy az emberek ritkán próbálják meg kihagyni vagy megkerülni a folyamatot, kivéve, ha a változás olyan kicsi vagy jelentéktelen, hogy egyszerűen nem számít.

Ez egy hihetetlenül egyszerű és hatékony folyamat. Azt hiszem, a legtöbb ember egyetértene azzal, hogy a GitHub egy nagyon stabil platform, hogy a problémákat gyorsan kezelik, ha egyáltalán felmerülnek, és hogy az új funkciókat gyors ütemben vezetik be. Nincs kompromisszum a minőség vagy a stabilitás terén annak érdekében, hogy több sebességet vagy egyszerűséget vagy kevesebb folyamatot kapjunk.”

Következtetés

A Git önmagában is meglehetősen összetett, ha a szükségesnél bonyolultabbá tesszük a vele használt munkafolyamatot, az egyszerűen csak még több mentális terhet ró mindenki napjára. Én mindig azt javasolnám, hogy a lehető legegyszerűbb rendszert használd, ami a csapatod számára működik, és ezt addig csináld, amíg már nem működik, és csak akkor növeld a komplexitást, ha feltétlenül szükséges.

Azoknak a csapatoknak, akiknek hosszabb időközönként (néhány hét és néhány hónap között) kell hivatalos kiadásokat készíteniük, és képesnek kell lenniük a forró javításokra, karbantartási ágakra és egyéb dolgokra, amelyek az ilyen ritkán történő szállításból adódnak, a git-flow-nak van értelme, és nagyon támogatom a használatát.

Azoknak a csapatoknak, akik kialakították a szállítás kultúráját, akik minden nap a termelésbe tolják, akik folyamatosan tesztelnek és telepítenek, én valami egyszerűbbet javasolnék, mint a GitHub Flow.

Leave a Reply