Files
Data-Coupler/VERSIONING_SYSTEM.md
T
Alessio Dal Santo ae16f99776
Build and Push Docker Images / Build Linux Container (push) Successful in 6m54s
Build and Push Docker Images / Build Windows Container (push) Has been cancelled
Build and Push Docker Images / Create Multi-Platform Manifest (push) Has been cancelled
feat: Implementato sistema di versioning automatizzato con MinVer e Gitea Actions
- Aggiunto MinVer per calcolo automatico versione da git tags
- Creato modello VersionInfo e servizio VersionService
- Integrato display versione nel NavMenu (Data_Coupler v2.1.0)
- Aggiornato workflow Gitea Actions (Linux e Windows) per generare version.json
- Risolto problema inconsistenza versioning tra container Linux e Windows
- Documentazione completa: VERSIONING_SYSTEM.md e MINVER_SETUP.md
- Versione ora calcolata automaticamente da git tags (Semantic Versioning)
2026-02-02 12:00:05 +01:00

17 KiB

Sistema di Versioning Automatizzato

Panoramica

Data-Coupler implementa un sistema di versioning automatizzato che integra le Gitea Actions con l'applicazione Blazor per mostrare dinamicamente la versione corrente nel NavMenu.

Architettura del Sistema

Componenti

  1. version.json: File JSON generato automaticamente durante il build
  2. VersionInfo.cs: Modello dati per le informazioni di versione
  3. VersionService.cs: Servizio per leggere e gestire le informazioni di versione
  4. NavMenu.razor: UI che mostra la versione corrente

Flusso di Versioning

graph LR
    A[Git Push] --> B[Gitea Actions]
    B --> C[Generate version.json]
    C --> D[Docker Build]
    D --> E[Deploy]
    E --> F[VersionService carica version.json]
    F --> G[NavMenu mostra versione]

Gitea Actions Workflow

Generazione version.json - Linux

Durante il build Linux, il workflow legge dinamicamente la versione dal .csproj:

# Extract version from Data_Coupler.csproj or use default
VERSION=$(grep '<Version>' Data_Coupler/Data_Coupler.csproj | sed 's/.*<Version>\(.*\)<\/Version>.*/\1/' || echo "2.1.0")

# If version tag not found, use default
if [ -z "$VERSION" ]; then
  VERSION="2.1.0"
fi

# Create version.json
cat > Data_Coupler/wwwroot/version.json <<EOF
{
  "version": "${VERSION}",
  "commitSha": "${GITHUB_SHA:0:7}",
  "branch": "${GITHUB_REF_NAME}",
  "buildDate": "$(date -u +"%Y-%m-%d %H:%M:%S UTC")",
  "buildEnvironment": "Gitea Actions"
}
EOF

Logica:

  1. Usa grep per cercare tag <Version> nel .csproj
  2. Estrae il valore con sed
  3. Se non trova nulla, usa fallback "2.1.0"
  4. Genera version.json con tutti i metadati

Generazione version.json - Windows

Durante il build Windows, il workflow legge dinamicamente la versione dal .csproj usando PowerShell:

# Extract version from Data_Coupler.csproj or use default
$csprojPath = "Data_Coupler\Data_Coupler.csproj"
$VERSION = "2.1.0"

if (Test-Path $csprojPath) {
  $csprojContent = Get-Content $csprojPath -Raw
  if ($csprojContent -match '<Version>(.*?)<\/Version>') {
    $VERSION = $matches[1]
    Write-Host "Version extracted from csproj: $VERSION"
  } else {
    Write-Host "Version tag not found in csproj, using default: $VERSION"
  }
} else {
  Write-Host "csproj not found, using default version: $VERSION"
}

$COMMIT_SHA = "${{ github.sha }}"
$SHORT_SHA = $COMMIT_SHA.Substring(0, 7)
$BRANCH = "${{ github.ref_name }}"
$BUILD_DATE = (Get-Date).ToUniversalTime().ToString("yyyy-MM-dd HH:mm:ss UTC")

# Create version.json
$versionJson = @{
  version = $VERSION
  commitSha = $SHORT_SHA
  branch = $BRANCH
  buildDate = $BUILD_DATE
  buildEnvironment = "Gitea Actions"
} | ConvertTo-Json

$versionJson | Out-File -FilePath "Data_Coupler\wwwroot\version.json" -Encoding UTF8

Logica:

  1. Legge contenuto del file .csproj
  2. Usa regex per estrarre <Version> tag
  3. Se non trova, usa fallback "2.1.0"
  4. Genera version.json usando ConvertTo-Json per formato corretto
  5. Data in formato UTC consistente con Linux

Consistenza: Entrambi i workflow (Linux e Windows) ora leggono la versione dalla stessa fonte (.csproj)

Modello Dati

VersionInfo.cs

public class VersionInfo
{
    public string Version { get; set; } = "0.0.0";
    public string CommitSha { get; set; } = "unknown";
    public string Branch { get; set; } = "unknown";
    public string BuildDate { get; set; } = "unknown";
    public string BuildEnvironment { get; set; } = "Local";

    // Formati di output
    public string GetFullVersion()    // "v2.1.0 (main-abc1234)"
    public string GetShortVersion()   // "v2.1.0"
}

Servizio di Versioning

VersionService.cs

Il servizio:

  1. Viene registrato come Singleton in Program.cs
  2. Carica version.json all'avvio dell'applicazione
  3. Fornisce fallback a valori di default se il file non esiste
  4. Log dettagliato delle operazioni
public class VersionService : IVersionService
{
    public VersionInfo GetVersion()        // Info complete
    public string GetDisplayVersion()       // Solo versione per UI
}

Registrazione del Servizio

In Program.cs:

builder.Services.AddSingleton<Data_Coupler.Services.IVersionService, Data_Coupler.Services.VersionService>();

Integrazione UI

NavMenu.razor

@inject Data_Coupler.Services.IVersionService VersionService

<a class="navbar-brand" href="">Data_Coupler @_version</a>

@code {
    private string _version = "";

    protected override void OnInitialized()
    {
        _version = VersionService.GetDisplayVersion();
    }
}

Risultato: "Data_Coupler v2.1.0"

Gestione Versioni

⚠️ Importante: Incremento Manuale

Il sistema NON incrementa automaticamente la versione. Il versioning segue questo flusso:

  1. Developer aggiorna manualmente <Version> in Data_Coupler.csproj
  2. Gitea Actions legge la versione dal file .csproj
  3. Workflow genera version.json con la versione letta
  4. Applicazione carica e mostra la versione

Come Incrementare la Versione

NON modificare version.json direttamente. Segui questi passi:

  1. File csproj: Aggiorna <Version>2.1.0</Version> in Data_Coupler.csproj
  2. Commit e Push: Le Gitea Actions genereranno automaticamente il nuovo version.json
  3. Deploy: La nuova versione sarà visibile nell'applicazione

Semantic Versioning

Seguiamo il pattern MAJOR.MINOR.PATCH:

  • MAJOR: Breaking changes (incompatibilità con versione precedente)
  • MINOR: Nuove feature backward-compatible (non rompe codice esistente)
  • PATCH: Bug fixes (solo correzioni, nessuna nuova funzionalità)

Esempio progressione:

  • 2.1.02.1.1 (bug fix - aggiornamento PATCH)
  • 2.1.12.2.0 (nuova feature - aggiornamento MINOR)
  • 2.2.03.0.0 (breaking change - aggiornamento MAJOR)

Pattern di Incremento: Logica e Consistenza

🎯 Fonte Unica della Verità (Single Source of Truth)

Il file Data_Coupler.csproj è l'unica fonte della versione:

<PropertyGroup>
  <Version>2.1.0</Version>
  <AssemblyVersion>2.1.0.0</AssemblyVersion>
  <FileVersion>2.1.0.0</FileVersion>
</PropertyGroup>

📋 Flusso di Versioning

┌───────────────────────────────────────────────────────────────┐
│ 1. Developer aggiorna <Version> in Data_Coupler.csproj       │
│    - MANUALE: Developer sceglie il numero (2.1.0 → 2.2.0)    │
│    - Segue Semantic Versioning                                │
└────────────────────────┬──────────────────────────────────────┘
                         ↓
┌───────────────────────────────────────────────────────────────┐
│ 2. Git Commit & Push                                          │
│    - git commit -am "Bump version to 2.2.0"                   │
│    - git push origin main                                     │
└────────────────────────┬──────────────────────────────────────┘
                         ↓
┌───────────────────────────────────────────────────────────────┐
│ 3. Gitea Actions Triggered                                    │
│    - Workflow avvia automaticamente                           │
└────────────────────────┬──────────────────────────────────────┘
                         ↓
┌───────────────────────────────────────────────────────────────┐
│ 4. Build Linux: Legge versione da .csproj                    │
│    - grep '<Version>' Data_Coupler.csproj                     │
│    - Estrae: "2.2.0"                                          │
└────────────────────────┬──────────────────────────────────────┘
                         ↓
┌───────────────────────────────────────────────────────────────┐
│ 5. Build Windows: Legge versione da .csproj                  │
│    - PowerShell regex: '<Version>(.*?)<\/Version>'            │
│    - Estrae: "2.2.0"                                          │
└────────────────────────┬──────────────────────────────────────┘
                         ↓
┌───────────────────────────────────────────────────────────────┐
│ 6. Genera version.json (identico su Linux e Windows)         │
│    {                                                          │
│      "version": "2.2.0",                                      │
│      "commitSha": "abc1234",                                  │
│      "branch": "main",                                        │
│      "buildDate": "2026-02-02 10:30:45 UTC",                 │
│      "buildEnvironment": "Gitea Actions"                      │
│    }                                                          │
└────────────────────────┬──────────────────────────────────────┘
                         ↓
┌───────────────────────────────────────────────────────────────┐
│ 7. Docker Build include version.json                         │
│    - File copiato in container                                │
└────────────────────────┬──────────────────────────────────────┘
                         ↓
┌───────────────────────────────────────────────────────────────┐
│ 8. Deploy & Runtime                                           │
│    - VersionService carica version.json                       │
│    - NavMenu mostra: "Data_Coupler v2.2.0"                   │
└───────────────────────────────────────────────────────────────┘

Garanzie di Consistenza

Aspetto Linux Windows Consistenza
Fonte versione .csproj .csproj Identica
Metodo estrazione grep + sed PowerShell regex Equivalente
Fallback default "2.1.0" "2.1.0" Identico
Formato date UTC UTC Identico
Formato JSON Manuale ConvertTo-Json Valido
Posizione file wwwroot/version.json wwwroot\version.json Stessa

🚫 Cosa NON Viene Fatto

  • Auto-incremento: Non esiste logica di auto-bump (nessun +1 automatico)
  • Parsing Git Tags: Non legge versioni da git tags
  • Calcolo automatico: Non calcola MAJOR/MINOR/PATCH basandosi su commit
  • Versionamento per branch: Tutti i branch usano la stessa versione dal .csproj

Cosa Viene Fatto

  • Lettura semplice: Estrae valore esistente da .csproj
  • Propagazione: Copia versione in version.json
  • Metadata arricchito: Aggiunge commit SHA, branch, data
  • Consistenza multi-platform: Stessa logica su Linux e Windows

Decisioni di Design

Perché incremento manuale?

  • Controllo esplicito: Developer decide consapevolmente quando incrementare
  • Semantic Versioning corretto: Umano determina se MAJOR/MINOR/PATCH
  • Semplicità: Nessuna logica complessa di parsing commit messages
  • Chiarezza: Una singola fonte di verità (.csproj)

Perché non auto-incremento basato su commit?

  • Richiederebbe parsing di commit messages (Conventional Commits)
  • Complessità aggiunta senza reale beneficio
  • Rischio di errori nell'interpretazione dei commit
  • Preferibile controllo umano per decisioni di versioning

File version.json

Formato

{
  "version": "2.1.0",
  "commitSha": "abc1234",
  "branch": "main",
  "buildDate": "2026-02-02 10:30:45 UTC",
  "buildEnvironment": "Gitea Actions"
}

Posizione

  • Sviluppo Locale: Data_Coupler/wwwroot/version.json
  • Docker Container: /app/wwwroot/version.json

Fallback

Se version.json non esiste o c'è un errore, il servizio usa:

{
  "version": "2.1.0",
  "commitSha": "local",
  "branch": "dev",
  "buildDate": "2026-02-02 HH:mm:ss",
  "buildEnvironment": "Local"
}

Testing

Test Locale

  1. Creare manualmente Data_Coupler/wwwroot/version.json:
{
  "version": "2.1.0-dev",
  "commitSha": "local",
  "branch": "dev",
  "buildDate": "2026-02-02",
  "buildEnvironment": "Local"
}
  1. Eseguire l'applicazione:
dotnet run --project Data_Coupler/Data_Coupler.csproj
  1. Verificare nel NavMenu la versione "Data_Coupler v2.1.0-dev"

Test Docker

Dopo il build e push tramite Gitea Actions:

docker pull gitea.home-nas-ds.org/alessio/data-coupler:latest
docker run -p 7550:8080 gitea.home-nas-ds.org/alessio/data-coupler:latest

Verificare:

  • NavMenu mostra la versione corretta
  • Logs mostrano: Version loaded: v2.1.0 (main-abc1234)

Troubleshooting

Problema: Versione non aggiornata

Sintomo: NavMenu mostra sempre "v2.1.0" anche dopo aggiornamento

Soluzione:

  1. Verificare che version.json sia stato generato nel workflow
  2. Controllare i logs del workflow Gitea
  3. Verificare che il file sia incluso nel Docker image:
docker run --rm gitea.home-nas-ds.org/alessio/data-coupler:latest cat /app/wwwroot/version.json

Problema: VersionService non trovato

Sintomo: Errore Cannot provide a value for property 'VersionService'

Soluzione: Verificare la registrazione in Program.cs:

builder.Services.AddSingleton<Data_Coupler.Services.IVersionService, Data_Coupler.Services.VersionService>();

Problema: version.json non caricato

Sintomo: Logs mostrano "version.json not found"

Soluzione:

  1. Verificare che il file esista in wwwroot/version.json
  2. Controllare i permessi del file
  3. Verificare il path in VersionService.cs:
var versionFilePath = Path.Combine(_env.ContentRootPath, "wwwroot", "version.json");

Best Practices

1. Aggiornamento Versione

  • Aggiornare sempre <Version> in Data_Coupler.csproj
  • Seguire Semantic Versioning
  • Documentare le modifiche nel changelog

2. Build e Deploy

  • Testare localmente prima del push
  • Verificare che i workflow Gitea completino con successo
  • Controllare i logs del container dopo il deploy

3. Monitoraggio

  • Verificare periodicamente che la versione sia corretta
  • Controllare i logs per errori di caricamento version.json
  • Mantenere sincronizzati i tag Docker con la versione applicazione

Integrazione Futura

Potenziali Miglioramenti

  1. Health Check Endpoint:
app.MapGet("/version", (IVersionService versionService) => 
    Results.Ok(versionService.GetVersion()));
  1. Footer con Versione Dettagliata:
<footer>
    Build: @_versionInfo.CommitSha | Branch: @_versionInfo.Branch | @_versionInfo.BuildDate
</footer>
  1. About Page: Creare una pagina dedicata con tutte le informazioni di versione

  2. Notifiche di Aggiornamento: Sistema per notificare agli utenti quando è disponibile una nuova versione

Riferimenti

  • File Sorgenti:

    • Data_Coupler/Models/VersionInfo.cs
    • Data_Coupler/Services/VersionService.cs
    • Data_Coupler/Shared/NavMenu.razor
    • Data_Coupler/Program.cs
    • .gitea/workflows/docker-build.yml
  • Documentazione Correlata:

    • GITHUB_ACTIONS_SETUP.md
    • DOCKER_DEPLOYMENT.md
    • .gitea/workflows/README.md

Versione Documento: 1.0
Data Creazione: 2 Febbraio 2026
Autore: Alessio Dalsanto
Ultima Revisione: 2 Febbraio 2026