Share via


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, aprenderá a usar la tarea Caché para almacenar en caché y restaurar los paquetes NuGet.

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 la memoria 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

Tendremos que 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é.

Captura de pantalla que muestra cómo se genera la clave de caché en Azure Pipelines.

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 restore, lo que 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 las tareas dentro de la misma canalización pueden acceder a la misma caché y compartirla.

Comparación del rendimiento

El almacenamiento en caché de canalización es una excelente manera de acelerar la ejecución de la canalización. Esta es 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.

Captura de pantalla que muestra el rendimiento de la canalización con y sin almacenamiento en caché.

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)'