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

O come ottenere dei badge eleganti per il proprio progetto in una sola serata di coding senza stress

Probabilmente, ogni sviluppatore con almeno un progetto personale sente a un certo punto il bisogno di avere dei badge belli con gli stati, la copertura del codice, le versioni dei pacchetti in nuget... E questo bisogno mi ha portato a scrivere questo articolo. Durante la preparazione per la sua scrittura, ho realizzato questa bellezza in uno dei miei progetti:

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

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

Come ambiente di sviluppo, ho utilizzato VS Code con l'estensione GitLab Workflow (per la validazione del file di configurazione direttamente dall'ambiente di sviluppo).

Breve introduzione

CD è quando hai appena fatto push, e al cliente è già tutto andato in crash?

Cosa sono CI/CD e perché sono necessari — si può facilmente cercare su Google. Trovare la documentazione completa per la configurazione dei pipeline in GitLab non è difficile neanche. anche non complicatoQui descrivo brevemente, e per quanto possibile senza errori, il funzionamento del sistema dall'alto:

  • lo sviluppatore invia un commit nel repository e crea una merge request tramite il sito, oppure avvia esplicitamente o implicitamente il pipeline in altro modo,
  • dalla configurazione vengono selezionati tutti i task le cui condizioni consentono di avviarli in questo contesto,
  • le attività sono organizzate in base alle loro fasi,
  • le fasi vengono eseguite a turno — cioè, in parallelo tutti i task di questa fase vengono eseguiti,
  • se una fase termina con un errore (cioè se almeno uno dei task della fase fallisce) — il pipeline si ferma (quasi sempre),
  • se tutte le fasi terminano con successo, il pipeline è considerato riuscito.

In questo modo, abbiamo:

  • un pipeline è un insieme di task organizzati in fasi, che possono essere utilizzati per assemblare, testare, impacchettare codice, distribuire la build finale su un servizio cloud, e altro ancora,
  • fase (stage) — un'unità di organizzazione del pipeline, contiene 1+ task,
  • task (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, il compito durante la configurazione del CI/CD consiste nel creare un insieme di attività che realizzino tutte le azioni necessarie per la costruzione, il test e la pubblicazione di codice e artefatti.

Prima di tutto: perché?

  • Perché GitLab?

Perché, quando si è presentata la necessità di creare repository privati per progetti personali, su GitHub erano a pagamento, ed io ero — parsimonioso. I repository sono diventati gratuiti, ma questo non è ancora un motivo sufficiente per trasferirmi su GitHub.

  • Perché non Azure DevOps Pipelines?

Perché là la configurazione è elementare — non servono neppure conoscenze della riga di comando. L'integrazione con fornitori git esterni avviene con un paio di clic, l'importazione delle chiavi SSH per inviare i commit nel repository avviene ugualmente, e il pipeline si configura facilmente anche senza un template.

Situazione attuale: cosa abbiamo e cosa desideriamo

Abbiamo:

  • un repository su GitLab.

Desideriamo:

  • una costruzione e un test automatici per ogni merge request,
  • la costruzione di pacchetti per ogni merge request e il push nel master a condizione che ci sia una certa stringa nel messaggio del commit,
  • l'invio dei pacchetti costruiti a un feed privato in Azure DevOps,
  • la creazione della documentazione e la pubblicazione su GitLab Pages,
  • badge!

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

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

Iniziamo!

Configuriamo la configurazione

Prepariamo gli account

  1. Creiamo un account in Microsoft Azure

  2. Andiamo su Azure DevOps

  3. Creiamo un nuovo progetto

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

  4. Facendo clic sul pulsante Crea, il progetto verrà creato e verrà effettuato il passaggio alla sua pagina. In questa pagina è possibile disattivare le funzionalità non necessarie accedendo alle impostazioni del progetto (collegamento in basso nella lista a sinistra -> Panoramica -> blocco Azure DevOps Services)
    Guida CI/CD in GitLab per (quasi) assoluti principianti

  5. Andiamo su Artifacts, clicchiamo su Crea feed

    1. Inseriamo il nome della fonte
    2. Selezioniamo la visibilità
    3. Deselezioniamo Include packages from common public sources, affinché la fonte non diventi un raccoglitore di cloni nuget
      Guida CI/CD in GitLab per (quasi) assoluti principianti

  6. Clicchiamo su Connetti al feed, selezioniamo Visual Studio, copiamo Source dal blocco Configurazione macchina
    Guida CI/CD in GitLab per (quasi) assoluti principianti

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

  8. Creiamo un nuovo token di accesso

    1. Nome — a scelta
    2. Organizzazione — attuale
    3. Durata — massimo 1 anno
    4. Ambito di applicazione (scope) — Packaging/Read & Write
      Guida 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 CI/CD in GitLab per (quasi) assoluti principianti

  11. Espandiamo il blocco Variabili, aggiungiamo una nuova

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

A questo punto la configurazione preliminare è completata.

Prepariamo la struttura della configurazione

Per impostazione predefinita, per configurare CI/CD in GitLab si utilizza il file .gitlab-ci.yml nella radice del repository. Puoi configurare un percorso arbitrario 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 descrive in dettaglio quali chiavi possono essere presenti a livello superiore della configurazione e in ciascuno dei livelli nidificati.

Innanzitutto, 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 nostra compilazione, ci servirà l'immagine con .Net Core 3.1, quindi possiamo tranquillamente aggiungere come prima riga nella configurazione

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

Ora, al momento dell'avvio della pipeline, l'immagine specificata verrà scaricata dal repository di immagini Microsoft, e tutte le attività della configurazione verranno eseguite in essa.

Il passo successivo è aggiungere stagefasi. Di default, GitLab definisce 5 fasi:

  • .pre — eseguita prima di tutte le fasi,
  • .post — eseguita dopo tutte le fasi,
  • build — la prima dopo .pre la fase,
  • test — la seconda fase,
  • deploy — la terza fase.

Non c'è nulla che impedisca di dichiararle esplicitamente. L'ordine in cui sono specificate le fasi influisce sull'ordine in cui vengono eseguite. A scopo di 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 verranno eseguiti prima di ogni attività, utilizzando before_script:

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

È necessario aggiungere almeno un'attività affinché il pipeline venga avviato al momento dell'invio dei commit. Aggiungiamo un'attività vuota per la dimostrazione:

job fittizio:
  script:
    - echo ok

Avviamo la validazione, otteniamo un messaggio che tutto va bene, effettuiamo il commit, eseguiamo il push e controlliamo i risultati sul sito... Ma otteniamo un errore dello script — bash: .PSVersion: comando non trovato. Che diavolo?

Tutto ha senso — per impostazione predefinita, i runner (responsabili dell'esecuzione degli script delle attività e forniti da GitLab) utilizzano bash per eseguire comandi. Possiamo risolvere questo problema specificando esplicitamente nella descrizione dell'attività quali tag devono avere i runner del pipeline in esecuzione:

job fittizio su Windows:
  script:
    - echo ok
  tags:
    - windows

Ottimo! Ora il pipeline viene eseguito.

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

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

job di costruzione:
  script:
    - echo "costruzione..."
  tags:
    - windows
  stage: costruzione

test e job di copertura:
  script:
    - echo "esecuzione dei test e analisi della copertura..."
  tags:
    - windows
  stage: test

pack e job di distribuzione:
  script:
    - echo "imballaggio e invio a nuget..."
  tags:
    - windows
  stage: distribuzione

pagine:
  script:
    - echo "creazione documenti..."
  tags:
    - windows
  stage: distribuzione

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

Impostazione dei trigger

Poiché nessuna delle attività ha filtri di attivazione specificati, il pipeline sarà completamente eseguito ad ogni invio di commit nel repository. Poiché questo non è un comportamento desiderato nella maggior parte dei casi, configureremo i filtri di attivazione per le attività.

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

Ricordiamo l'insieme dei requisiti: compilazione e test solo per merge request, imballaggio e invio a Azure DevOps per merge request e push nel master, generazione della documentazione per push nel master.

Iniziamo configurando il task di compilazione del codice, aggiungendo una regola di attivazione solo per le merge request:

build job:
  # snip
  only:
    - merge_request

Adesso configuriamo il task di imballaggio in modo da attivarsi per le merge request e l'aggiunta di commit nel master:

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

Come si può vedere, è tutto semplice e diretto.

È anche possibile configurare un task 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 è possibile utilizzare le variabili elencate qui; le regole rules non sono compatibili con le regole only/except.

Configurazione del salvataggio degli artefatti

Durante l'esecuzione del task build job verranno creati artefatti di compilazione che possono essere riutilizzati nei task successivi. A questo scopo, è necessario aggiungere nella configurazione del task i percorsi e i file da salvare e riutilizzare nei task successivi, sotto la chiave artifacts:

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

I percorsi supportano i wildcards, il che rende sicuramente più facile la loro definizione.

Se un'operazione genera artefatti, ogni operazione successiva potrà accedervi — si troveranno negli stessi percorsi rispetto alla radice del repository, da cui sono stati generati dall'operazione originale. Gli artefatti sono anche disponibili per il download sul sito.

Ora che abbiamo pronte (e verificate) le basi della configurazione, possiamo procedere alla scrittura degli script per le operazioni.

Scriviamo script

Forse, tanto tempo fa, in una galassia lontana, costruire progetti (anche su .net) dalla riga di comando era un vero problema. Oggi, tuttavia, è possibile costruire, testare e pubblicare un progetto con 3 comandi:

dotnet build
dotnet test
dotnet pack

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

  1. Desideriamo una build di rilascio, non una di debug, quindi aggiungiamo a ciascun comando -c Release
  2. Durante i test, vogliamo raccogliere dati sulla copertura del codice, quindi dovremo connettere l'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 team di avvio dei test /p:CollectCoverage=true
    3. Nella configurazione del job di test aggiungeremo una chiave per ottenere i risultati di copertura (vedi sotto)
  3. Durante l'imballaggio del codice nei pacchetti nuget, specificheremo la directory di uscita per i pacchetti: -o .

Raccogliamo i dati di copertura del codice

Coverlet fornisce nella console statistiche sull'esecuzione dopo il completamento dei test:

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

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

+---------+--------+--------+--------+
|         | Linea  | Branch | 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 possono poi essere visualizzate come un badge. L'espressione regolare viene fornita nelle impostazioni del job con la chiave coverage; l'espressione deve contenere un gruppo di cattura, il cui valore sarà passato al badge:

test and cover job:
  # snip
  coverage: /|s*Totals*|s*(d+[,.]d+%)/

Qui otteniamo le statistiche dalla riga con la copertura complessiva delle linee.

Pubblicazione di pacchetti e documentazione

Entrambe le azioni sono programmate per l'ultima fase del pipeline: una volta completata la build e i test, possiamo condividere i risultati con il mondo.

Iniziamo con la pubblicazione in una sorgente di pacchetti:

  1. Se il progetto non contiene il file di configurazione nuget (nuget.config), creiamo uno nuovo: 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 una nuova sorgente di pacchetti alla configurazione locale: nuget sources add -name -source -username -password -configfile nuget.config -StorePasswordInClearText
    1. name — nome locale della sorgente, non è fondamentale
    2. url — URL della sorgente dalla fase "Prepariamo gli account", p. 6
    3. organization — nome dell'organizzazione in Azure DevOps
    4. gitlab variable — nome della variabile con il token di accesso, aggiunta in GitLab ("Prepariamo gli account", p. 11). Naturalmente, nel formato $variableName
    5. -StorePasswordInClearText — hack per aggirare l'errore di accesso negato (non sono il primo a inciampare su questi problemi)
    6. In caso di errori, potrebbe essere utile aggiungere -verbosity detailed
  3. Inviamo il pacchetto alla fonte: nuget push -source -skipduplicate -apikey *.nupkg
    1. Stiamo inviando tutti i pacchetti dalla directory attuale, quindi *.nupkg.
    2. name — dal passo precedente.
    3. key — qualsiasi stringa. In Azure DevOps nella finestra Connetti all'alimentazione, viene sempre fornito come esempio la stringa az.
    4. -skipduplicate — tentando di inviare un pacchetto già esistente; senza questa chiave, la fonte restituirà un errore 409 Conflict; con la chiave, l'invio verrà ignorato.

Ora configuriamo la creazione della documentazione:

  1. Per iniziare, nel repository, sul branch master, inizializziamo il progetto docfx. Per fare ciò, dal root dobbiamo eseguire il comando docfx init e in modalità interattiva impostiamo i parametri chiave per la compilazione della documentazione. Una descrizione dettagliata della configurazione minima del progetto qui.
    1. Durante la configurazione è importante specificare la directory di uscita ..public — GitLab raccoglie di default il contenuto della cartella public nella root del repository come fonte per le Pages. Poiché il progetto si troverà in una cartella annidata nel repository, aggiungiamo nel percorso una risalita di livello.
  2. Invieremo le modifiche a GitLab.
  3. Nella configurazione del pipeline aggiungeremo il task pages (parola riservata per i task di pubblicazione di siti in GitLab Pages):
    1. Script:
      1. nuget install docfx.console -version 2.51.0 — installerà docfx; la versione è specificata per garantire la correttezza dei percorsi di installazione del pacchetto.
      2. .docfx.console.2.51.0toolsdocfx.exe .docfx_projectdocfx.json — generiamo la documentazione
    2. Nodo artifacts:

pages:
  # snip
  artifacts:
    paths:
      - public

Una digressione lirica su docfx

In passato, quando configuravo il progetto, specificavo la fonte del codice per la documentazione come file di soluzione. Il principale svantaggio è che la documentazione viene creata anche per progetti di test. Se non è necessario, è possibile impostare questo valore sul nodo metadata.src:

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

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

Risultato intermedio

Questa semplice configurazione può essere creata in appena mezz'ora e con qualche tazza di caffè. Permette di controllare ad ogni richiesta di fusione che il codice si compila e che i test passano, raccogliere un nuovo pacchetto, aggiornare la documentazione e abbellire il progetto con bei badge nel README.

Il file .gitlab-ci.yml finale

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

A proposito dei badge

È tutto iniziato per loro!

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

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

Il badge con il link alla documentazione l'ho creato sulla piattaforma Shields.io — lì tutto è abbastanza semplice, puoi creare il tuo badge e ottenerlo tramite richiesta.

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

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

Azure DevOps Artifacts consente anche di creare badge per i pacchetti specificando la versione attuale. Per questo, nella sorgente sul sito di Azure DevOps, è necessario fare clic su Crea badge per il pacchetto selezionato e copiare il markup markdown:

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

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

Aggiungiamo un tocco di stile

Evidenziamo i frammenti comuni della configurazione

Durante la scrittura della configurazione e la ricerca nella documentazione, mi sono imbattuto in una funzione interessante di YAML: il riutilizzo dei frammenti.

Come si può vedere dalle impostazioni dei task, tutti richiedono un tag windows per il runner e scattano all'invio su master/creazione di una richiesta di fusione (a parte la documentazione). Aggiungiamo questo al frammento che riutilizzeremo:

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

E ora nella descrizione del task possiamo inserire il frammento precedentemente dichiarato:

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

I nomi dei frammenti devono iniziare con un punto per non essere interpretati come un'istruzione.

Versionamento dei pacchetti

Durante la creazione di un pacchetto, il compilatore verifica 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 in fase di compilazione. Quindi, per compilare un pacchetto con una nuova versione, è necessario aggiornare il valore nel file di progetto o passarlo come argomento nella riga di comando.

Aggiungiamo un'ulteriore richiesta: i due ultimi numeri della versione saranno l'anno e la data di compilazione del pacchetto, e aggiungiamo anche versioni pre-release. È possibile inserire questi dati nel file di progetto e verificarli prima di ogni invio, ma possiamo anche gestirli nel pipeline, costruendo la versione del pacchetto in base al contesto e passando i dati tramite un argomento nella riga di comando.

Conveniamo che se nel messaggio di commit è presente una stringa del tipo release (v./ver./version) <version number> (rev./revision <revision>)?, prenderemo la versione del pacchetto da questa stringa, la completeremo con la data attuale e la passeremo come argomento al comando dotnet pack. In assenza della stringa, non compileremo 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 compito di pack e deploy e osserviamo la costruzione dei pacchetti solo in presenza della stringa specificata nel messaggio di commit.

Totale

Dopo aver speso circa mezz'ora a un'ora per scrivere la configurazione, fare debug nel powershell locale e, probabilmente, alcuni avvii errati, abbiamo ottenuto una configurazione semplice per automatizzare compiti ripetitivi.

Certo, GitLab CI/CD è molto più vasto e complesso di quanto possa sembrare dopo aver letto questa guida — non è affatto così. Ci sono anche Auto DevOps, che consente di

rilevare automaticamente, costruire, testare, distribuire e monitorare le tue applicazioni

Ora nei nostri piani c'è configurare un pipeline per il deployment delle applicazioni su Azure, utilizzando Pulumi e con rilevamento automatico dell'ambiente target, cosa che verrà trattata 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