Compartilhar via


Armazenar em cache pacotes NuGet

Azure DevOps Services

Com o cache de pipeline, você pode reduzir o tempo de compilação armazenando em cache suas dependências para serem reutilizadas em execuções posteriores. Neste artigo, você aprenderá a usar a tarefa Cache para armazenar em cache e restaurar seus pacotes NuGet.

Observação

O armazenamento em cache de Pipeline tem suporte em trabalhos de pool de agentes para pipelines YAML e Clássicos. No entanto, não há suporte para isso em pipelines de lançamento Clássicos.

Bloquear as dependências

Para configurar a tarefa de cache, primeiro devemos bloquear as dependências do projeto e criar um arquivo package.lock.json. Usaremos o hash do conteúdo desse arquivo para gerar uma chave exclusiva para nosso cache.

Para bloquear as dependências do projeto, defina a propriedade RestorePackagesWithLockFile no arquivo csproj como true. A restauração do NuGet gera o arquivo de bloqueio packages.lock.json no diretório raiz do projeto. Verifique se você marcou o arquivo packages.lock.json no código-fonte.

<PropertyGroup>
  <RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
</PropertyGroup>

Armazenar em cache pacotes NuGet

Precisaremos criar uma variável de pipeline para apontar para o local de nossos pacotes no agente que executa o pipeline.

Neste exemplo, o conteúdo do packages.lock.json será com hash para produzir uma chave de cache dinâmica. Isso garante que toda vez que o arquivo for modificado, uma nova chave de cache seja gerada.

Uma captura de tela mostrando como a chave de cache é gerada no 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'

Observação

Os caches são imutáveis, depois que um cache é criado, o conteúdo dele não pode ser alterado.

Restaurar cache

Essa tarefa só será executada se a variável CACHE_RESTORED for falsa.

- task: NuGetCommand@2
  condition: ne(variables.CACHE_RESTORED, true)
  inputs:
    command: 'restore'
    restoreSolution: '**/*.sln'

Se você encontrar a mensagem de erro "project.assets.json não encontrado" durante a tarefa de compilação, poderá resolvê-la removendo a condição condition: ne(variables.CACHE_RESTORED, true) da tarefa de restauração. Ao fazer isso, o comando de restauração será executado, gerando seu arquivo project.assets.json. A tarefa de restauração não baixará pacotes que já estão presentes na pasta correspondente.

Observação

Um pipeline pode conter uma ou mais tarefas de cache, e trabalhos e tarefas dentro do mesmo pipeline podem acessar e compartilhar o mesmo cache.

Comparação de desempenho

O cache de pipeline é uma ótima maneira de acelerar a execução do pipeline. Aqui está uma comparação de desempenho lado a lado para dois pipelines diferentes. Antes de adicionar a tarefa de cache (à direita), a tarefa de restauração levou aproximadamente 41 segundos. Adicionamos a tarefa de cache em um segundo pipeline (à esquerda) e configuramos a tarefa de restauração para ser executada quando uma falha de cache for encontrada. Nesse caso, a tarefa de restauração levou 8 segundos para ser concluída.

Uma captura de tela mostrando o desempenho do pipeline com e sem cache.

Veja abaixo o pipeline YAML completo para referência:

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