Guida a CI/CD in GitLab per (quasi) assoluti principianti

O come ottenere badge bellissimi per il tuo progetto in una sola serata di programmazione senza stress

Probabilmente ogni sviluppatore, che ha almeno un progetto personale, in un certo momento prova il desiderio di avere badge eleganti con stati, copertura del codice, versioni dei pacchetti in nuget... E questa voglia mi ha portato a scrivere questo articolo. Nel processo di preparazione alla sua stesura ho ottenuto questa bellezza in uno dei miei progetti:

Guida a CI/CD in GitLab per (quasi) assoluti principianti

L'articolo esaminerà la configurazione di base dell'integrazione continua e della distribuzione per un progetto di libreria classi su .Net Core in GitLab, con la pubblicazione della documentazione in GitLab Pages e l'invio dei pacchetti compilati a un feed privato in Azure DevOps.

Come ambiente di sviluppo è stato utilizzato VS Code con l'estensione GitLab Workflow (per la convalida del file di configurazione direttamente dall'ambiente di sviluppo).

Breve introduzione

CD è quando hai appena fatto un push e il cliente ha già tutto giù?

Cos'è CI/CD e perché è necessario - si può facilmente cercare online. Trovare una documentazione completa sulla configurazione dei pipeline in GitLab non è difficile. Qui descriverò brevemente e per quanto possibile senza errori il processo di lavoro del sistema dall'alto:

  • lo sviluppatore invia un commit nel repository, crea una merge request tramite il sito web, o avvia esplicitamente o implicitamente il pipeline in altro modo,
  • dalla configurazione vengono selezionate tutte le attività le cui condizioni consentono di avviarle in questo contesto,
  • le attività sono organizzate in base ai loro passaggi,
  • i passaggi vengono eseguiti uno dopo l'altro - cioè. in parallelo tutte le attività di questo passaggio vengono eseguite,
  • se il passaggio termina con un errore (cioè se almeno una delle attività del passaggio termina con un errore) - il pipeline si ferma (quasi sempre),
  • se tutti i passaggi sono stati completati con successo, il pipeline viene considerato completato con successo.

In questo modo, abbiamo:

  • un pipeline è un insieme di attività organizzate in passaggi, in cui è possibile compilare, testare, pacchettizzare il codice, distribuire la build pronta in un servizio cloud, ecc.,
  • un passaggio (stage) è un'unità di organizzazione del pipeline, contiene 1+ attività,
  • un'attività (job) è un'unità di lavoro nel pipeline. Consiste in uno script (obbligatorio), condizioni di avvio, impostazioni di pubblicazione/cache degli artefatti e molto altro.

Pertanto, l'obiettivo nella configurazione di CI/CD è quello di creare un insieme di attività che realizzino tutte le azioni necessarie per la build, il testing e la pubblicazione del codice e degli artefatti.

Prima di iniziare: perché?

  • Perché GitLab?

Perché quando è emersa la necessità di creare repository privati per progetti personali, su GitHub erano a pagamento, e io sono avaro. I repository sono diventati gratuiti, ma questo non è ancora un motivo sufficiente per migrare su GitHub.

  • Perché non Azure DevOps Pipelines?

Perché lì la configurazione è elementare — non sono nemmeno necessarie conoscenze della riga di comando. L'integrazione con fornitori esterni di git è questione di un paio di clic, l'importazione delle chiavi SSH per inviare commit al repository è altrettanto semplice, e la pipeline si configura facilmente anche senza un template.

Posizione di partenza: cosa abbiamo e cosa desideriamo

Abbiamo:

  • un repository in GitLab.

Desideriamo:

  • una build automatica e un testing per ogni merge request,
  • la build di pacchetti per ogni merge request e il push in master a condizione che nel messaggio del commit sia presente una certa stringa,
  • l'invio dei pacchetti assemblati in un feed privato in Azure DevOps,
  • la build della documentazione e la pubblicazione in GitLab Pages,
  • badge!11

I requisiti descritti si adattano perfettamente al seguente modello di pipeline:

  • Fase 1 — build
    • Costruiamo il codice, pubblichiamo i file di output come artefatti
  • Fase 2 — testing
    • Otteniamo gli artefatti dalla fase di build, eseguiamo i test, raccogliamo i dati di copertura del codice
  • Fase 3 — invio
    • Attività 1 — costruiamo un pacchetto nuget e lo inviamo in Azure DevOps
    • Attività 2 — costruiamo il sito da xmldoc nel codice sorgente e pubblichiamo in GitLab Pages

Iniziamo!

Configuriamo

Prepariamo gli account

  1. Creiamo un account in Microsoft Azure

  2. Passiamo a Azure DevOps

  3. Creiamo un nuovo progetto

    1. Nome — qualsiasi
    2. Visibilità — qualsiasi
      Guida a CI/CD in GitLab per (quasi) assoluti principianti

  4. Premendo il pulsante Crea, il progetto verrà creato e si passerà alla sua pagina. In questa pagina è possibile disabilitare funzionalità non necessarie passando alle impostazioni del progetto (link in fondo a sinistra -> Panoramica -> blocco Azure DevOps Services)
    Guida a CI/CD in GitLab per (quasi) assoluti principianti

  5. Passiamo a Atrifacts, clicchiamo su Crea feed

    1. Inseriamo il nome della fonte
    2. Scegliamo la visibilità
    3. Deselezioniamo l'opzione Include packages from common public sources, per evitare che la fonte diventi un accumulo di cloni nuget
      Guida a CI/CD in GitLab per (quasi) assoluti principianti

  6. Clicchiamo su Connetti al feed, scegliamo Visual Studio, dal blocco Impostazione macchina copiamo la fonte
    Guida a CI/CD in GitLab per (quasi) assoluti principianti

  7. Andiamo nelle impostazioni dell'account, scegliamo Token di accesso personale
    Guida a CI/CD in GitLab per (quasi) assoluti principianti

  8. Creiamo un nuovo token di accesso

    1. Nome — a piacere
    2. Organizzazione — attuale
    3. La durata è massima di 1 anno
    4. Ambito di applicazione (scope) — Packaging/Read & Write
      Guida a CI/CD in GitLab per (quasi) assoluti principianti

  9. Copiamo il token creato — dopo la chiusura della finestra modale, il valore non sarà più disponibile

  10. Accediamo alle impostazioni del repository in GitLab, selezioniamo le impostazioni CI/CD
    Guida a CI/CD in GitLab per (quasi) assoluti principianti

  11. Espandiamo il blocco Variabili, aggiungiamo un nuovo elemento

    1. Nome — qualsiasi senza spazi (sarà disponibile nella shell dei comandi)
    2. Valore — token di accesso al punto 9
    3. Selezioniamo Maschera variabile
      Guida a CI/CD in GitLab per (quasi) assoluti principianti

Con questo abbiamo completato la configurazione preliminare.

Prepariamo la struttura di configurazione

Di default, per configurare CI/CD in GitLab si utilizza il file .gitlab-ci.yml nella radice del repository. È possibile configurare un percorso personalizzato per questo file nelle impostazioni del repository, ma in questo caso non è necessario.

Come si può vedere dall'estensione, il file contiene una configurazione nel formato YAML. La documentazione spiega in dettaglio quali chiavi possono essere presenti a livello superiore della configurazione e in ciascun livello annidato.

Per prima cosa, aggiungiamo al file di configurazione un collegamento all'immagine Docker, in cui verranno eseguite le attività. A tal fine, troviamo la pagina delle immagini .Net Core su Docker Hub. In GitHub c'è una guida dettagliata su quale immagine scegliere per diverse attività. Per la compilazione, ci servirà l'immagine con .Net Core 3.1, quindi possiamo aggiungerla come prima riga nella configurazione

image: mcr.microsoft.com/dotnet/core/sdk:3.1

Ora, quando avvii il pipeline dal repository, verrà scaricata l'immagine specificata da Microsoft e tutte le attività dalla configurazione verranno eseguite lì.

Il passaggio successivo è aggiungere stagestadi. Di default, GitLab definisce 5 stadi:

  • .pre — viene eseguito prima di tutti gli stadi,
  • .post — viene eseguito dopo tutti gli stadi,
  • build — primo dopo .pre stagione,
  • test — secondo stadio,
  • deploy — terzo stadio.

Non c'è nulla che impedisca di dichiararli esplicitamente, tuttavia. L'ordine in cui sono elencati gli stadi influisce sull'ordine in cui vengono eseguiti. Per completezza, aggiungiamo alla configurazione:

stages:
  - build
  - test
  - deploy

Per il debug, ha senso ottenere informazioni sull'ambiente in cui vengono eseguite le attività. Aggiungiamo un insieme globale di comandi che verrà eseguito prima di ogni attività, utilizzando before_script:

before_script:
  - $PSVersionTable.PSVersion
  - dotnet --version
  - nuget help | select-string Version

Rimane da aggiungere almeno un'attività, in modo che il pipeline si avvii all'invio di commit. Per ora, aggiungiamo un'attività vuota per dimostrazione:

dummy job:
  script:
    - echo ok

Avviamo la validazione, riceviamo un messaggio che va tutto bene, facciamo il commit, eseguiamo il push, controlliamo i risultati sul sito… E riceviamo un errore di script — bash: .PSVersion: comando non trovato. WTF?

Tutto ha senso — di default i runner (che si occupano dell'esecuzione degli script delle attività e forniti da GitLab) utilizzano bash per eseguire i comandi. Possiamo risolvere la cosa specificando esplicitamente nella descrizione dell'attività quali tag devono essere presenti nel runner del pipeline esecutore:

dummy job on windows:
  script:
    - echo ok
  tags:
    - windows

Ottimo! Ora il pipeline viene eseguito.

Il lettore attento, ripetendo i passaggi indicati, noterà che l'attività è stata eseguita nella fase test, anche se non abbiamo specificato la fase. Come si può intuire, test è la fase predefinita.

Continuiamo a creare lo scheletro di configurazione, aggiungendo tutte le attività descritte sopra:

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

Abbiamo ottenuto un pipeline non particolarmente funzionale, ma comunque corretto.

Impostazione dei trigger

Poiché per nessuna delle attività sono stati specificati filtri di attivazione, il pipeline sarà completamente eseguito ad ogni invio di commit nel repository. Poiché questo non è desiderabile in generale, configureremo i filtri di attivazione per le attività.

I filtri possono essere configurati in due formati: only/except e rules. In breve, only/except consente di configurare filtri basati sui trigger (merge_request, ad esempio — configura l'attività per essere eseguita ad ogni creazione di richiesta di merge e ad ogni invio di commit nel ramo che è la fonte della richiesta di merge) e sui nomi dei rami (incluso l'uso di espressioni regolari); rules consente di configurare un insieme di condizioni e, facoltativamente, modificare la condizione di esecuzione dell'attività in base al successo delle attività precedenti (when in GitLab CI/CD).

Ricordiamo l'insieme di requisiti — build e test solo per le merge request, imballaggio e invio in Azure DevOps — per merge request e push nel master, generazione della documentazione — per push nel master.

Per iniziare, configuriamo l'attività di build del codice, aggiungendo una regola di attivazione solo per le merge request:

build job:
  # snip
  only:
    - merge_request

Ora configuriamo il lavoro di imballaggio per attivarsi su merge request e l'aggiunta di commit nel master:

pack and deploy job:
  # snip
  only:
    - merge_request
    - master

Come puoi vedere, è tutto semplice e diretto.

È possibile configurare il lavoro per attivarsi solo se viene creata una merge request con un ramo target o source specifico:

  rules:
    - if: $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master"

Nelle condizioni puoi utilizzare le variabili elencate qui; le regole rules non sono compatibili con le regole only/except.

Configurazione per il salvataggio degli artefatti

Durante l'esecuzione del lavoro build job verranno creati artefatti di build che possono essere riutilizzati nei lavori successivi. Per questo è necessario aggiungere nella configurazione del lavoro i percorsi, i file che devono essere salvati e riutilizzati nei lavori successivi, nella chiave artifacts:

build job:
  # snip
  artifacts:
    paths:
      - path/to/build/artifacts
      - another/path
      - MyCoolLib.*/bin/Release/*

I percorsi supportano i caratteri jolly, il che semplifica sicuramente la loro definizione.

Se il lavoro crea artefatti, ogni lavoro successivo potrà accedervi — saranno posizionati negli stessi percorsi relativi alla radice del repository, da cui sono stati creati dal lavoro originale. Gli artefatti sono anche disponibili per il download sul sito.

Ora che abbiamo pronto (e verificato) lo scheletro della configurazione, possiamo passare alla scrittura degli script per i lavori.

Scriviamo gli script

Forse, molto tempo fa, in una galassia lontana lontana, compilare progetti (compresi quelli .net) dalla riga di comando era un problema. Ora, invece, compilare, testare e pubblicare un progetto può essere fatto in 3 comandi:

dotnet build
dotnet test
dotnet pack

Naturalmente, ci sono alcune sfide che complicano un po' i comandi.

  1. Vogliamo una build di rilascio, non una di debug, quindi a ogni comando aggiungiamo -c Release
  2. Durante i test vogliamo raccogliere dati sulla copertura del codice, quindi sarà necessario integrare un analizzatore di copertura nelle librerie di test:
    1. In tutte le librerie di test è necessario aggiungere il pacchetto coverlet.msbuild: dotnet add package coverlet.msbuild dalla cartella del progetto
    2. Aggiungeremo al comando di esecuzione dei test /p:CollectCoverage=true
    3. Nella configurazione del lavoro di test aggiungeremo una chiave per ottenere i risultati della copertura (vedi sotto)
  3. Quando impacchettiamo il codice in pacchetti nuget, specificheremo la directory di uscita per i pacchetti: -o .

Raccogliamo i dati sulla copertura del codice

Coverlet, dopo l'esecuzione dei test, mostra nella console le statistiche dell'esecuzione:

Calcolo dei risultati di copertura...
  Generazione del rapporto 'C:Usersxxxsourcereposmy-projectmyProject.testscoverage.json'

+-------------+--------+--------+--------+
| Modulo      | Linea  | Ramo   | Metodo |
+-------------+--------+--------+--------+
| progetto 1  | 83,24% | 66,66% | 92,1%  |
+-------------+--------+--------+--------+
| progetto 2  | 87,5%  | 50%    | 100%   |
+-------------+--------+--------+--------+
| progetto 3  | 100%   | 83,33% | 100%   |
+-------------+--------+--------+--------+

+---------+--------+--------+--------+
|         | Linea  | Ramo   | Metodo |
+---------+--------+--------+--------+
| Totale  | 84,27% | 65,76% | 92,94% |
+---------+--------+--------+--------+
| Media   | 90,24% | 66,66% | 97,36% |
+---------+--------+--------+--------+

GitLab consente di specificare un'espressione regolare per ottenere statistiche, che poi possono essere visualizzate come un badge. L'espressione regolare viene specificata nelle impostazioni del task con la chiave copertura; nell'espressione deve essere presente un gruppo di cattura, il cui valore verrà passato al badge:

job di test e copertura:
  # snip
  copertura: \/|s*Totali*|s*(d+[,.]d+%)\/

Qui otteniamo statistiche dalla stringa con la copertura totale per le righe.

Pubblicazione di pacchetti e documentazione

Entrambe le azioni sono pianificate per l'ultima fase del pipeline: dato che la build e i test sono stati completati, possiamo condividere le nostre scoperte con il mondo.

Iniziamo a considerare la pubblicazione in un repository di pacchetti:

  1. Se nel progetto non è presente un file di configurazione nuget (nuget.config), creiamo un nuovo file: dotnet new nugetconfig

    Perché: nell'immagine potrebbe essere vietato l'accesso in scrittura alle configurazioni globali (utente e macchina). Per evitare errori, creiamo semplicemente una nuova configurazione locale e lavoriamo con essa.

  2. Aggiungiamo un nuovo repository di pacchetti alla configurazione locale: nuget sources add -name -source -username -password -configfile nuget.config -StorePasswordInClearText
    1. name — nome locale del repository, non è decisivo
    2. url — URL del repository dalla fase "Preparazione degli account", punto 6
    3. organization — nome dell'organizzazione in Azure DevOps
    4. gitlab variable — nome della variabile con il token di accesso, aggiunta in GitLab ("Preparazione degli account", punto 11). Naturalmente, nel formato $variableName
    5. -StorePasswordInClearText — hack per aggirare l'errore di accesso negato (non sono il primo a inciampare in questo problema)
    6. In caso di errori, potrebbe essere utile aggiungere -verbosity detailed
  3. Inviare il pacchetto al repository: nuget push -source -skipduplicate -apikey *.nupkg
    1. Invia tutti i pacchetti dalla directory corrente, quindi *.nupkg.
    2. name — dal passaggio precedente.
    3. key — qualsiasi stringa. In Azure DevOps, nella finestra Connect to feed, viene sempre fornita come esempio la stringa az.
    4. -skipduplicate — durante il tentativo di inviare un pacchetto già esistente senza questa chiave, la fonte restituirà un errore 409 Conflitto; con la chiave l'invio sarà saltato.

Ora configuriamo la creazione della documentazione:

  1. Innanzitutto, nel repository, nel ramo master, inizializziamo il progetto docfx. Per fare ciò, dalla radice dobbiamo eseguire il comando docfx init e in modalità interattiva indichiamo i parametri chiave per la build della documentazione. Una descrizione dettagliata della configurazione minima del progetto qui.
    1. È importante specificare la directory di output ..public — GitLab per impostazione predefinita prende il contenuto della cartella public nella radice del repository come fonte per le Pages. Poiché il progetto si trova in una cartella all'interno del repository, aggiungiamo nel percorso l'uscita a un livello superiore.
  2. Invieremo le modifiche in GitLab.
  3. Nella configurazione del pipeline aggiungeremo il compito pages (parola riservata per i compiti di pubblicazione dei siti in GitLab Pages):
    1. Script:
      1. nuget install docfx.console -version 2.51.0 — installerà docfx; la versione è indicata per garantire la correttezza dei percorsi di installazione del pacchetto.
      2. .docfx.console.2.51.0toolsdocfx.exe .docfx_projectdocfx.json — compiliamo la documentazione
    2. Nodo artifacts:

pages:
  # snip
  artifacts:
    paths:
      - public

Riflessione lirica su docfx

In precedenza, durante la configurazione del progetto, indicavo la fonte del codice per la documentazione come file della soluzione. Il principale svantaggio è che la documentazione viene creata anche per i progetti di test. Nel caso in cui ciò non sia necessario, è possibile specificare un valore per il nodo metadata.src:

{
  "metadata": [
    {
      "src": [
        {
          "src": "..\/",
          "files": [
            "**/*.csproj"
          ],
          "exclude":[
            "*.tests*\/**"
          ]
        }
      ],
      \/\/ --- snip ---
    },
    \/\/ --- snip ---
  ],
  \/\/ --- snip ---
}

  1. metadata.src.src: "..\/" — usciamo a un livello superiore rispetto alla posizione docfx.json, poiché nei pattern non funziona la ricerca a ritroso nell'albero delle directory.
  2. metadata.src.files: ["**/*.csproj"] — pattern globale, raccogliamo tutti i progetti C# da tutte le directory.
  3. metadata.src.exclude: ["*.tests*\/**"] — pattern globale, escludiamo tutto dalle cartelle con .tests nel nome

Risultato intermedio

Una configurazione così semplice può essere creata letteralmente in mezz'ora e un paio di tazze di caffè, che permetterà ad ogni richiesta di unione e invio al master di verificare che il codice si compili e i test passino, compili un nuovo pacchetto, aggiorni la documentazione e soddisfi la vista con bei badge nel README del progetto.

File finale .gitlab-ci.yml

immagine: 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

A proposito dei badge

È per loro che tutto è stato progettato!

I badge con gli stati della pipeline e la copertura del codice sono disponibili in GitLab nelle impostazioni CI/CD nel blocco Gtntral pipelines:

Guida a CI/CD in GitLab per (quasi) assoluti principianti

Ho creato il badge con il link alla documentazione sulla piattaforma Shields.io — lì è tutto piuttosto diretto, puoi creare il tuo badge e ottenerlo tramite richiesta.

![Esempio con Shields.io](https://img.shields.io/badge/custom-badge-blue)

Guida a CI/CD in GitLab per (quasi) assoluti principianti

Azure DevOps Artifacts consente anche di creare badge per i pacchetti indicando la versione attuale. Per fare ciò, nel sito di Azure DevOps, è necessario fare clic su Crea badge per il pacchetto selezionato e copiare la sintassi markdown:

Guida a CI/CD in GitLab per (quasi) assoluti principianti

Guida a CI/CD in GitLab per (quasi) assoluti principianti

Aggiungiamo un po' di bellezza

Evidenziamo i frammenti comuni di configurazione

Durante la scrittura della configurazione e la ricerca nella documentazione, ho trovato un'interessante funzionalità di YAML: il riutilizzo dei frammenti.

Come si può vedere dalle impostazioni delle attività, tutte richiedono un tag windows sul runner, e si attivano quando viene effettuato un invio nel master/creazione di una pull request (eccetto per la documentazione). Aggiungiamo ciò nel frammento che riutilizzeremo:

.common_tags: &common_tags
  tags:
    - windows
.common_only: &common_only
  only:
    - merge_requests
    - master

E ora nella descrizione dell'attività possiamo inserire il frammento dichiarato in precedenza:

build job:
  <<: *common_tags
  <<: *common_only

I nomi dei frammenti devono iniziare con un punto per non essere interpretati come attività.

Versioning dei pacchetti

Quando si crea un pacchetto, il compilatore controlla le chiavi della riga di comando e, in loro assenza, i file di progetto; trovando il nodo Version, ne prende il valore come versione del pacchetto generato. Pertanto, per costruire un pacchetto con una nuova versione, è necessario aggiornare quest'ultima nel file di progetto o passarla come argomento della riga di comando.

Aggiungiamo un'altra richiesta: i due numeri inferiori nella versione devono rappresentare l'anno e la data di costruzione del pacchetto, e dobbiamo aggiungere le versioni di pre-rilascio. È sicuramente possibile aggiungere questi dati al file del progetto e verificarli prima di ogni invio, ma ciò può essere fatto anche nel pipeline, costruendo la versione del pacchetto dal contesto e passando come argomento della riga di comando.

Conveniamo che se nel messaggio del commit c'è una riga del tipo release (v.\/ver.\/version) <numero della versione> (rev.\/revision <revision>)?, estrarremo da questa riga la versione del pacchetto, la completeremo con la data corrente e la passeremo come argomento al comando dotnet pack. In assenza della riga, semplicemente non costruiremo il pacchetto.

Questo compito è risolto dal seguente script:

# регулярное выражение для поиска строки с версией
$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

Aggiungiamo lo script al compito pack and deploy job e osserviamo la costruzione dei pacchetti solo in presenza della riga richiesta nel messaggio del commit.

Totale

Dopo aver speso circa mezz'ora-ora per scrivere la configurazione, fare debugging in powershell locale e, forse, qualche esecuzione non riuscita, abbiamo ottenuto una configurazione semplice per automatizzare le attività quotidiane.

Certo, GitLab CI\/CD è molto più ampio e complesso di quanto possa sembrare dopo aver letto questa guida — non è affatto così. Lì c'è anche Auto DevOps, che permette di

detect, build, test, deploy e monitorare automaticamente le tue applicazioni.

Ora nei piani c'è di configurare un pipeline per la distribuzione delle applicazioni in Azure, utilizzando Pulumi e la determinazione automatica dell'ambiente target, un argomento che sarà trattato nel prossimo articolo.

Fonte: habr.com

Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server 🔥 Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server | ProHoster