Opi rakentamaan kevyitä ja luotettavia GitLab CI -monorepojen putkia hyödyntämällä ehdollisia includeja, rules:changes-toimintoa ja käytännönläheisiä pipelinejen parhaita käytäntöjä.
Joonas Jauhiainen
DevOps Lead
Joonas is a DevOps lead with experience in telecom, banking, insurance, and manufacturing, among other industries. His hobbies include investigation of IT devices, developing games and other SW projects not to mention underwater rugby!
GitLab-monorepon CI:n do’s and don’ts
Tässä artikkelissa keskitytään siihen, miten monorepo-pipelineja hallitaan tehokkaasti GitLab CI:n avulla. Erityisesti hyödynnetään modernia ehdollista logiikkaa, jotta konfiguraatiot pysyvät kevyinä ja luotettavina.
GitLab 16.4:ssä otettiin käyttöön uusia sääntöjä, jotka helpottavat monorepo-pipelinejen hallintaa GitLab CI:tä käytettäessä. Tämä on hyvä huomioida, jos käytössäsi on vanhempi versio.
Rakennettuani ja rikottuani näitä pipelineja useita kertoja olen oppinut tarkalleen, mikä toimii – ja ennen kaikkea, mikä ei toimi.
GitLab-monorepon pipeline selitettynä
Tätä blogikirjoitusta varten olen valmistellut julkiselle GitLab-tililleni teknisen demon Atihinen/monorepo-demo,, johon viittaan kirjoituksen aikana.
Yksi monorepojen varhaisten versioiden keskeisistä haasteista oli CI/CD:n monimutkaisuuden hallinta. Aiemmin jokainen alipipeline tai job-konfiguraatio piti sisällyttää ehdoitta, minkä jälkeen jokaiseen yksittäiseen jobiin piti määritellä tarkat säännöt sen ratkaisemiseksi, tulisiko sen suorittua. Tuloksena oli valtavia, vaikeasti ylläpidettäviä tiedostoja ja sekavia pipeline-arviointeja.
GitLabin päivitysten ansiosta changes-avainsana voidaan nyt arvioida suoraan ehdollisissa include-lauseissa. Voimme siis kirjoittaa kevyen ja luotettavan ylimmän tason pipelinen, joka hakee alusta asti mukaan vain tarvittavat alipipelinet.
monorepo-demo-projektissani pääpipeline hallitsee kahta rinnakkain kehitettävää erillistä CLI-työkalua: toinen on kirjoitettu Golla (cligo) ja toinen Pythonilla (clipy). Lisäksi projektissa on dokumentaatiokansio.
Näin ylimmän tason pipeline orkestroi nämä aliprojektit ehdollisesti:
Aloitetaan nyt kahden viime vuoden aikana tekemistäni havainnoista.
Tee näin: määritä .gitlab-ci.yml huolellisesti
Kun luot monorepolle juuritason pipelinen GitLab CI:ssä, määritä ja suunnittele tarvittavat staget huolellisesti. Varmista myös, että juuritason pipelinessa on määritelty jobeja siltä varalta, etteivät alipipelinet korvaa tai luo jobeja stageihin. Muuten seurauksena voi olla ajonaikaisia virheitä. Pää-yml-tiedoston ”paikkamerkkijobin” voisi helposti ajatella olevan esimerkiksi echo-komento, mutta suosittelen sen sijaan suorittamaan jotain, joka tuottaa jo arvoa kehitystyölle.
Demorepossani olen määrittänyt seuraavat staget (https://gitlab.com/Atihinen/monorepo-demo/-/blob/main/.gitlab-ci.yml?ref_type=heads#L2):
static_analysis
build
Olen määrittänyt pääpipelineen seuraavat jobit:
Sen sijaan, että kaikki jobit vain tulostaisivat ”jotain mahtavaa”, lisäsin päätasolle jo oletuslinterit, sillä ne ovat nopeita suorittaa jokaisella commitilla. Build-stageen en valitettavasti pystynyt määrittämään yhteistä nimittäjää, koska se riippuu vahvasti tuotteesta.
Älä: odota voivasi mukauttaa alipipelineja
Edellisessä luvussa kehotin miettimään tarkkaan, mitä stageja pipelineen tarvitaan. Syy on tämä: GitLab ei tue uusia stageja alipipelineissa. Katso tämä commit (https://gitlab.com/Atihinen/monorepo-demo/-/commit/e838b935e9e9ee6577e1ef9404339bca05418acc):
Tämä johtaa GitLab CI:ssä virheeseen (https://gitlab.com/Atihinen/monorepo-demo/-/pipelines/1645391400):
deploy-go job: chosen stage deploy does not exist; available stages are .pre, static-analysis, build, .post
Tee näin: käytä uusia stageja luomisen sijaan avainsanaa 'needs'
Uusia stageja kannattaa ottaa käyttöön, jos jokainen alipipeline todella käyttää niitä. Tällöin ylimmälle tasolle on varmuuden vuoksi toteutettava jälleen yksi job.
Edellisen luvun esimerkissä GoLang-alipipeline tarvitsisi uuden ”deploy”-stagen käyttöönottoa varten, mutta Python-pipeline ei tarvitsisi sitä. Tämä voidaan ratkaista GitLabin needs-avainsanalla (https://docs.gitlab.com/ci/yaml/#needs). Sen avulla voimme määrittää uuden jobin esimerkiksi build-stageen, mutta tämä deploy-job suoritetaan vasta, kun esimerkiksi build-go-job on valmis.
Älä: Oleta, että * on jokerimerkki
Aluksi ajattelin, että path/to/some/src/* riittäisi (https://gitlab.com/Atihinen/monorepo-demo/-/blob/main/.gitlab-ci.yml?ref_type=heads#L38):
GitLab tulkitsee *-jokerimerkin vain määritetyn polun ylimmällä tasolla. Se ei käy läpi alihakemistoja.
Voit tarkistaa, miten tämä toimii käytännössä (https://gitlab.com/Atihinen/monorepo-demo/-/pipelines/1643388739)
Tämä ei käynnistänyt odotettua mdlint-työtä (https://gitlab.com/Atihinen/monorepo-demo/-/pipelines/1643389164).
Tee näin: Käytä */** *-merkin sijaan
Edellisessä luvussa selitin, miksi path/to/something/in/repo/* ei ole hyvä ratkaisu. Käytä sen sijaan polkua path/to/something/in/repo/*/**, jotta kaikki kyseisen polun alla tehdyt muutokset täsmäävät.
Esimerkki:
Tämä täsmää kaikkiin cligo/-hakemiston alla tehtyihin tiedostomuutoksiin.
Yhteenveto
GitLab CI:n uusi rules:changes-avainsana on tehokas työkalu monorepojen kanssa käytettäväksi, mutta siinä on muutamia sudenkuoppia, jotka on hyvä tuntea. Toivottavasti näiden esimerkkien avulla sinun ei tarvitse törmätä samoihin ongelmiin ja käyttää liikaa aikaa sen selvittämiseen, miksi tämä ei toimi odottamallasi tavalla.
- GitLab
- CI/CD
Subscribe to our newsletter
Related blogs