Või kuidas hankida ühe lihtsa kodeerimise õhtuga oma projektile ilusaid märke
Tõenäoliselt on igal arendajal, kellel on mingil hetkel vähemalt üks lemmikloomaprojekt, kihelus ilusate olekutega märgide, koodi katvuse, nugeti paketi versioonide pärast ... Ja see kihelus pani mind selle artikli kirjutama. Selle kirjutamiseks valmistudes sain selle kaunitari ühes oma projektis:

See artikkel juhendab teid GitLabis .Net Core klassi raamatukogu projekti pideva integreerimise ja edastamise põhiseadistuse, GitLabi lehtedel dokumentatsiooni avaldamise ja ehitatud pakettide edastamise Azure DevOpsi privaatsesse voogu.
Laiendusega arenduskeskkonnana kasutati VS Code'i (seadete faili kinnitamiseks otse arenduskeskkonnast).
Lühitutvustus
CD - kas see on siis, kui sa lihtsalt lükkasid ja kõik on juba kliendi peale kukkunud?
Mis on CI / CD ja miks seda vaja on - saate seda hõlpsalt googeldada. Leidke täielik dokumentatsioon torujuhtmete konfigureerimise kohta GitLabis . Siin kirjeldan lühidalt ja võimalusel ilma vigadeta süsteemi protsessi linnulennult:
- arendaja saadab hoidlasse kohustuse, loob saidi kaudu liitmistaotluse, või mõnel muul viisil otseselt või kaudselt käivitab konveieri,
- konfiguratsioonist valitakse kõik ülesanded, mille tingimused võimaldavad neid antud kontekstis käivitada,
- ülesanded on korraldatud vastavalt nende etappidele,
- etapid täidetakse kordamööda – st. paralleelselt kõik selle etapi ülesanded on täidetud,
- kui etapp ebaõnnestub (st vähemalt üks etapi ülesannetest ebaõnnestub), torujuhe peatub (peaaegu alati),
- kui kõik etapid on edukalt läbitud, loetakse torujuhe edukaks.
Seega on meil:
- konveier – etappideks jaotatud ülesannete kogum, mille käigus saate koostada, testida, pakkida koodi, juurutada valmis ehitust pilveteenusesse jne,
- etapp (etapp) — torujuhtme organisatsiooniüksus, sisaldab 1+ ülesannet,
- ülesanne (töö) on töös olev tööühik. See koosneb skriptist (kohustuslik), käivitustingimustest, artefaktide avaldamise/vahemällu salvestamise sätetest ja paljust muust.
Sellest tulenevalt taandub CI / CD seadistamise ülesanne ülesannete komplekti loomisele, mis rakendab kõiki koodi ja artefaktide loomiseks, testimiseks ja avaldamiseks vajalikke toiminguid.
Enne alustamist: miks?
- Miks Gitlab?
Sest kui oli vaja luua lemmikloomaprojektide jaoks privaatseid hoidlaid, maksti neile GitHubis ja ma olin ahne. Hoidlad on muutunud tasuta, kuid siiani pole see piisav põhjus, et ma saaksin GitHubisse kolida.
- Miks mitte Azure DevOps Pipelines?
Kuna seal on seadistus elementaarne - käsurea tundmine pole isegi vajalik. Integratsioon väliste git-pakkujatega – paari klõpsuga SSH-võtmete import hoidlasse kohustuste saatmiseks – samuti on konveieri hõlpsasti konfigureeritav isegi mitte malli järgi.
Lähtepositsioon: mis sul on ja mida sa tahad
Meil on:
- hoidla GitLabis.
Me tahame:
- iga ühendamistaotluse automaatne kokkupanek ja testimine,
- pakettide koostamine iga liitmistaotluse jaoks ja edastamine ülemseadmele, eeldusel, et kinnitusteates on kindel rida,
- ehitatud pakettide saatmine Azure DevOpsi privaatsesse voogu,
- dokumentatsiooni koostamine ja avaldamine GitLabi lehtedel,
- märgid!11
Kirjeldatud nõuded langevad orgaaniliselt järgmisele torujuhtme mudelile:
- 1. etapp – kokkupanek
- Kogume koodi, avaldame väljundfailid artefaktidena
- 2. etapp – testimine
- Me hangime koostamise etapist artefakte, teeme teste, kogume koodi katvuse andmeid
- 3. etapp – esita
- Ülesanne 1 – koostage nugeti pakett ja saatke see Azure DevOpsi
- Ülesanne 2 – kogume saidi lähtekoodi xmldoc-ist ja avaldame selle GitLabi lehtedel
Alustame!
Konfiguratsiooni kogumine
Kontode ettevalmistamine
Loo konto sisse
Minema
Loome uue projekti
- Nimi - mis tahes
- Nähtavus - mis tahes

Kui klõpsate nupul Loo, luuakse projekt ja teid suunatakse selle lehele. Sellel lehel saate mittevajalikud funktsioonid keelata, minnes projekti seadetesse (vasakpoolses loendis alumine link -> Ülevaade -> Azure DevOps Services plokk)

Avage Atrifacts ja klõpsake käsul Loo voog
- Sisestage allika nimi
- Valige nähtavus
- Tühjendage märge Kaasake paketid levinud avalikest allikatest, et allikas ei muutuks prügimägede klooniks

Klõpsake nuppu Ühenda söödaga, valige Visual Studio, kopeerige allikas Masina seadistusplokist

Avage konto seaded, valige Isiklik juurdepääsuluba

Looge uus juurdepääsuluba
- Nimi - meelevaldne
- Organisatsioon – praegune
- Kehtib maksimaalselt 1 aasta
- Reguleerimisala – pakendamine/lugemine ja kirjutamine

Kopeerige loodud märk - pärast modaalakna sulgemist pole väärtus saadaval
Avage GitLabi hoidla seaded, valige CI / CD sätted

Laiendage muutujate plokki, lisage uus
- Nimi – mis tahes ilma tühikuteta (saadaval käsukestas)
- Väärtus – juurdepääsuluba lõikest 9
- Valige maski muutuja

See lõpetab eelkonfiguratsiooni.
Konfiguratsiooniraamistiku ettevalmistamine
Vaikimisi kasutab GitLabi CI/CD konfiguratsioon faili .gitlab-ci.yml hoidla juurest. Hoidla sätetes saate määrata selle faili suvalise tee, kuid sel juhul pole see vajalik.
Nagu laiendist näete, sisaldab fail vormingus konfiguratsiooni YAML. Dokumentatsioonis kirjeldatakse üksikasjalikult, millised võtmed võivad sisalduda konfiguratsiooni ülemisel tasemel ja igal pesastatud tasemel.
Esmalt lisame konfiguratsioonifaili dokkeri pildi lingi, milles ülesandeid täidetakse. Selle jaoks leiame . Sisse seal on üksikasjalik juhend, millist pilti erinevate ülesannete jaoks valida. Meile sobib .Net Core 3.1-ga pilt, nii et lisage julgelt konfiguratsiooni esimene rida
image: mcr.microsoft.com/dotnet/core/sdk:3.1Nüüd, kui konveier käivitatakse Microsofti pildihoidlast, laaditakse alla määratud pilt, milles täidetakse kõik konfiguratsiooni toimingud.
Järgmine samm on lisada etapp's. Vaikimisi määratleb GitLab 5 etappi:
.pre- sooritatud kuni kõikide etappideni,.post- sooritatakse pärast kõiki etappe,build- kõigepealt pärast.prelava,test- teine etapp,deploy- kolmas etapp.
Kuid miski ei takista teil neid selgesõnaliselt deklareerimast. Toimingute loendi järjekord mõjutab nende sooritamise järjekorda. Täielikkuse huvides lisame konfiguratsioonile:
stages:
- build
- test
- deploySilumiseks on mõttekas hankida teavet keskkonna kohta, kus ülesandeid täidetakse. Lisame globaalse käskude komplekti, mis täidetakse enne iga toimingut before_script:
before_script:
- $PSVersionTable.PSVersion
- dotnet --version
- nuget help | select-string VersionJääb üle lisada vähemalt üks ülesanne, et kui commits on saadetud, käivitub konveier. Nüüd lisame demonstreerimiseks tühja ülesande:
dummy job:
script:
- echo okAlustame valideerimist, saame teate, et kõik on korras, pühendume, surume, vaatame saidil tulemusi ... Ja saame skriptivea - bash: .PSVersion: command not found. wtf?
Kõik on loogiline – vaikimisi kasutavad jooksjad (vastutavad ülesannete skriptide täitmise eest ja mida pakub GitLab) bash käskude täitmiseks. Saate selle parandada, määrates ülesande kirjelduses selgesõnaliselt, millised sildid peavad käivitaval konveieri käivitajal olema:
dummy job on windows:
script:
- echo ok
tags:
- windowsSuurepärane! Torujuhe töötab praegu.
Tähelepanelik lugeja, olles korranud näidatud samme, märkab, et ülesanne sai etapis täidetud test, kuigi me ei täpsustanud etappi. Nagu arvata võis test on vaikesamm.
Jätkame konfiguratsiooniskeleti loomist, lisades kõik ülalkirjeldatud ülesanded:
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: deploySaime mitte eriti toimiva, kuid siiski õige torustiku.
Päästikute seadistamine
Tulenevalt asjaolust, et ühegi ülesande jaoks pole määratud päästikfiltreid, toimib konveier täielikult täidetakse iga kord, kui hoidlasse toimetatakse. Kuna see ei ole üldiselt soovitav käitumine, seadistame ülesannete jaoks päästikfiltrid.
Filtreid saab konfigureerida kahes vormingus: и . Lühidalt only/except võimaldab seadistada filtreid päästikute (merge_request, näiteks - määrab ülesande, mis täidetakse iga kord, kui luuakse tõmbepäring ja iga kord, kui commits saadetakse harule, mis on liitmistaotluses allikas) ja harude nimed (sh kasutades regulaaravaldisi); rules võimaldab kohandada tingimuste komplekti ja soovi korral muuta ülesande täitmise tingimust sõltuvalt eelmiste ülesannete õnnestumisest ().
Tuletagem meelde nõuete kogumit - kokkupanek ja testimine ainult liitmistaotluse jaoks, pakkimine ja saatmine Azure DevOpsile - liitmistaotluste ja tõugete jaoks ülemseadmele, dokumentatsiooni genereerimine - tõuke jaoks ülemseadmele.
Esmalt seadistame koodi koostamise ülesande, lisades reegli, mis käivitub ainult liitmistaotlusel:
build job:
# snip
only:
- merge_requestNüüd seadistame pakkimisülesande, mis käivitab liitmistaotluse ja lisab põhiseadmele kohustused:
pack and deploy job:
# snip
only:
- merge_request
- masterNagu näete, on kõik lihtne ja arusaadav.
Samuti saate ülesande käivitada ainult siis, kui ühendamistaotlus luuakse konkreetse sihtmärgi või lähteharuga:
rules:
- if: $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master"Tingimustel võite kasutada ; reeglid rules reeglitega kokkusobimatu only/except.
Artefaktide salvestamise seadistamine
Ülesande ajal build job meil on luua artefakte, mida saab järgmistes ülesannetes uuesti kasutada. Selleks peate võtmele lisama ülesande konfiguratsiooni teed, failid, mida mööda peate salvestama ja järgmistes ülesannetes uuesti kasutama :
build job:
# snip
artifacts:
paths:
- path/to/build/artifacts
- another/path
- MyCoolLib.*/bin/Release/*Teed toetavad metamärke, mis teeb nende määramise kindlasti lihtsamaks.
Kui ülesanne loob artefakte, pääseb iga järgmine ülesanne neile juurde – need asuvad hoidla juurega võrreldes samadel radadel, mis koguti algsest ülesandest. Artefaktid on saidilt allalaadimiseks saadaval ka.
Nüüd, kui meil on konfiguratsiooniraamistik valmis (ja testitud), saame jätkata ülesannete skriptide kirjutamisega.
Kirjutame stsenaariume
Võib-olla oli kunagi kauges galaktikas käsurealt projektide (sealhulgas .net-i) ehitamine piin. Nüüd saate projekti ehitada, testida ja avaldada kolmes meeskonnas:
dotnet build
dotnet test
dotnet packLoomulikult on mõned nüansid, mille tõttu teeme käsklused mõnevõrra keerulisemaks.
- Tahame väljalaske, mitte silumisjärgu, seega lisame igale käsule
-c Release - Testimisel tahame koguda koodi katvuse andmeid, seega peame testiteekidesse lisama katvuse analüsaatori:
- Lisage pakett kõikidesse testteekidesse
coverlet.msbuild:dotnet add package coverlet.msbuildprojekti kaustast - Lisage testkäivituskäsku
/p:CollectCoverage=true - Katvuse tulemuste saamiseks lisage testülesande konfiguratsiooni võti (vt allpool)
- Lisage pakett kõikidesse testteekidesse
- Koodi pakkimisel nuget-pakettidesse määrake pakettide väljundkataloog:
-o .
Koodi katvuse andmete kogumine
Pärast testide käivitamist käivitavad Coverleti prindid konsooli statistika:
Calculating coverage result...
Generating report 'C:Usersxxxsourcereposmy-projectmyProject.testscoverage.json'
+-------------+--------+--------+--------+
| Module | Line | Branch | Method |
+-------------+--------+--------+--------+
| project 1 | 83,24% | 66,66% | 92,1% |
+-------------+--------+--------+--------+
| project 2 | 87,5% | 50% | 100% |
+-------------+--------+--------+--------+
| project 3 | 100% | 83,33% | 100% |
+-------------+--------+--------+--------+
+---------+--------+--------+--------+
| | Line | Branch | Method |
+---------+--------+--------+--------+
| Total | 84,27% | 65,76% | 92,94% |
+---------+--------+--------+--------+
| Average | 90,24% | 66,66% | 97,36% |
+---------+--------+--------+--------+GitLab võimaldab statistika saamiseks määrata regulaaravaldise, mida saab seejärel märgi kujul hankida. Regulaaravaldis määratakse ülesande sätetes klahviga coverage; avaldis peab sisaldama püüdmisrühma, mille väärtus edastatakse märgile:
test and cover job:
# snip
coverage: /|s*Totals*|s*(d+[,.]d+%)/Siin saame statistikat liinilt, millel on kogu liini katvus.
Avalda paketid ja dokumentatsioon
Mõlemad toimingud on kavandatud torujuhtme viimasesse etappi – kuna kokkupanek ja katsetused on möödas, saame oma arendusi maailmaga jagada.
Esiteks kaaluge paketi allikas avaldamist:
Kui projektil pole nugeti konfiguratsioonifaili (
nuget.config), looge uus:dotnet new nugetconfigMilleks: pildil ei pruugi olla kirjutusõigust globaalsetele (kasutaja ja masina) konfiguratsioonidele. Et mitte vigu tabada, loome lihtsalt uue lokaalse konfiguratsiooni ja töötame sellega.
- Lisame kohalikule konfiguratsioonile uue paketi allika:
nuget sources add -name <name> -source <url> -username <organization> -password <gitlab variable> -configfile nuget.config -StorePasswordInClearTextname- kohaliku allika nimi, mitte kriitilineurl- allika URL etapist "Kontode ettevalmistamine", lk 6organization- organisatsiooni nimi Azure DevOpsisgitlab variable- GitLabi lisatud juurdepääsulubaga muutuja nimi ("Kontode ettevalmistamine", lk 11). Loomulikult vormingus$variableName-StorePasswordInClearText- häkkimine juurdepääsu keelamise veast möödahiilimiseks ()- Vigade korral võib olla kasulik lisada
-verbosity detailed
- Paketi saatmine allikale:
nuget push -source <name> -skipduplicate -apikey <key> *.nupkg- Saadame kõik pakid praegusest kataloogist, nii et
*.nupkg. name- ülaltoodud sammust.key- mis tahes rida. Azure DevOpsi aknas Connect to feed on näide alati ridaaz.-skipduplicate- kui proovite saata juba olemasolevat paketti ilma selle võtmeta, tagastab allikas veateate409 Conflict; võtmega jäetakse saatmine vahele.
- Saadame kõik pakid praegusest kataloogist, nii et
Nüüd paneme paika dokumentatsiooni loomise:
- Esiteks initsialiseerime hoidlas põhiharus docfx projekti. Selleks käivitage käsk juurtest
docfx initja interaktiivselt määrata ehitusdokumentatsiooni põhiparameetrid. Projekti minimaalse seadistuse üksikasjalik kirjeldus .- Seadistamisel on oluline määrata väljundkataloog
..public- GitLab võtab vaikimisi lehtede allikana hoidla juurtes oleva avaliku kausta sisu. Sest projekt asub hoidlas olevas kaustas – lisage väljund tee kõrgemale tasemele.
- Seadistamisel on oluline määrata väljundkataloog
- Lükkame muudatused GitLabi.
- Lisage konveieri konfiguratsioonile ülesanne
pages(reserveeritud sõna saidi avaldamise ülesannete jaoks GitLabi lehtedel):- Skript:
nuget install docfx.console -version 2.51.0- installige docfx; versioon on määratud tagamaks, et paketi installiteed on õiged..docfx.console.2.51.0toolsdocfx.exe .docfx_projectdocfx.json- dokumentatsiooni kogumine
- Sõlme artefaktid:
- Skript:
pages:
# snip
artifacts:
paths:
- publicLüüriline kõrvalepõige docfxi kohta
Varem määrasin projekti seadistamisel lahendusfailina dokumentatsiooni koodiallika. Peamine miinus on see, et dokumentatsiooni luuakse ka testprojektide jaoks. Kui see pole vajalik, saate selle väärtuse määrata sõlmele metadata.src:
{
"metadata": [
{
"src": [
{
"src": "../",
"files": [
"**/*.csproj"
],
"exclude":[
"*.tests*/**"
]
}
],
// --- snip ---
},
// --- snip ---
],
// --- snip ---
}metadata.src.src: "../"- liigume asukoha suhtes ühe taseme võrra kõrgemaledocfx.json, sest mustrites ei tööta kataloogipuust otsimine.metadata.src.files: ["**/*.csproj"]- globaalne muster, kogume kõik C # projektid kõigist kataloogidest.metadata.src.exclude: ["*.tests*/**"]- globaalne muster, välistage kõik kaustadest koos.testsPealkirjas
Vahesumma
Sellise lihtsa konfiguratsiooni saab luua vaid poole tunni ja paari tassi kohviga, mis võimaldab kontrollida, kas kood on üles ehitatud ja testid läbitud, ehitada uue paketi, uuendada dokumentatsiooni ja rõõmustada silma kauniga. märgid projekti README-s iga liitmistaotluse ja kaptenile saatmisega.
Lõplik .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:
- masterRääkides märkidest
Nende pärast sai ju kõik käima lükatud!
Konveieri olekute ja koodi katvuse märgid on saadaval GitLabis CI/CD seadetes Gtntral torujuhtmete plokis:

Lõin platvormi dokumentatsiooni lingiga märgi - seal on kõik üsna lihtne, saate luua oma märgi ja selle päringu abil vastu võtta.

Azure DevOps Artifacts võimaldab teil luua ka uusima versiooniga pakettide jaoks märke. Selleks peate Azure DevOpsi saidi allikas klõpsama valitud paketi jaoks nuppu Loo märk ja kopeerima allahindluse märgistuse:


Ilu lisamine
Tavaliste konfiguratsioonifragmentide esiletõstmine
Konfiguratsiooni kirjutades ja dokumentatsioonist otsides leidsin YAMLi huvitava funktsiooni – fragmentide taaskasutamise.
Nagu ülesande seadetest näha, vajavad need kõik silti windows käivitaja juures ja käivituvad, kui ühendamistaotlus saadetakse juhtseadmele/loodud (välja arvatud dokumentatsioon). Lisame selle fragmendile, mida taaskasutame:
.common_tags: &common_tags
tags:
- windows
.common_only: &common_only
only:
- merge_requests
- masterJa nüüd saame sisestada ülesande kirjelduses varem deklareeritud fragmendi:
build job:
<<: *common_tags
<<: *common_onlyFragmentide nimed peavad algama punktiga, et neid ei tõlgendataks ülesandena.
Paketi versioonide loomine
Paketi loomisel kontrollib kompilaator käsurea lüliteid, nende puudumisel projektifaile; kui see leiab versioonisõlme, võtab see selle väärtuseks ehitatava paketi versiooni. Selgub, et uue versiooniga paketi koostamiseks tuleb seda kas projekti failis uuendada või käsurea argumendina edasi anda.
Lisame veel ühe soovinimekirja – olgu versiooni kaks väiksemat numbrit paketi aasta ja valmimiskuupäev ning lisa väljalaskeeelsed versioonid. Loomulikult saab need andmed lisada projektifaili ja enne iga esitamist kontrollida – aga seda saab teha ka konveieri käigus, kogudes kontekstist paketiversiooni ja edastades selle käsurea argumendi kaudu.
Lepime kokku, et kui commit teade sisaldab rida like release (v./ver./version) <version number> (rev./revision <revision>)?, siis võtame sellelt realt paketi versiooni, täiendame seda praeguse kuupäevaga ja edastame selle argumendina käsule dotnet pack. Joone puudumisel me lihtsalt ei võta pakki järgi.
Järgmine skript lahendab selle probleemi:
# регулярное выражение для поиска строки с версией
$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=$versionSkripti lisamine ülesandele pack and deploy job ja jälgige pakkide kokkupanemist rangelt kinnistamissõnumis antud stringi olemasolul.
Kogusummas
Pärast umbes poole tunni või tunni kulutamist konfiguratsiooni kirjutamisele, kohalikus powershellis silumisele ja võib-olla ka paarile ebaõnnestunud käivitamisele saime rutiinsete toimingute automatiseerimiseks lihtsa konfiguratsiooni.
Muidugi on GitLab CI / CD palju ulatuslikum ja mitmetahulisem, kui pärast selle juhendi lugemist võib tunduda - . Isegi seal lubades
automaatselt tuvastada, koostada, testida, juurutada ja jälgida teie rakendusi
Nüüd on plaanis konfigureerida konveier rakenduste juurutamiseks Azure'i, kasutades Pulumit ja määrates automaatselt sihtkeskkonna, mida käsitletakse järgmises artiklis.
Allikas: www.habr.com








