Gvidilo pri CI/KD en GitLab por la (preskaŭ) absoluta komencanto
Aŭ kiel akiri belajn insignojn por via projekto en unu vespero de facila kodigo
Verŝajne, ĉiu programisto, kiu havas almenaŭ unu dorlotbestan projekton iam, havas jukon pri belaj insignoj kun statusoj, koda kovrado, pakaĵversioj en nuget ... Kaj ĉi tiu juko kondukis min skribi ĉi tiun artikolon. Prepare por verki ĝin, mi ricevis ĉi tiun belecon en unu el miaj projektoj:
Ĉi tiu artikolo gvidos vin tra la baza aranĝo de kontinua integriĝo kaj livero por .Net Core klasbiblioteka projekto en GitLab, publikigante dokumentaron al GitLab Pages, kaj puŝante konstruitajn pakaĵojn al privata nutrado en Azure DevOps.
VS Code estis utiligita kiel la evolumedio kun la etendaĵo GitLab Laborfluo (por validigi la agordan dosieron rekte el la evolumedio).
Mallonga enkonduko
KD - ĉu kiam vi ĵus puŝis, kaj ĉio jam falis sur la klienton?
Kio estas CI / KD kaj kial vi bezonas ĝin - vi povas facile guglo ĝin. Trovu kompletan dokumentaron pri agordo de duktoj en GitLab ankaŭ facila. Ĉi tie mi mallonge kaj, se eble, sen difektoj priskribos la procezon de la sistemo el birda vido:
la programisto sendas kompromiton al la deponejo, kreas kunfandan peton tra la retejo, aŭ alimaniere, eksplicite aŭ implicite komencas la dukton,
ĉiuj taskoj estas elektitaj el la agordo, kies kondiĉoj ebligas lanĉi ilin en la donita kunteksto,
taskoj estas organizitaj laŭ siaj etapoj,
etapoj estas ekzekutitaj laŭvice - t.e. paralela ĉiuj taskoj de ĉi tiu etapo estas plenumitaj,
se la scenejo malsukcesas (t.e., almenaŭ unu el la taskoj de la scenejo malsukcesas), la dukto ĉesas (preskaŭ ĉiam),
se ĉiuj etapoj estas kompletigitaj sukcese, la dukto estas konsiderita sukcesa.
Tiel, ni havas:
dukto - aro da taskoj organizitaj en etapoj en kiuj vi povas konstrui, testi, paki kodon, disfaldi finitan konstruon al nuba servo ktp.,
scenejo (scenejo) — dukto organiza unuo, enhavas 1+ taskon,
tasko (laborposteno) estas laborunuo en la dukto. Ĝi konsistas el skripto (deviga), lanĉkondiĉoj, agordoj por eldonado/kaŝmemoro de artefaktoj, kaj multe pli.
Sekve, la tasko dum la agordo de CI / KD konsistas en krei aron da taskoj, kiuj efektivigas ĉiujn necesajn agojn por konstrui, testi kaj publikigi kodon kaj artefaktojn.
Antaŭ ol komenci: kial?
Kial Gitlab?
Ĉar kiam estis necese krei privatajn deponejojn por dorlotbestaj projektoj, ili estis pagitaj sur GitHub, kaj mi estis avida. La deponejoj fariĝis liberaj, sed ĝis nun ĉi tio ne sufiĉas por ke mi moviĝu al GitHub.
Kial ne Azure DevOps Pipelines?
Ĉar tie la agordo estas elementa - kono de la komandlinio eĉ ne necesas. Integriĝo kun eksteraj git-provizantoj - en kelkaj klakoj, importo de SSH-ŝlosiloj por sendi kommitaĵojn al la deponejo - ankaŭ, la dukto estas facile agordita eĉ ne de ŝablono.
Komenca pozicio: kion vi havas kaj kion vi volas
Ni havas:
deponejo en GitLab.
Ni volas:
aŭtomata kunigo kaj testado por ĉiu kunfanda peto,
konstruante pakaĵojn por ĉiu kunfanda peto kaj puŝi al la majstro, kondiĉe ke estas certa linio en la commit-mesaĝo,
sendante konstruitajn pakaĵojn al privata fluo en Azure DevOps,
kunigo de dokumentado kaj publikigo en GitLab Pages,
insignoj!11
La priskribitaj postuloj organike falas sur la sekva duktomodelo:
Etapo 1 - Asembleo
Ni kolektas la kodon, publikigas la eligajn dosierojn kiel artefaktojn
Etapo 2 - testado
Ni ricevas artefaktojn de la konstrustadio, faras testojn, kolektas kodajn priraportajn datumojn
Etapo 3 - Submeti
Tasko 1 - konstruu la nuget-pakaĵon kaj sendu ĝin al Azure DevOps
Tasko 2 - ni kolektas la retejon de xmldoc en la fontkodo kaj publikigas ĝin en GitLab Pages
Kiam vi alklakas la butonon Krei, la projekto estos kreita kaj vi estos redirektita al ĝia paĝo. En ĉi tiu paĝo, vi povas malŝalti nenecesajn funkciojn irante al la projektaj agordoj (malsupra ligilo en la listo maldekstre -> Superrigardo -> Azure DevOps Services-bloko)
Iru al Atrifacts, alklaku Krei nutradon
Enigu la nomon de la fonto
Elektu videblecon
Malmarku Inkluzivi pakaĵojn el oftaj publikaj fontoj, tiel ke la fonto ne iĝas dumpnuget-klono
Alklaku Konekti por nutri, elektu Visual Studio, kopiu Fonton el la bloko Agordo de Maŝino
Iru al kontaj agordoj, elektu Persona Aliro-Signo
Kreu novan alirĵetonon
Nomo - arbitra
Organizo - Aktuala
Valida por maksimume 1 jaro
Amplekso - Pakado/Legi & Skribi
Kopiu la kreitan ĵetonon - post kiam la modala fenestro estas fermita, la valoro estos neatingebla
Iru al la deponejaj agordoj en GitLab, elektu la CI / KD-agordojn
Vastigu la Variablo-blokon, aldonu novan
Nomo - ajna sen spacoj (estos disponebla en la komanda ŝelo)
Valoro - alirĵetono de paragrafo 9
Elektu Masko-variablon
Ĉi tio kompletigas la antaŭ-agordon.
Preparante la agordan kadron
Defaŭlte, CI/CD-agordo en GitLab uzas la dosieron .gitlab-ci.yml de la radiko de la deponejo. Vi povas agordi arbitran vojon al ĉi tiu dosiero en la deponejaj agordoj, sed ĉi-kaze ĝi ne estas necesa.
Kiel vi povas vidi de la etendaĵo, la dosiero enhavas agordon en la formato YAML. La dokumentaro detaligas kiuj ŝlosiloj povas esti enhavitaj ĉe la supra nivelo de la agordo, kaj ĉe ĉiu el la nestitaj niveloj.
Unue, ni aldonu ligilon al la docker-bildo en la agorda dosiero, en kiu la taskoj estos plenumitaj. Por tio ni trovas Paĝo de bildoj .Net Core sur Docker Hub. la GitHub estas detala gvidilo pri kiu bildo elekti por malsamaj taskoj. Bildo kun .Net Core 3.1 taŭgas por ni konstrui, do bonvolu aldoni la unuan linion al la agordo
image: mcr.microsoft.com/dotnet/core/sdk:3.1
Nun, kiam la dukto estas lanĉita de la Microsoft-bilddeponejo, la specifita bildo estos elŝutita, en kiu ĉiuj taskoj de la agordo estos ekzekutitaj.
La sekva paŝo estas aldoni scenejo's. Defaŭlte, GitLab difinas 5 stadiojn:
.pre - plenumita ĝis ĉiuj etapoj,
.post - farita post ĉiuj etapoj,
build - unue poste .pre scenejo,
test - dua fazo,
deploy - la tria etapo.
Tamen nenio malhelpas vin eksplicite deklari ilin. La ordo en kiu la paŝoj estas listigitaj influas la sinsekvon en kiu ili estas faritaj. Por kompleteco, ni aldonu al la agordo:
stages:
- build
- test
- deploy
Por senararigado, havas sencon ricevi informojn pri la medio en kiu la taskoj estas ekzekutitaj. Ni aldonu tutmondan aron de komandoj, kiuj estos plenumitaj antaŭ ĉiu tasko kun before_script:
before_script:
- $PSVersionTable.PSVersion
- dotnet --version
- nuget help | select-string Version
Restas aldoni almenaŭ unu taskon por ke kiam la kommits estos senditaj, la dukto komenciĝu. Nuntempe, ni aldonu malplenan taskon por montri:
dummy job:
script:
- echo ok
Ni komencas validigon, ni ricevas mesaĝon, ke ĉio estas bona, ni kompromitas, ni puŝas, ni rigardas la rezultojn en la retejo ... Kaj ni ricevas skripto-eraron - bash: .PSVersion: command not found. wtf?
Ĉio estas logika - defaŭlte, kuristoj (respondecaj pri ekzekuto de taskoskriptoj kaj provizitaj de GitLab) uzas bash por plenumi ordonojn. Vi povas ripari ĉi tion eksplicite specifante en la taskopriskribo kiajn etikedojn havu la plenumanta duktokuristo:
dummy job on windows:
script:
- echo ok
tags:
- windows
Bonege! La dukto nun funkcias.
Atenta leganto, ripetinte la indikitajn paŝojn, rimarkos, ke la tasko estis plenumita en la stadio test, kvankam ni ne precizigis la scenejon. Kiel vi eble divenos test estas la defaŭlta paŝo.
Ni daŭrigu krei la agordan skeleton aldonante ĉiujn taskojn priskribitajn supre:
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
Ni ricevis ne precipe funkcian, sed tamen ĝustan dukton.
Agordo de ellasiloj
Pro la fakto, ke neniuj ellasilfiltriloj estas specifitaj por iu ajn el la taskoj, la dukto faros plene esti ekzekutita ĉiufoje kiam kommit estas puŝita al la deponejo. Ĉar ĉi tio ne estas la dezirata konduto ĝenerale, ni starigos ellasilajn filtrilojn por taskoj.
Filtriloj povas esti agorditaj en du formatoj: nur/krom и reguloj. Mallonge, only/except permesas al vi agordi filtrilojn per ellasiloj (merge_request, ekzemple - fiksas la taskon por esti efektivigita ĉiufoje kiam tira peto estas kreita kaj ĉiufoje kiam kommits estas senditaj al la branĉo kiu estas la fonto en la kunfandipeto) kaj branĉonomoj (inkluzive de uzado de regulaj esprimoj); rules permesas al vi agordi aron da kondiĉoj kaj, laŭvole, ŝanĝi la taskan ekzekutkondiĉon depende de la sukceso de antaŭaj taskoj (when en GitLab CI/CD).
Ni rememoru aron da postuloj - muntado kaj testado nur por kunfanda peto, pakado kaj sendado al Azure DevOps - por kunfanda peto kaj puŝoj al la majstro, dokumentada generacio - por puŝoj al la majstro.
Unue, ni agordu la kodan konstrutaskon aldonante regulon, kiu ekfunkciigas nur laŭ kunfanda peto:
build job:
# snip
only:
- merge_request
Nun ni agordu la pakaĵtaskon por ekfunkciigi la kunfandan peton kaj aldonu kommitaĵojn al la majstro:
Dum tasko build job ni devos konstrui artefaktojn, kiuj povas esti reuzitaj en postaj taskoj. Por fari tion, vi devas aldoni la vojojn al la taska agordo, la dosierojn laŭ kiuj vi devos konservi kaj reuzi en la sekvaj taskoj, al la ŝlosilo artifacts:
Padoj subtenas ĵokerojn, kio certe faciligas ilin agordi.
Se tasko kreas artefaktojn, tiam ĉiu posta tasko povos aliri ilin - ili troviĝos laŭ la samaj vojoj rilate al la deponeja radiko, kiu estis kolektita de la origina tasko. Artefaktoj ankaŭ estas elŝuteblaj en la retejo.
Nun kiam ni havas la agordan kadron preta (kaj testita), ni povas efektive verki skriptojn por taskoj.
Ni skribas skriptojn
Eble, iam, en galaksio malproksima, malproksime, konstrui projektojn (inkluzive de tiuj en .net) el la komandlinio estis doloro. Nun vi povas konstrui, testi kaj publikigi la projekton en 3 teamoj:
dotnet build
dotnet test
dotnet pack
Kompreneble, estas kelkaj nuancoj pro kiuj ni iom komplikos la komandojn.
Ni volas eldonan konstruon, ne sencimigan konstruon, do ni aldonas al ĉiu komando -c Release
Dum testado, ni volas kolekti kodajn priraportajn datumojn, do ni devas inkludi priraportanalizilon en la testaj bibliotekoj:
Aldonu la pakaĵon al ĉiuj testaj bibliotekoj coverlet.msbuild: dotnet add package coverlet.msbuild el projekta dosierujo
Aldonu al la komando de prova ekzekuto /p:CollectCoverage=true
Aldonu ŝlosilon al la testa taska agordo por akiri kovrajn rezultojn (vidu sube)
Dum pakado de la kodo en nuget-pakaĵojn, agordu la eligdosierujon por la pakaĵoj: -o .
Kolektante kodajn priraportajn datumojn
Post rulado de la testoj, Coverlet-presaĵoj ruligas statistikojn al la konzolo:
GitLab permesas al vi specifi regulan esprimon por akiri statistikojn, kiuj tiam povas esti akiritaj en formo de insigno. La regula esprimo estas specifita en la taskaj agordoj per la klavo coverage; la esprimo devas enhavi kaptgrupon, kies valoro estos transdonita al la insigno:
test and cover job:
# snip
coverage: /|s*Totals*|s*(d+[,.]d+%)/
Ĉi tie ni ricevas statistikojn de linio kun tuta linio-kovrado.
Eldoni pakojn kaj dokumentadon
Ambaŭ agoj estas planitaj por la lasta etapo de la dukto - ĉar la asembleo kaj testoj pasis, ni povas kunhavigi niajn evoluojn kun la mondo.
Unue, konsideru publikigi al la paka fonto:
Se la projekto ne havas nuget-agordan dosieron (nuget.config), kreu novan: dotnet new nugetconfig
Por kio: la bildo eble ne havas skriban aliron al tutmondaj (uzanto kaj maŝina) agordoj. Por ne kapti erarojn, ni simple kreas novan lokan agordon kaj laboras kun ĝi.
Ni aldonu novan pakfonton al la loka agordo: nuget sources add -name <name> -source <url> -username <organization> -password <gitlab variable> -configfile nuget.config -StorePasswordInClearText
name - loka fonta nomo, ne kritika
url - URL de la fonto el la etapo "Preparado de kontoj", p. 6
organization - nomo de organizo en Azure DevOps
gitlab variable - la nomo de la variablo kun la alirĵetono aldonita al GitLab ("Preparante kontojn", p. 11). Nature, en la formato $variableName
En kazo de eraroj, povas esti utile aldoni -verbosity detailed
Sendante la pakaĵon al la fonto: nuget push -source <name> -skipduplicate -apikey <key> *.nupkg
Ni sendas ĉiujn pakaĵojn el la nuna dosierujo, do *.nupkg.
name - de la supra paŝo.
key - ajna linio. En Azure DevOps, en la fenestro Konekti al feed, la ekzemplo ĉiam estas la linio az.
-skipduplicate - kiam oni provas sendi jam ekzistantan pakaĵon sen ĉi tiu ŝlosilo, la fonto resendos eraron 409 Conflict; per la ŝlosilo, sendo estos preterlasita.
Nun ni agordu la kreadon de dokumentaro:
Unue, en la deponejo, en la majstra branĉo, ni pravigigas la docfx-projekton. Por fari tion, rulu la komandon de la radiko docfx init kaj interage agordi la ŝlosilajn parametrojn por konstrui dokumentadon. Detala priskribo de la minimuma projekto-aranĝo tie.
Dum agordado, estas grave specifi la eligdosierujon ..public - GitLab defaŭlte prenas la enhavon de la publika dosierujo en la radiko de la deponejo kiel fonton por Paĝoj. Ĉar la projekto troviĝos en dosierujo nestita en la deponejo - aldonu eligon al la nivelo supren en la vojo.
Ni puŝu la ŝanĝojn al GitLab.
Aldonu taskon al la dukto-agordo pages (rezervita vorto por retejo-eldonaj taskoj en GitLab Pages):
Skripto:
nuget install docfx.console -version 2.51.0 - instali docfx; la versio estas specifita por certigi, ke la pakaj instalvojoj estas ĝustaj.
.docfx.console.2.51.0toolsdocfx.exe .docfx_projectdocfx.json - kolektado de dokumentado
Nodaj artefaktoj:
pages:
# snip
artifacts:
paths:
- public
Lirika digresio pri docfx
Antaŭe, kiam oni starigis projekton, mi specifis la kodfonton por la dokumentado kiel solvdosieron. La ĉefa malavantaĝo estas, ke dokumentado ankaŭ estas kreita por testaj projektoj. Se tio ne estas necesa, vi povas agordi ĉi tiun valoron al la nodo metadata.src:
metadata.src.src: "../" - ni supreniras unu nivelon rilate al la loko docfx.json, ĉar en ŝablonoj, serĉi la dosierujon ne funkcias.
metadata.src.files: ["**/*.csproj"] - tutmonda ŝablono, ni kolektas ĉiujn C # projektojn de ĉiuj dosierujoj.
metadata.src.exclude: ["*.tests*/**"] - tutmonda ŝablono, ekskludu ĉion el dosierujoj kun .tests En la titolo
Subtotalo
Tia simpla agordo povas esti kreita en nur duonhoro kaj kelkaj tasoj da kafo, kio permesos al vi kontroli, ke la kodo estas konstruita kaj la testoj trapasas, konstrui novan pakaĵon, ĝisdatigi la dokumentadon kaj plaĉi al la okulo per bela. insignoj en la README de la projekto kun ĉiu kunfanda peto kaj sendado al la majstro.
Fina .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
Parolante pri insignoj
Pro ili, finfine, ĉio komenciĝis!
Insignoj kun duktostatusoj kaj koda kovrado estas haveblaj en GitLab en la CI/CD-agordoj en la Gtntral-duktobloko:
Mi kreis insignon kun ligilo al la dokumentaro en la platformo Ŝildoj.io - ĉio estas sufiĉe simpla tie, vi povas krei vian propran insignon kaj ricevi ĝin uzante peton.
![Пример с Shields.io](https://img.shields.io/badge/custom-badge-blue)
Azure DevOps Artefacts ankaŭ permesas krei insignojn por pakaĵoj kun la plej nova versio. Por fari tion, en la fonto sur la retejo Azure DevOps, vi devas alklaki Krei insignon por la elektita pako kaj kopii la markdown-markon:
Aldonante belecon
Emfazante Oftajn Agordajn Fragmentojn
Skribante la agordon kaj serĉante la dokumentadon, mi trovis interesan funkcion de YAML - reuzado de fragmentoj.
Kiel vi povas vidi el la taskaj agordoj, ili ĉiuj postulas la etikedon windows ĉe la kuristo, kaj estas ekigitaj kiam kunfanda peto estas sendita al la majstro/kreita (krom dokumentado). Ni aldonu ĉi tion al la fragmento, kiun ni reuzos:
Kaj nun ni povas enmeti la fragmenton deklaritan pli frue en la taskopriskribon:
build job:
<<: *common_tags
<<: *common_only
Fragmentnomoj devas komenciĝi per punkto, por ne esti interpretitaj kiel tasko.
Pakaĵversiado
Kreante pakaĵon, la kompililo kontrolas la komandliniajn ŝaltilojn, kaj en ilia foresto, la projektodosierojn; kiam ĝi trovas Version-nodon, ĝi prenas sian valoron kiel la versio de la pakaĵo konstruata. Rezultas, ke por konstrui pakaĵon kun nova versio, vi devas aŭ ĝisdatigi ĝin en la projektdosiero aŭ pasigi ĝin kiel komandlinia argumento.
Ni aldonu unu plian Wishlist - lasu la malgravajn du nombrojn en la versio esti la jaro kaj konstrudato de la pakaĵo, kaj aldonu antaŭ-eldonajn versiojn. Kompreneble, vi povas aldoni ĉi tiujn datumojn al la projektdosiero kaj kontroli antaŭ ĉiu sendado - sed vi ankaŭ povas fari ĝin en la dukto, kolektante la pakaĵversion el la kunteksto kaj pasante ĝin tra la komandlinia argumento.
Ni konsentu, ke se la commit-mesaĝo enhavas linion kiel release (v./ver./version) <version number> (rev./revision <revision>)?, tiam ni prenos la version de la pako el ĉi tiu linio, kompletigos ĝin per la aktuala dato kaj transdonos ĝin kiel argumenton al la komando dotnet pack. Se manko de linio, ni simple ne kolektos la pakaĵon.
La sekva skripto solvas ĉi tiun problemon:
# регулярное выражение для поиска строки с версией
$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
Aldonante skripton al tasko pack and deploy job kaj observu la asembleon de pakaĵoj strikte en la ĉeesto de donita ĉeno en la commit-mesaĝo.
Tuta
Pasiginte ĉirkaŭ duonhoron aŭ horon skribante la agordon, sencimigante en la loka powershell kaj, eble, kelkajn malsukcesajn lanĉojn, ni ricevis simplan agordon por aŭtomatigi rutinajn taskojn.
Kompreneble, GitLab CI / KD estas multe pli ampleksa kaj multfaceta ol ĝi povus ŝajni post legado de ĉi tiu gvidilo - tio tute ne veras. Tie eĉ Aŭtomata DevOps estaspermesante
aŭtomate detekti, konstrui, testi, disfaldi kaj monitori viajn aplikojn
Nun la planoj estas agordi dukton por disfaldi aplikaĵojn al Azure, uzante Pulumi kaj aŭtomate determini la celan medion, kiu estos kovrita en la sekva artikolo.