Memorizzare nella cache i pacchetti NuGet
Azure DevOps Services | Azure DevOps Server 2022 | Azure DevOps Server 2020
La memorizzazione nella cache della pipeline consente di ridurre il tempo di compilazione archiviando le dipendenze per il riutilizzo in esecuzioni future. Questo articolo illustra come utilizzare l'attività cache per salvare nella cache e ripristinare i pacchetti NuGet.
Nota
La memorizzazione nella cache della pipeline non è supportata nelle pipeline di rilascio classiche.
Prerequisiti
Prodotto | Requisiti |
---|---|
Azure DevOps | - Un progetto Azure DevOps. Autorizzazioni - : - Per concedere l'accesso a tutte le pipeline del progetto, è necessario essere membri del gruppo Project Administrators. |
Bloccare le dipendenze
Prima di configurare l'attività della cache, è necessario bloccare le dipendenze del progetto e generare un file package.lock.json. La chiave della cache univoca deriva dall'hash del contenuto di questo file di blocco per garantire la coerenza tra le compilazioni.
Per bloccare le dipendenze del progetto, aggiungere la proprietà RestorePackagesWithLockFile al file csproj e impostarla su true. Quando si esegue nuget restore
, viene generato un file packages.lock.json nella directory radice del progetto. Assicurarsi di controllare il file packages.lock.json nel codice sorgente.
<PropertyGroup>
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
</PropertyGroup>
Memorizzare nella cache i pacchetti NuGet
Per memorizzare nella cache i pacchetti NuGet, definire una variabile della pipeline che punti al percorso dei pacchetti nell'agente che esegue la pipeline.
Nell'esempio seguente il contenuto del packages.lock.json viene sottoposto a hash per generare una chiave della cache dinamica. In questo modo si garantisce che ogni volta che il file viene modificato, viene creata una nuova chiave della cache.
variables:
NUGET_PACKAGES: $(Pipeline.Workspace)/.nuget/packages
- task: Cache@2
displayName: Cache v2 task
inputs:
key: 'nuget | "$(Agent.OS)" | **/packages.lock.json,!**/bin/**,!**/obj/**'
restoreKeys: |
nuget | "$(Agent.OS)"
nuget
path: '$(NUGET_PACKAGES)'
cacheHitVar: 'CACHE_RESTORED'
Nota
Le cache non sono modificabili, una volta creata una cache, il relativo contenuto non può essere modificato.
Ripristinare la cache
L'attività seguente verrà eseguita solo se la variabile CACHE_RESTORED
è false. Ciò significa che se si verifica un riscontro nella cache (i pacchetti sono già disponibili nella cache), il passaggio di ripristino viene ignorato per risparmiare tempo e risorse. Se non viene trovata alcuna cache, il comando di ripristino viene eseguito per scaricare le dipendenze necessarie.
- task: NuGetCommand@2
condition: ne(variables.CACHE_RESTORED, true)
inputs:
command: 'restore'
restoreSolution: '**/*.sln'
Nota
Se si usa Ubuntu 24.04 o versione successiva, è necessario usare l'attività NuGetAuthenticate
con l'interfaccia della riga di comando di .NET anziché l'attività NuGetCommand@2
. Per ulteriori dettagli, vedere il supporto per le immagini ospitate di Ubuntu più recenti.
Gestire gli errori "project.assets.json non trovati"
Se si verifica l'errore "project.assets.json non trovato" durante l'attività di compilazione, rimuovere la condizione condition: ne(variables.CACHE_RESTORED, true)
dall'attività di ripristino. In questo modo il comando di ripristino viene eseguito e genera il file project.assets.json. L'attività di ripristino non scarica nuovamente i pacchetti già presenti nella cartella corrispondente.
Nota
Una pipeline può includere più attività di memorizzazione nella cache e processi e attività all'interno della stessa pipeline possono accedere e condividere la stessa cache.
Confronto delle prestazioni
La memorizzazione nella cache della pipeline riduce significativamente il tempo necessario per ripristinare le dipendenze, causando compilazioni più veloci. Il confronto seguente illustra l'impatto della memorizzazione nella cache sul tempo di esecuzione della pipeline per due pipeline diverse:
Senza memorizzazione nella cache (a destra): l'attività di ripristino ha richiesto circa 41 secondi.
Con memorizzazione nella cache (a sinistra): Abbiamo aggiunto l'attività di memorizzazione nella cache a una seconda pipeline e configurato l'attività di ripristino per essere eseguita solo in caso di un miss della cache. L'attività di ripristino in questo caso è stata completata in soli 8 secondi.
Di seguito è riportata la pipeline YAML completa per riferimento:
pool:
vmImage: 'windows-latest'
variables:
solution: '**/*.sln'
buildPlatform: 'Any CPU'
buildConfiguration: 'Release'
NUGET_PACKAGES: $(Pipeline.Workspace)/.nuget/packages
steps:
- task: NuGetToolInstaller@1
displayName: 'NuGet tool installer'
- task: Cache@2
displayName: 'NuGet Cache'
inputs:
key: 'nuget | "$(Agent.OS)" | **/packages.lock.json,!**/bin/**,!**/obj/**'
restoreKeys: |
nuget | "$(Agent.OS)"
nuget
path: '$(NUGET_PACKAGES)'
cacheHitVar: 'CACHE_RESTORED'
- task: NuGetCommand@2
displayName: 'NuGet restore'
condition: ne(variables.CACHE_RESTORED, true)
inputs:
command: 'restore'
restoreSolution: '$(solution)'
- task: VSBuild@1
displayName: 'Visual Studio Build'
inputs:
solution: '$(solution)'
platform: '$(buildPlatform)'
configuration: '$(buildConfiguration)'
Questo approccio si applica anche ai progetti .NET Core, purché il progetto usi packages.lock.json per bloccare le versioni dei pacchetti. È possibile abilitare questa opzione impostando RestorePackagesWithLockFile
su True
nel file * Csproj* oppure eseguendo il comando seguente: dotnet restore --use-lock-file
.