'n Gids tot CI/CD in GitLab vir die (amper) absolute beginner
Of hoe om pragtige kentekens vir jou projek te kry in een aand van maklike kodering
Waarskynlik, elke ontwikkelaar wat een of ander tyd ten minste een troeteldierprojek het, jeuk oor pragtige kentekens met statusse, kodedekking, pakketweergawes in nuget ... En hierdie jeuk het my gelei om hierdie artikel te skryf. Ter voorbereiding vir die skryf daarvan, het ek hierdie skoonheid in een van my projekte gekry:
Hierdie artikel sal jou deur die basiese opstelling van deurlopende integrasie en aflewering vir 'n .Net Core-klasbiblioteekprojek in GitLab lei, dokumentasie na GitLab Pages publiseer, en geboude pakkette na 'n private voer in Azure DevOps stoot.
VS-kode is as die ontwikkelingsomgewing met die uitbreiding gebruik GitLab-werkvloei (vir die validering van die instellingslêer direk vanaf die ontwikkelingsomgewing).
Kort inleiding
CD - is dit toe jy net gedruk het, en alles het reeds op die kliënt geval?
Wat is CI / CD en hoekom jy dit nodig het - jy kan dit maklik google. Vind volledige dokumentasie oor die opstel van pyplyne in GitLab ook maklik. Hier sal ek kortliks en, indien moontlik, sonder gebreke die proses van die stelsel beskryf vanuit 'n voëlvlug:
die ontwikkelaar stuur 'n commit na die bewaarplek, skep 'n samesmeltingsversoek deur die webwerf, of op 'n ander manier, eksplisiet of implisiet die pyplyn begin,
alle take word gekies uit die konfigurasie, waarvan die voorwaardes dit moontlik maak om dit in die gegewe konteks te begin,
take word volgens hul stadiums georganiseer,
stadiums word om die beurt uitgevoer - d.w.s. parallel alle take van hierdie stadium is voltooi,
as die stadium misluk (d.w.s. ten minste een van die take van die stadium misluk), stop die pyplyn (amper altyd),
indien alle fases suksesvol voltooi is, word die pyplyn as suksesvol beskou.
So, ons het:
pyplyn - 'n stel take wat in stadiums georganiseer is waarin jy kan bou, toets, kode verpak, 'n voltooide bouwerk na 'n wolkdiens kan ontplooi, ens.,
taak (werk) is 'n werkseenheid in die pyplyn. Dit bestaan uit 'n skrif (verpligtend), bekendstellingsvoorwaardes, instellings vir die publisering/kas van artefakte, en nog baie meer.
Gevolglik kom die taak by die opstel van CI / CD neer op die skep van 'n stel take wat al die nodige aksies implementeer vir die bou, toets en publiseer van kode en artefakte.
Voordat jy begin: hoekom?
Hoekom Gitlab?
Want toe dit nodig geword het om private bewaarplekke vir troeteldierprojekte te skep, is hulle op GitHub betaal, en ek was gulsig. Die bewaarplekke het gratis geword, maar tot dusver is dit nie genoeg rede vir my om na GitHub te skuif nie.
Hoekom nie Azure DevOps Pipelines nie?
Want daar is die instelling elementêr - kennis van die opdragreël is nie eers nodig nie. Integrasie met eksterne git-verskaffers - in 'n paar kliks, invoer van SSH-sleutels om commits na die bewaarplek te stuur - ook, die pyplyn word maklik gekonfigureer, selfs nie vanaf 'n sjabloon nie.
Beginposisie: wat jy het en wat jy wil hê
Ons het:
bewaarplek in GitLab.
Ons wil hê:
outomatiese samestelling en toetsing vir elke samesmeltingsversoek,
bou pakkette vir elke samesmeltingversoek en druk na die meester, mits daar 'n sekere reël in die commit-boodskap is,
die stuur van geboude pakkette na 'n private voer in Azure DevOps,
samestelling van dokumentasie en publikasie in GitLab Pages,
kentekens!11
Die beskryfde vereistes val organies op die volgende pyplynmodel:
Fase 1 - samestelling
Ons versamel die kode, publiseer die uitvoerlêers as artefakte
Fase 2 - toets
Ons kry artefakte vanaf die boustadium, voer toetse uit, versamel kodedekkingsdata
Fase 3 - Dien in
Taak 1 - bou die nuget-pakket en stuur dit na Azure DevOps
Taak 2 - ons versamel die webwerf van xmldoc in die bronkode en publiseer dit in GitLab Pages
Wanneer jy op die Skep-knoppie klik, sal die projek geskep word en jy sal na sy bladsy herlei word. Op hierdie bladsy kan u onnodige kenmerke deaktiveer deur na die projekinstellings te gaan (onderste skakel in die lys aan die linkerkant -> Oorsig -> Azure DevOps Services-blok)
Gaan na Atrifacts, klik Skep feed
Voer die naam van die bron in
Kies sigbaarheid
Ontmerk Sluit pakkette van algemene openbare bronne in, sodat die bron nie in 'n dump nuget kloon verander nie
Klik Koppel aan voer, kies Visual Studio, kopieer Bron uit die Masjienopstelling-blok
Gaan na rekeninginstellings, kies Persoonlike toegangtoken
Skep 'n nuwe toegangtoken
Naam - arbitrêr
Organisasie - huidige
Geldig vir 'n maksimum van 1 jaar
Omvang - Verpakking/Lees & Skryf
Kopieer die geskepte teken - nadat die modale venster gesluit is, sal die waarde nie beskikbaar wees nie
Gaan na die bewaarplekinstellings in GitLab, kies die CI / CD-instellings
Brei die Veranderlikes-blok uit, voeg 'n nuwe een by
Naam - enige sonder spasies (sal beskikbaar wees in die opdragdop)
Waarde - toegangsteken uit paragraaf 9
Kies Masker veranderlike
Dit voltooi die voorafkonfigurasie.
Voorbereiding van die konfigurasieraamwerk
By verstek gebruik CI/CD-konfigurasie in GitLab die lêer .gitlab-ci.yml vanaf die wortel van die bewaarplek. U kan 'n arbitrêre pad na hierdie lêer in die bewaarplekinstellings stel, maar in hierdie geval is dit nie nodig nie.
Soos u uit die uitbreiding kan sien, bevat die lêer 'n konfigurasie in die formaat YAML. Die dokumentasie gee besonderhede oor watter sleutels op die boonste vlak van die konfigurasie en op elk van die geneste vlakke bevat kan word.
Kom ons voeg eers 'n skakel by die docker-beeld in die konfigurasielêer, waarin die take uitgevoer sal word. Hiervoor vind ons .Net Core-beeldebladsy op Docker Hub. In GitHub daar is 'n gedetailleerde gids oor watter beeld om vir verskillende take te kies. 'n Prent met .Net Core 3.1 is geskik vir ons om te bou, so voeg gerus die eerste reël by die konfigurasie
image: mcr.microsoft.com/dotnet/core/sdk:3.1
Nou, wanneer die pyplyn vanaf die Microsoft-beeldbewaarplek van stapel gestuur word, sal die gespesifiseerde prent afgelaai word, waarin alle take van die konfigurasie uitgevoer sal word.
Die volgende stap is om by te voeg stadiumse. GitLab definieer by verstek 5 stadiums:
.pre - uitgevoer tot op alle stadiums,
.post - uitgevoer na alle stadiums,
build - eers daarna .pre verhoog,
test - tweede fase,
deploy - die derde fase.
Niks verhinder jou egter om hulle uitdruklik te verklaar nie. Die volgorde waarin die stappe gelys word, beïnvloed die volgorde waarin dit uitgevoer word. Vir volledigheid, kom ons voeg by die konfigurasie:
stages:
- build
- test
- deploy
Vir ontfouting is dit sinvol om inligting te kry oor die omgewing waarin die take uitgevoer word. Kom ons voeg 'n globale stel opdragte by wat uitgevoer sal word voor elke taak met before_script:
before_script:
- $PSVersionTable.PSVersion
- dotnet --version
- nuget help | select-string Version
Dit bly om ten minste een taak by te voeg sodat wanneer die commits gestuur word, die pyplyn sal begin. Kom ons voeg vir eers 'n leë taak by om te demonstreer:
dummy job:
script:
- echo ok
Ons begin validering, ons kry 'n boodskap dat alles in orde is, ons verbind, ons druk, ons kyk na die resultate op die webwerf ... En ons kry 'n scriptfout - bash: .PSVersion: command not found. wtf?
Alles is logies - by verstek gebruik hardlopers (verantwoordelik vir die uitvoering van taakskrifte en verskaf deur GitLab) bash opdragte uit te voer. U kan dit regstel deur uitdruklik in die taakbeskrywing te spesifiseer watter etikette die uitvoerende pyplynloper moet hê:
dummy job on windows:
script:
- echo ok
tags:
- windows
Puik! Die pyplyn loop nou.
'n Oplettende leser sal, nadat hy die aangeduide stappe herhaal het, agterkom dat die taak in die stadium voltooi is test, hoewel ons nie die verhoog gespesifiseer het nie. Soos jy dalk kan raai test is die verstekstap.
Kom ons gaan voort met die skep van die konfigurasieskelet deur al die take hierbo beskryf by te voeg:
build job:
script:
- echo "building..."
tags:
- windows
stage: build
test and cover job:
script:
- echo "running tests and coverage analysis..."
tags:
- windows
stage: test
pack and deploy job:
script:
- echo "packing and pushing to nuget..."
tags:
- windows
stage: deploy
pages:
script:
- echo "creating docs..."
tags:
- windows
stage: deploy
Ons het 'n nie besonder funksionele, maar tog korrekte pyplyn gekry.
Stel snellers op
As gevolg van die feit dat geen snellerfilters vir enige van die take gespesifiseer word nie, sal die pyplyn ten volle uitgevoer word elke keer as 'n commit na die bewaarplek gedruk word. Aangesien dit nie die gewenste gedrag in die algemeen is nie, sal ons snellerfilters vir take opstel.
Filters kan in twee formate gekonfigureer word: slegs/behalwe и reëls. Kortliks, only/except laat jou toe om filters op te stel deur snellers (merge_request, byvoorbeeld - stel die taak om uitgevoer te word elke keer as 'n trekversoek geskep word en elke keer wat commits gestuur word na die tak wat die bron in die samesmeltingsversoek is) en takname (insluitend die gebruik van gewone uitdrukkings); rules laat jou toe om 'n stel voorwaardes aan te pas en, opsioneel, die taakuitvoervoorwaarde te verander na gelang van die sukses van vorige take (when in GitLab CI/CD).
Kom ons onthou 'n stel vereistes - samestelling en toetsing slegs vir samesmeltingversoek, verpakking en stuur na Azure DevOps - vir samesmeltingversoek en stoot na die meester, dokumentasiegenerering - vir stoot na die meester.
Kom ons stel eers die kodebou-taak op deur 'n reël by te voeg wat slegs op samevoegingversoek begin:
build job:
# snip
only:
- merge_request
Kom ons stel nou die verpakkingstaak op om op die samesmeltingversoek te gebruik en voeg commits by die meester:
Tydens 'n taak build job ons sal bou-artefakte hê wat hergebruik kan word in daaropvolgende take. Om dit te doen, moet jy die paaie by die taakkonfigurasie voeg, die lêers waarlangs jy in die volgende take moet stoor en hergebruik, by die sleutel artifacts:
Paadjies ondersteun jokertekens, wat dit beslis makliker maak om te stel.
As 'n taak artefakte skep, sal elke daaropvolgende taak toegang daartoe hê - hulle sal langs dieselfde paaie geleë wees relatief tot die bewaarplekwortel wat van die oorspronklike taak versamel is. Artefakte is ook beskikbaar vir aflaai op die webwerf.
Noudat ons 'n konfigurasieraamwerk gereed (en getoets) het, kan ons voortgaan om werklik skrifte vir take te skryf.
Ons skryf skrifte
Miskien, eens op 'n tyd, in 'n sterrestelsel ver, ver weg, was dit 'n pyn om projekte (insluitend dié op .net) vanaf die opdragreël te bou. Nou kan jy die projek in 3 spanne bou, toets en publiseer:
dotnet build
dotnet test
dotnet pack
Natuurlik is daar 'n paar nuanses waardeur ons die opdragte ietwat sal kompliseer.
Ons wil 'n vrystellingbou hê, nie 'n ontfoutbou nie, so ons voeg by elke opdrag -c Release
Wanneer ons toets, wil ons kodedekkingsdata insamel, daarom moet ons 'n dekkingontleder by die toetsbiblioteke insluit:
Voeg die pakket by alle toetsbiblioteke coverlet.msbuild: dotnet add package coverlet.msbuild uit die projekmap
Voeg by die toetsloop-opdrag /p:CollectCoverage=true
Voeg 'n sleutel by die toetstaakkonfigurasie om dekkingresultate te kry (sien hieronder)
Wanneer u die kode in nuget-pakkette verpak, stel die uitvoergids vir die pakkette: -o .
Versamel kode dekking data
Nadat die toetse uitgevoer is, druk Coverlet loopstatistieke na die konsole af:
GitLab laat jou toe om 'n gereelde uitdrukking te spesifiseer om statistieke te kry, wat dan in die vorm van 'n kenteken verkry kan word. Die gereelde uitdrukking word in die taakinstellings gespesifiseer met die sleutel coverage; die uitdrukking moet 'n vanggroep bevat, waarvan die waarde na die kenteken oorgedra sal word:
test and cover job:
# snip
coverage: /|s*Totals*|s*(d+[,.]d+%)/
Hier kry ons statistieke van 'n lyn met totale lyndekking.
Publiseer pakkette en dokumentasie
Albei aksies is geskeduleer vir die laaste fase van die pyplyn - aangesien die samestelling en toetse geslaag het, kan ons ons ontwikkelings met die wêreld deel.
Oorweeg eers om na die pakketbron te publiseer:
As die projek nie 'n nuget-konfigurasielêer het nie (nuget.config), skep 'n nuwe een: dotnet new nugetconfig
Hoekom: die prent het dalk nie skryftoegang tot globale (gebruiker en masjien) konfigurasies nie. Om nie foute op te vang nie, skep ons eenvoudig 'n nuwe plaaslike konfigurasie en werk daarmee.
Kom ons voeg 'n nuwe pakketbron by die plaaslike konfigurasie: nuget sources add -name <name> -source <url> -username <organization> -password <gitlab variable> -configfile nuget.config -StorePasswordInClearText
name - plaaslike bronnaam, nie krities nie
url - URL van die bron vanaf die stadium "Voorbereiding van rekeninge", bl. 6
organization - organisasie naam in Azure DevOps
gitlab variable - die naam van die veranderlike met die toegangsteken wat by GitLab gevoeg is ("Voorbereiding van rekeninge", bl. 11). Natuurlik, in die formaat $variableName
In die geval van foute, kan dit nuttig wees om by te voeg -verbosity detailed
Stuur die pakkie na die bron: nuget push -source <name> -skipduplicate -apikey <key> *.nupkg
Ons stuur alle pakkette vanaf die huidige gids, so *.nupkg.
name - vanaf die stap hierbo.
key - enige lyn. In Azure DevOps, in die Connect to feed-venster, is die voorbeeld altyd die lyn az.
-skipduplicate - wanneer u probeer om 'n reeds bestaande pakket sonder hierdie sleutel te stuur, sal die bron 'n fout terugstuur 409 Conflict; met die sleutel sal versending oorgeslaan word.
Kom ons stel nou die skepping van dokumentasie op:
Eerstens, in die bewaarplek, in die meestertak, inisialiseer ons die docfx-projek. Om dit te doen, voer die opdrag vanaf die wortel docfx init en stel interaktief die sleutelparameters vir boudokumentasie in. Gedetailleerde beskrywing van die minimum projekopstelling hier.
By die konfigurasie is dit belangrik om die uitvoergids te spesifiseer ..public - GitLab neem by verstek die inhoud van die publieke vouer in die wortel van die bewaarplek as 'n bron vir Pages. Omdat die projek sal geleë wees in 'n vouer wat in die bewaarplek geneste is - voeg 'n uitvoer by tot die vlak bo in die pad.
Kom ons druk die veranderinge na GitLab.
Voeg 'n taak by die pyplynkonfigurasie pages (gereserveerde woord vir werfpubliseringstake in GitLab-bladsye):
Skrip:
nuget install docfx.console -version 2.51.0 - installeer docfx; die weergawe word gespesifiseer om te verseker dat die pakketinstallasiepaaie korrek is.
.docfx.console.2.51.0toolsdocfx.exe .docfx_projectdocfx.json - versameling van dokumentasie
Nodus artefakte:
pages:
# snip
artifacts:
paths:
- public
Liriese afwyking oor docfx
Voorheen, toe ek 'n projek opgestel het, het ek die kodebron vir die dokumentasie as 'n oplossinglêer gespesifiseer. Die grootste nadeel is dat dokumentasie ook vir toetsprojekte geskep word. As dit nie nodig is nie, kan jy hierdie waarde op die nodus stel metadata.src:
metadata.src.src: "../" - ons gaan een vlak hoër relatief tot die ligging docfx.json, omdat in patrone werk dit nie om die gidsboom op te soek nie.
metadata.src.files: ["**/*.csproj"] - 'n globale patroon, ons versamel alle C #-projekte uit alle dopgehou.
metadata.src.exclude: ["*.tests*/**"] - globale patroon, sluit alles uit van dopgehou met .tests In die titel
subtotaal
So 'n eenvoudige konfigurasie kan in net 'n halfuur en 'n paar koppies koffie geskep word, wat jou sal toelaat om te kyk of die kode gebou is en die toetse slaag, 'n nuwe pakket bou, die dokumentasie opdateer en die oog met pragtige kentekens in die README van die projek met elke samesmeltingversoek en stuur aan die meester.
Finale .gitlab-ci.yml
image: mcr.microsoft.com/dotnet/core/sdk:3.1
before_script:
- $PSVersionTable.PSVersion
- dotnet --version
- nuget help | select-string Version
stages:
- build
- test
- deploy
build job:
stage: build
script:
- dotnet build -c Release
tags:
- windows
only:
- merge_requests
- master
artifacts:
paths:
- your/path/to/binaries
test and cover job:
stage: test
tags:
- windows
script:
- dotnet test -c Release /p:CollectCoverage=true
coverage: /|s*Totals*|s*(d+[,.]d+%)/
only:
- merge_requests
- master
pack and deploy job:
stage: deploy
tags:
- windows
script:
- dotnet pack -c Release -o .
- dotnet new nugetconfig
- nuget sources add -name feedName -source https://pkgs.dev.azure.com/your-organization/_packaging/your-feed/nuget/v3/index.json -username your-organization -password $nugetFeedToken -configfile nuget.config -StorePasswordInClearText
- nuget push -source feedName -skipduplicate -apikey az *.nupkg
only:
- master
pages:
tags:
- windows
stage: deploy
script:
- nuget install docfx.console -version 2.51.0
- $env:path = "$env:path;$($(get-location).Path)"
- .docfx.console.2.51.0toolsdocfx.exe .docfxdocfx.json
artifacts:
paths:
- public
only:
- master
Van kentekens gepraat
As gevolg van hulle is alles immers begin!
Kentekens met pyplynstatusse en kodedekking is beskikbaar in GitLab in die CI/CD-instellings in die Gtntral-pypleidingsblok:
Ek het 'n kenteken geskep met 'n skakel na die dokumentasie op die platform shields.io - alles is redelik eenvoudig daar, jy kan jou eie kenteken skep en dit met 'n versoek ontvang.
![Пример с Shields.io](https://img.shields.io/badge/custom-badge-blue)
Azure DevOps Artifacts laat jou ook toe om kentekens vir pakkette met die nuutste weergawe te skep. Om dit te doen, in die bron op die Azure DevOps-werf, moet jy op Skep kenteken vir die geselekteerde pakket klik en die afmerkopmerk kopieer:
Byvoeging van skoonheid
Verlig algemene konfigurasiefragmente
Terwyl ek die konfigurasie geskryf en deur die dokumentasie gesoek het, het ek op 'n interessante kenmerk van YAML afgekom - hergebruik van fragmente.
Soos u uit die taakinstellings kan sien, benodig hulle almal die merker windows by die hardloper, en word geaktiveer wanneer 'n samesmeltingversoek na die meester gestuur/geskep word (behalwe dokumentasie). Kom ons voeg dit by die fragment wat ons sal hergebruik:
En nou kan ons die fragment wat vroeër verklaar is in die taakbeskrywing invoeg:
build job:
<<: *common_tags
<<: *common_only
Fragmentname moet met 'n punt begin, om nie as 'n taak geïnterpreteer te word nie.
Pakketweergawe
Wanneer 'n pakket geskep word, kontroleer die samesteller die opdragreëlskakelaars, en in hul afwesigheid, die projeklêers; wanneer dit 'n weergawe-nodus vind, neem dit die waarde daarvan as die weergawe van die pakket wat gebou word. Dit blyk dat om 'n pakket met 'n nuwe weergawe te bou, jy dit óf in die projeklêer moet opdateer óf dit as 'n opdragreëlargument moet deurgee.
Kom ons voeg nog een wenslys by - laat die klein twee nommers in die weergawe die jaar en boudatum van die pakket wees, en voeg voorvrystelling weergawes by. Natuurlik kan jy hierdie data by die projeklêer voeg en voor elke indiening nagaan - maar jy kan dit ook in die pyplyn doen, die pakketweergawe uit die konteks versamel en dit deur die opdragreëlargument stuur.
Kom ons stem saam dat as die commit-boodskap 'n reël soos bevat release (v./ver./version) <version number> (rev./revision <revision>)?, dan sal ons die weergawe van die pakket van hierdie reël neem, dit aanvul met die huidige datum en dit as 'n argument aan die opdrag gee dotnet pack. In die afwesigheid van 'n lyn, sal ons eenvoudig nie die pakket kom haal nie.
Die volgende skrif los hierdie probleem op:
# регулярное выражение для поиска строки с версией
$rx = "releases+(v.?|ver.?|version)s*(?<maj>d+)(?<min>.d+)?(?<rel>.d+)?s*((rev.?|revision)?s+(?<rev>[a-zA-Z0-9-_]+))?"
# ищем строку в сообщении коммита, передаваемом в одной из предопределяемых GitLab'ом переменных
$found = $env:CI_COMMIT_MESSAGE -match $rx
# совпадений нет - выходим
if (!$found) { Write-Output "no release info found, aborting"; exit }
# извлекаем мажорную и минорную версии
$maj = $matches['maj']
$min = $matches['min']
# если строка содержит номер релиза - используем его, иначе - текущий год
if ($matches.ContainsKey('rel')) { $rel = $matches['rel'] } else { $rel = ".$(get-date -format "yyyy")" }
# в качестве номера сборки - текущие месяц и день
$bld = $(get-date -format "MMdd")
# если есть данные по пререлизной версии - включаем их в версию
if ($matches.ContainsKey('rev')) { $rev = "-$($matches['rev'])" } else { $rev = '' }
# собираем единую строку версии
$version = "$maj$min$rel.$bld$rev"
# собираем пакеты
dotnet pack -c Release -o . /p:Version=$version
Voeg 'n skrif by 'n taak pack and deploy job en let op die samestelling van pakkette streng in die teenwoordigheid van 'n gegewe string in die commit-boodskap.
In totaal
Nadat ons ongeveer 'n halfuur of 'n uur bestee het aan die skryf van die konfigurasie, ontfouting in die plaaslike powershell en moontlik 'n paar onsuksesvolle bekendstellings, het ons 'n eenvoudige konfigurasie gekry om roetinetake te outomatiseer.
Natuurlik is GitLab CI / CD baie meer omvangryk en veelsydiger as wat dit mag lyk na die lees van hierdie gids - dit is glad nie waar nie. Daar selfs Auto DevOps istoelaat
bespeur, bou, toets, ontplooi en monitor u toepassings outomaties
Nou is die planne om 'n pyplyn op te stel vir die implementering van toepassings na Azure, met behulp van Pulumi en outomatiese bepaling van die teikenomgewing, wat in die volgende artikel gedek sal word.