Almacenamiento en caché de paquetes NuGet
Azure DevOps Services
Con el almacenamiento en caché de canalizaciones, puede reducir el tiempo de compilación porque se almacenan las dependencias de manera que se puedan reutilizar en ejecuciones posteriores. En este artículo, obtendrá información sobre cómo a usar la tarea Caché para almacenar en caché y restaurar los paquetes NuGet.
Nota:
El almacenamiento en caché de las canalizaciones se admite en trabajos de grupos de agentes para canalizaciones YAML y clásicas. Sin embargo, no se admite en canalizaciones de versiones clásicas.
Bloqueo de dependencias
Para configurar la tarea de caché, primero debemos bloquear las dependencias del proyecto y crear un archivo package.lock.json. Usaremos el hash del contenido de este archivo para generar una clave única para nuestra caché.
Para bloquear las dependencias del proyecto, establezca la propiedad RestorePackagesWithLockFile del archivo csproj en true. La restauración de NuGet genera un archivo de bloqueo packages.lock.json en el directorio raíz del proyecto. Asegúrese de comprobar el archivo packages.lock.json en el código fuente.
<PropertyGroup>
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
</PropertyGroup>
Almacenamiento en caché de paquetes NuGet
Necesitaremos crear una variable de canalización para que apunte a la ubicación de nuestros paquetes en el agente que ejecuta la canalización.
En este ejemplo, se aplica un algoritmo hash al contenido de packages.lock.json para generar una clave de caché dinámica. Esto garantiza que cada vez que se modifica el archivo, se genera una nueva clave de caché.
variables:
NUGET_PACKAGES: $(Pipeline.Workspace)/.nuget/packages
- task: Cache@2
displayName: Cache
inputs:
key: 'nuget | "$(Agent.OS)" | **/packages.lock.json,!**/bin/**,!**/obj/**'
restoreKeys: |
nuget | "$(Agent.OS)"
nuget
path: '$(NUGET_PACKAGES)'
cacheHitVar: 'CACHE_RESTORED'
Nota:
Las memorias caché son inmutables, una vez creada una caché, no se puede modificar su contenido.
Restauración de caché
Esta tarea solo se ejecutará si la variable CACHE_RESTORED
es false.
- task: NuGetCommand@2
condition: ne(variables.CACHE_RESTORED, true)
inputs:
command: 'restore'
restoreSolution: '**/*.sln'
Si encuentra el mensaje de error "project.assets.json no encontrado" durante la tarea de compilación, puede resolverlo quitando la condición condition: ne(variables.CACHE_RESTORED, true)
de la tarea de restauración. Al hacerlo, se ejecutará el comando de restauración y se generará el archivo project.assets.json. La tarea de restauración no descargará paquetes que ya están presentes en la carpeta correspondiente.
Nota:
Una canalización puede contener una o varias tareas de almacenamiento en caché, y los trabajos y tareas dentro de la misma canalización pueden acceder y compartir la misma caché.
Comparación del rendimiento
El almacenamiento en caché de canalización es una excelente manera de acelerar la ejecución de la canalización. A continuación, se muestra una comparación de rendimiento en paralelo para dos canalizaciones diferentes. Antes de agregar la tarea de almacenamiento en caché (derecha), la tarea de restauración tardaba aproximadamente 41 segundos. Hemos agregado la tarea de almacenamiento en caché a una segunda canalización (izquierda) y hemos configurado la tarea de restauración para que se ejecute cuando se encuentre una pérdida en la memoria caché. La tarea de restauración en este caso tardó 8 segundos en completarse.
A continuación se muestra la canalización YAML completa como referencia:
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)'