Sziasztok!
Ötletelek egy meglévő monorepo kapcsán, de gondoltam hátha kapok jó tanácsokat, így leírnám dióhéjban a problémámat.
Adott egy monorepo (ezt vegyük kérlek fixnek, nem tudunk elmozdulni belőle még), amiben van több komponens, amiknek a verziója többnyire együtt mozog, de mindenképpen van köztük összefüggés. Például van egy common komponens, ami mindenkinek szükséges és a többi modullal olyan összefüggésben van h. a többi modul verziója csak nagyobb (v egyenlő) lehet mint a commoné egy build során.
Jelenleg kézi builddel készülnek el a komponensek, gyakorlatilag teljesen manuálisan komponensenként, a tárolóban nincs sem tag, sem branch, sem semmi, néhány fejlesztő commitolgat a master branchbe. Ebbe se menjünk bele, hogy miért nincs, ez van sajnos, nem az én repositorym, nem az én workflowm.
A célom az lenne, hogy minimális workflow módosítással a buildet központosítsam és kialakítsak valamiféle release folyamatot, aminek az eredménye valami olyasmi lenne, amit az üzemeltetésben deploy alapnak lehet használni végre és nem ilyen-olyan módon venné át az üzemeltetés a lebuildelt dolgokat, hanem a meglévő GitLab-ben jönne létre pl. Release-ként v. akármilyen Assetként, amit ki kell deployolni.
Ez ugye odáig tiszta h. ha 1 projekt egy komponens, akkor tag-elésre hívnám a CI-t, aki megcsinálja a buildet, release-cli-vel felrakja szépen és utána jenkins/ansible/whatever a release apin keresztül le tudja kérdezni h. adott projektnek mi a latest release-e, honnan lehet beszerezni, stb és meg is vagyunk. Csak ez monorepo és ahány cikket olvastam kb. annyiféle megközelítést láttam.
Az működhetne pl. úgy tagelünk h. a tagben szerepel az adott komponens és annak a verziója, ebből meg a CI kisakkozza h. akkor mit is kell buildelni milyen verzióval, eddig talán ez tűnik a legjobb megoldásnak, de mindenképpen kíváncsi voltam h. ezt ki hogyan csinálná.
Előre is köszönöm a tippeket!
ps: meglehet h. felületes a leírás, de bármilyen kérdésre szívesen válaszolok ha ennyi infó kevés éppkézláb ötlet megfogalmazásához.
Hozzászólások
Szerintem erre nincs semmi megkotes, azt kell csinalni, ami legjobban beleillik a mostani release folyamatba, aztan onnan lehet tovabb menni. Akar minden push utan buildelhetsz egyet, akkor pl. trivialis megnezni, melyik komponensek modosultak, es akkor csak azokbol tudsz egy-egy buildet eloallitani. De persze mukodik az is, hogy csinalsz "kiskutya/v1.1", "cica/v1.2", stb. tageket is, nincs semmi akadalya.
mennyivel nyűgösebb mindent lebuildelni egy-egy tagre, mint a komponenseket egyesével?
nekem az a gut feelingem, hogy ha szelektív build félre fog csúszni idővel, és... káosz lesz.
Tehát van verzió. Honnan jön a verzió? Ha az összefüggés leírható valami programnyelven akkor ide már a GitLab logika nem is kell. A CI minden master commit esetén lefut. egy bash/python/go/java/akármi script meg eldönti mi legyen?
GitLab rules több mindent is tud nézni. Branch, tag, commit ...
Vagy csak simán újra buildlesz mindig mindent. Feltéve ha az app mindig újra buildelhető...
Lehet manual run-nál megadsz egy változót (componentA=true) és akkor csak arra fut le.
Nemtom, nincs rá univerzális megoldás...
"Vagy csak simán újra buildlesz mindig mindent. Feltéve ha az app mindig újra buildelhető..." - na igen, rátapintottál a lényegre. Simán van olyan h. a commit to master miatt commitolódik (deszépszó :)) olyan verzió ahol X modul buildelődik, Y meg nem...
Nyilván ebből kéne elmozdulni, de sajnos egyszerre csak 1 lépés, mert a dev csapatnak ajánlásokat tehetek, de parancsokat nem oszthatok. Elsőre csak azt szeretném elérni h. a dev munkaállomásokról behúzzuk a buildet vhova amit valahogy tudnak triggerelni komponensenként. Erre jött a már fentebb is írt tagelés, ahogy kolléga már fentebb írta is "kutya/1.0.0", "kutya/1.0.1", "macska/2.1.0", stb.
Sajnos az való igaz, hogy nincs univerzális megoldás, de az nekem is segítség h. tőletek is kapok inputot.
Továbbra is az az álláspontom, hogy a CI-t minden egyes commit után meg lehet hívni. Azt nem feltétlenül a CI yaml-nek kell eldönteni, hogy mikor mit kell csinálni. Elborult esetben csinálsz egy szriptet ami a commitból kiszedi hogy melyik fáljok módosultak és az alapján indítja a bildet a megfelelő componensre. Vagy épp nem csinál semmit.
Sokat segítene ha tudnánk, hogy jelenleg te hogyan tudod eldönteni, hogy a buldet mire kell indítani? A verzió változott egy fájlban? Változott egy vagy több fájl? A commit message tartalmaz valamit? A commit message-bem van egy ticket ID? XY commitolt? XY megváltoztatott egy konkrét fájlt? Megannyi kombináció...
A helyzet az, hogy a manuális szó minden tekintetben igaz. Tehát a jelenlegi workflow (nem ér nevetni, én is inkább sírok, de ez van) az, hogy az a néhány dev tologatja a commitjait a GitLab-be kb. ahogy épp eszükbe jut. Van olyan h. commit message sincs (vagy egy pont és/vagy kötőjel). Van olyan h. minden komponensben változik valami 1 commit hatására, de van h. csak mondjuk 1 komponensben.
Az eddig leírtakkal viszont jelenleg még nem tudok mit kezdeni. Lassan de biztosan haladnék, így első körben az éles verzió előállításának műszaki részét, tárolását, ellenőrzését (dtrack, sast) szeretném úgy kivenni a kezükből, hogy azon ők is nyerjenek valamit és ne csak erőszakoskodás legyen h. márpedig így kell mert ezt írja a "hogyan kezeljük a kódot normálisan" doksi. Innen már gondolom érzed, hogy a verzió kiadás is úgy megy h. adott dev, aki az adott komponens fejlesztését javítását felcommitolja, a saját working copyjában csinál most egy buildet és kirakja egy share-re h. akkor itt a release (kézzel ellátja verzióval).
Ezért gondoltam arra, hogy a tagging és a tag-eléskor futtatás a jó irány, mert ezzel a kézi buildet beerőszakolom egy szabaályozott környezetbe, plusz a kódot végre valahogy ellátnánk legalább a kiadott verziókkal.
Rövid válasz az utolsó összes kérdésedre: nem tudok mit figyelni, míg wild-wild west van. A köv. lépés lenne a branching, branching policy, stb. De ahhoz még nekem is feljebb kell kerülni a parancsnoki láncban :) Egyelőre csak üzemeltetési szemmel tudom nézni, plusz üzemeltetési szemmel kellene egy olyan környezetet teremtenem, ahol az ops csapat tudja mit kell deployolni, az hol van, stb.
Bocs, terjengős lett, de így talán jobban érted/értitek a problémáimat (amiből akad nem kevés, de haladunk vmerre :) )
Biztos, hogy itt technikai megoldast kell talalni, es nem a munkaszervezest, atalakitani? Adhatsz alajuk barmilyen lovat, ha egyszer vizicsuszdazni akarnak, es szabad is nekik.
Nem akarok mélységében belemenni, de ahol a fejlesztésvezető egyben tulajdonos is (hello magyar KKV-k zöme), ott nehezen alakítom én a munkaszervezést. Köv. kommentben bővebben egy kicsit.
Hát pedig. Szóval én teljesen megértem, hogy próbálsz kooperatív lenni, én se szeretem a márpedig mostantól így lesz... de... szóval itt nem az a baj, hogy lehetne a fejlesztés folyamatain javítani, hanem az, hogy láthatólag egyáltalán nincsenek. Ez a fejlesztő csapat semmilyen szakmai norma alapján nem végzi el a feladatait, csak gányolják a kódot. Ha te ebbe oldalról jössz, akkor őszintén szólva a saját sírod ásod, ha segítő szándékkal próbálsz alájuk tenni valamit. Úgyse lesz jó (semmi se tud jó lenni ilyen keretek között, mert nem lehet mindent ad-hoc megbaszni, hogy most épp jó legyen, bele fogja verni a fejét a keretbe, meg hülye lesz és nem fogja érteni, mit kell csinálni), és természetesen te leszel a hibás, meg ez az ostoba szarságod, amit ide tettél nekünk, és majd lehet még téged blamelni, hogy miattad nem mennek a dolgok. Ennek a kuplerájnak nem eszközt kell adni a kezébe, hogy hátha így jobb lesz, hanem requirement listát meg felelősséget, hogy az ő dolguk ezt megoldani. Aztán, ha jönnek azzal, hogy a saját dolgukhoz kellene valami, akkor lehet nekik segíteni.
És egyébként ahol ennyire szar sincs, ott teljesen jó stratégia, hogy a "hogyan kezeljük normálisan a kódot" doksiból kiválasztunk valami egyszerűt, és elkezdjük használni, hogy legyen egy bármilyen processz. És ha az már van, akkor lehet majd rájönni, hogy ez hány helyen nem jó, és hogyan kéne jobban csinálni. És amelyik fejlesztő csapat nem tud nagyjából instant elkezdeni használni legalább egy feature branches/mr-es modellt, azt egyben kell kibaszni a picsába, tök őszintén.
---
Hogy azért konkrétumot is írjak :)
Én nem nagyon hiszek abban, hogy vannak itt valódi függőségek, ez a nagyobb kell legyen a verzió ez simán csak egy hiedelem, a gyakorlatban az lesz a valóság, hogy pont azzal, ami pont akkor mellette volt tud fordulni meg működni, a nagyobb verzióval kis szerencsével lefordul (nem változott meg API, amit ugye basznak valójában követni), nagy szerencsével még azt is fogja csinálni, amit az ember gondol (mert nem változott meg a működés sem). Szóval szerintem tagre/gombra nyugodtan előállhat egy olyan verziójú artifact mindenből, azt jóccakát. Ha nagyon kell ez a fantom lófasz, akkor kell csinálni pipeline paramétereket, ahova beleírja azt, amit kb eddig is adhoc csinált: Melyik foldert buildelje le milyen verzióval, aztán azt csinálja meg a pipeline, a végén meg tageljen ő egyet.
Az, hogy egy monorepóból build time egyes részekből nem jó az, ami az aktuális commiton az állapot, azt gitlab ci-val zuzu petals csinálni, valami scripttel alá kell nyúlni, azt össze kell vadászni az apiból, meg másolgatni egy megfelelő állapotú working copyt. Máshol is szar ezt csinálni, de mivel a gitlabban minden a repo köré van szervezve, ezért gyak alágányolni tudsz csak. Máshol (jenkins, tc, akármi) a standard eszközökkel azért könnyebb, hogy van több git forrás, azt pakolod össze a pipelineban.
Teljesen egyet értek, nekem felesleges is leírnod a konkrétumok előtti részt. Azért köszi és kicsit visszacsatolnék rá.
Az előző kommentben írtam is h. ahol az adott KKV tulajdonosa a fejlesztésvezető is, ott nehéz nekem üzemeltetés oldalról megmondani h. hogy csinálja a sz.rját. Az általános válasz a magyar KKV szektorban ezekre a felvetésekre (tldr):
"az plusz munka": Értsd.: neki most csak meg kell nyomni h. commit and push és kész vagyunk. Commit message? dolgozni kell rajta. Taggelés? dolgozni kell rajta. Branchelés? dolgozni kell rajta. És ehhez még kombináld hozzá h. soha nem látták ezeket fogalmakat, mert évekig one man show volt mindegyikük.
"én nem így dolgozom": Értsd.: Összevissza turkálok a kódban, 1-1 commit javít 5 dolgot és behoz 2 új feature-t, meg behoz 3 új bugot. Én tudom, de magyarázd el valakinek aki 20 éve így csinálja h. mostantól 1 branch 1 fix/1 feature/1 topic, nem összevissza ide-oda belenyúlás.
"felesleges bonyolítás": Értsd.: Nem ért senki más a verziókezeléshez, csak te, mi minek tanuljuk meg, 10 éve jó ez így és hozza a pénzt.
"felesleges bonyolítás" v2: Értsd.: Ha te lelépsz, senki se fogja tudni h. mi hogy van, ha meg marad az egyszerű káosz, akkor egy hülye/hozzánemértő is tudja h. a K meghajtón van git repo és kész is vagyunk. Ha meg megkérdezik auditon h. van-e verziókezelés, akkor azt mondjuk igen, végülis van, nem? :)
"felesleges bonyolítás" v3: Értsd.: Behozunk egy halom toolt, ami számomra blackbox, így legalább a saját gépemen lefuttatom a build.sh-t és működik, nem a te szarodon múlik h. lesz-e frissítés. Egyébként meg az összes többit elmondom még egyszer, mert most azt akarod rámerőltetni h. valami olyanban dolgozzak amit nem értek. Végülis programozni sem tanultam, így születtem :) (bocs, itt már ironizálok :) )
---
Konkrétum: Köszi, nekem is ez tűnik jelenleg járhatónak h. a dev ahogy eddig lebuildeli, lepróbálja a cuccot az eddigi környezetében, majd ahhoz h. release legyen felcommitolja a cuccait és csinál egy tag-et (hogy ez most full build v. csak adott komponens, az már mindegy is).
A repon belüli komponensek dependency kezelését nem szeretném a vállamra venni, ellenben ahogy lejjebb is írta valaki (elnézést, oda nem fogok külön válaszolni), legalább az megvan h. az adott dolog kiadásának állapota megvan a gitlaben, a build pedig egy buildszerveren készült, nem jóska windowsos pcjén, amin a f.szom tudja milyen környezet van. Plusz innen még be tudom csomagolni konténerbe is akár, meg üzemeltetésileg tovább tudok lépni.
A fejlesztési metodikára visszakanyarodva, ha eljutunk oda h. legalább ennyi tud működni, akkor már bevonódik az a pár ember a gitlab használatába, mert muszáj lesz neki legalább egy minimálisan. Ezen a ponton már talán el tudok kezdeni beledumálni a folyamatokba, ha egy dolgot látnak h. nem is olyan szar. Szóval a topicnak ezen része (munkaszervezés, social tevékenység) most kicsit kívül esik azon amit meg akarok valósítani, de sajnos pontosan tudom h. ezt is muszáj lesz, mert valakinek az asztalra kell előbb-utóbb csapnia, pont az itt emlegetett minőségellenőrzés/minségirányítás/stb. témakörök miatt.
Sorry, hosszú lett, remélem azért nem csak zöldséget írtam a kis magyar valóságról.
Ok, ez leszűkíti a kört. Marad a tag ill. a manual run. Ha nagyon-nagyon-nagyon kukacoskodi szeretnék akkor azt mondanám, hogy amit szeretnél az sérti a taggelés alapkoncepcióját. A tag előtt illene sok más dolognak is megtörténnie. De technikailag kivitelezhető.
Én lehet inkább a manual run felé mennék. A dev-ek felé lehet egyszerűbb átvinni, talán könnyebben megértik. De nem egyértelmű a választás és igazából az esetedben mindegy is.
Ha ennyire alap szinten van a csapat én már annak is örülnék ha legalább az egyik komponens CI-ból készülne el és eltárolódna (CD) valami központi helyen. Az kb. mindegy hogy ki és hogyan indítja a GitLabban...
Pontosan ebbe az irányba tartok és jelenleg ennél többet nem is tudok megoldani, ez is egy komolyabb ugrás lesz.
A manual run azért kevés önmagában, mert a tag-el első körben az állapot is rögzítésre kerülne (tudom, a runban is tudnék tagelni CI oldalról), így legalább a koncepció -miszerint a kód valóban verziózva van- kezdene megtelepedni a fejekben.
Ehhez ugye az kellene, hogy valaki(k) fegyelmezetten taggelnek. Ez valóban egy nagy lépés lenne, szorítok!
GitLab-ból kézzel indított pipeline-nak még ez sem kell, csak kb arra figyelni, hogy ne írjon felül meglévő dolgokat...
Az nem/szarul fog működni, hogy nincsenek értelmes commit üzenetek (mert valahogy be kell azonosítani, hogy mi mehet a köv release-be).
Első megközelítés: Release brancsra válogassa (egy) valaki oda ami kell bele, aztán arra menjen a tag és ci/cd.
Jelenleg masterből készül kézzel a release, az adott komponensen dolgozás után eszébe jut a fejlesztőnek h. akkor abból fordít egyet és az lesz a release.
Ha ezt azzal első körben kiváltom h. tag komponens/verzió, az úgy kezdésnek nem tűnik számomra használhatatlan megoldásnak. Tény h. kellene normális commit message (policy is), meg branch és branching policy is, de ettől olyan messze vagyunk jelenleg mint Makó Jeruzsálemtől.
Csodálatosan hangzik. Azt nem értem, hogy a "release" (nagyon messze van ez tőle, de mindegy) után miért nem taggelnek? Ha hiba van egy "kiadott" verzióban, akkor hogyan veszik elő annak a verziónak a forrását? Hány helyre szállítanak?
Mindegy, költői kérdések
Csak széljegyzet: Ezen felül még van legalább 10 kérdésem nekem is, de most fogadjuk el h. ez így van.
Hosszú távon rá akarom venni a fejlesztőket h. ezek a dolgok rendbe legyenek rakva, de nem tudom egyszerre az egészet megugrani. A tageléssel legalább azt a problémát megoldanánk amit írtál te is, h. honnan tudom a kód állapotát egy buildhez tag nélkül pl. Volt is már ebből szívás természetesen. Szóval a kérdéseidet én is értem és feltettem, egyelőre egy kérdéssel foglalkozok, aztán jöhet a többi is.
Elgondolkoznék azon hogy:
- meg tudom-e "egyszerre ugrani magamnak" ?
- ugyaanakkor meg tudok-e ugrani egy kisebb lépést a többinek ?
A nagy kérdés hogy ez a cég, ez a vállalati kultúra megérdemli-e egyáltalán az első opciót...
Gábriel Ákos
Vállalati kultúra nincs ott, mert különben ez szabályozva lenne. És persze nem is tudják megugrani, mert csak egy embernek van igénye erre.
biztos hogy release előtt tagel(tet)nék
Gábriel Ákos
Normális esetben nyilván. De ilyen helyzetekben csak akkor célszerű taggelni, ha már tutira lefordult és nem mellesleg működik is.
Miért? Lehet mozgatni azt a teget, lehet új taget adni. Először a release reprodukálhatóságára mennék rá.
Ha megpukkant egy tag, adjon újat, próbálja újra.
Ebből aztán lehet számolni h a release-ek hány százaléka volt épkézláb (a.k.a. minőségirányítás).
Gábriel Ákos
Láttam olyat, ahol sok ezer "rossz" tag volt, mert úgy lett megvalósítva, hogy mindig tagelt, aztán próbált buildelni, és ha nem ment, akkor úgyhagyta. Tisztább megoldásnak vélem, hogy először (itt ugye most kézi módszerekről van szó, a konkrét helyzetre vonatkoztatva) megpróbálnak buildelni (valakinek a gépén, nyilván), aztán ha minden ok, akkor tag, és stb
Ebből így sose lesz mérhetőség. Szerintem a mérhetőség az egyik dolog amit a menedzsment megért (meg kéne értenie)
Gábriel Ákos
:D jelenleg kb cvs-ként használják a git-et, a mérhetőség sok lépéssel odébb van. és ahol ilyenek a viszonyok, ott a menedzsment sincs a topon.
Pedig a gitlab default kb mindent megad neked hogy tudd "normálisan csinálni". :(
Gábriel Ákos
Ehhez nem kell különösebben semmi, csak minimális igényesség és gondolkodás. Persze egy ci/cd megoldás sokat lendít értő kezekben. (a gitlab egy resource hog)
Szerintem összekevered a célt az eszközzel. Nem a kevés "tag" a cél hanem a normális "release".
Ennek majd következménye lesz a relatíve kevés (kevesebb) tag.
Ezt lehet mérni, elég jó indikátora a fejlődésnek.
Ha nagyon fáj akkor API-n keresztül meg tudod tenni a régebbi tag-ek törlését automatikusan.
Gábriel Ákos
Szerintem összekevered a topiknyitót velem. Még1x: láttam olyna környezetet, ahol ezrével voltak olyan tag-ek, amelyek buildelhetetlenek voltak. Személy szerint értelmetlennek látom ezt, de nyilván különbözőek vagyunk.
Metrikát sok mindenre fel lehet állítani, pont az ilyen jellegű mennyiségekre (tag-ek száma, kódsorok száma, etc) legtöbbször felesleges.
A különböző komponensek különböző állapotú összeválogatására egy külön release brancs használata egyszerű és olcsó megoldás. Most az összeválogatás minden komponens gazdának a saját hatásköre és ennek nem kell a release brancson se másképp lennie. Csak a release build kerül központi hatáskörbe.
Igazából ott megy félre a dolog, hogy nem a Gitlab CI dolga tudni, mit kell buildelni.A Gitlab csak azt tudja, hogy mely fájlok változtak. A modul függőségeket az adott programnyelvben egy keretrendszernek kéne tudnia.
Lesarkítva a Gitlab csak annyit tud, hogy hogyan futassa le a "build" parancsot.
Persze lehet vállalkozni rá, hogy a fájlok változásaiból megjósolni, hogy mit kell lebuildelni, de sose lesz igazán jó megoldás. Ha egy modul kikerül vagy új modul jön, vagy csak a függőségek változnak, akkor állandóan bele kell nyúlni a CI-ba.
A modul függősêgek kezelése jobb ha a fejlesztőknél marad és a CI csak egy build parancsot futtat pár kapcsolóval.
Nem tudom milyen programnyelvről van szó, de NodeJS-nél a függőségeket jól lehet kezelni az NX keretrendszerrel.