Almacenamiento en caché de paquetes NuGet
Azure DevOps Services | Azure DevOps Server 2022 | Azure DevOps Server 2020
El almacenamiento en caché de canalizaciones ayuda a reducir el tiempo de compilación mediante el almacenamiento de dependencias para su reutilización en futuras ejecuciones. 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 canalizaciones no se admite en canalizaciones de versión clásica.
Prerrequisitos
Bloqueo de dependencias
Antes de configurar la tarea de caché, debe bloquear las dependencias del proyecto y generar un archivo package.lock.json. La clave de caché única se deriva del hash del contenido de este archivo de bloqueo para garantizar la coherencia entre compilaciones.
Para bloquear las dependencias del proyecto, agregue la propiedad RestorePackagesWithLockFile al archivo csproj y establézcalo en true. Al ejecutar nuget restore
, genera un archivo 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
Para almacenar en caché paquetes NuGet, defina una variable de canalización que apunte a la ubicación de los paquetes en el agente que ejecuta la canalización.
En el ejemplo siguiente, el contenido del packages.lock.json se hash para generar una clave de caché dinámica. Esto garantiza que cada vez que cambia el archivo, se crea una nueva clave de caché.
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:
Las memorias caché son inmutables, una vez creada una caché, no se puede modificar su contenido.
Restauración de caché
La siguiente tarea solo se ejecutará si la variable CACHE_RESTORED
es false. Esto significa que si se produce una acierto de caché (los paquetes ya están disponibles en la memoria caché), se omite el paso de restauración para ahorrar tiempo y recursos. Si no se encuentra ninguna memoria caché, el comando restore se ejecuta para descargar las dependencias necesarias.
- task: NuGetCommand@2
condition: ne(variables.CACHE_RESTORED, true)
inputs:
command: 'restore'
restoreSolution: '**/*.sln'
Nota:
Si usa Ubuntu 24.04 o posterior, debe usar la tarea NuGetAuthenticate
con la CLI de .NET en lugar de la tarea NuGetCommand@2
. Consulte Compatibilidad con las imágenes más recientes hospedadas en Ubuntu para obtener más detalles.
Administrar los errores "project.assets.json no encontrado"
Si encuentra el error "project.assets.json no encontrado" durante la tarea de compilación, quite la condición condition: ne(variables.CACHE_RESTORED, true)
de la tarea de restauración. Esto garantiza que el comando restore se ejecute y genere el archivo project.assets.json. La tarea de restauración no vuelve a descargar paquetes que ya están presentes en la carpeta correspondiente.
Nota:
Una canalización puede incluir 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 pipelines reduce significativamente el tiempo necesario para restaurar las dependencias, lo que conduce a compilaciones más rápidas. En la siguiente comparación se muestra el impacto del almacenamiento en caché en el tiempo de ejecución de la canalización para dos canalizaciones diferentes:
sin almacenamiento en caché (derecha): la tarea de restauración tardó aproximadamente 41 segundos.
Con el almacenamiento en caché (izquierda): agregamos la tarea de almacenamiento en caché a una segunda canalización y configuramos la tarea de restauración para que solo se ejecute cuando se produzca una falta de caché. La tarea de restauración en este caso se completó en tan solo 8 segundos.
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)'
Este enfoque también se aplica a los proyectos de .NET Core, siempre que el proyecto use packages.lock.json para bloquear las versiones del paquete. Puede habilitarlo estableciendo RestorePackagesWithLockFile
en True
en el archivo * Csproj* o ejecutando el siguiente comando: dotnet restore --use-lock-file
.