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

Não há suporte para o cache de pipeline em pipelines de lançamento clássicos.

Bloquear as dependências

Para configurar a tarefa de cache, primeiro você deve bloquear as dependências do projeto e criar um arquivo package.lock.json. O hash do conteúdo do arquivo de bloqueio será usado para gerar uma chave de cache exclusiva.

Para bloquear as dependências do projeto, defina a propriedade RestorePackagesWithLockFile no arquivo csproj como true. A restauração do NuGet gera um 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 de packages.lock.json é transformado em hash para produzir uma chave dinâmica de cache. 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'

Observação

Se você estiver usando o Ubuntu 24.04 ou superior, deverá usar a tarefa NuGetAuthenticate com a CLI do .NET em vez da tarefa NuGetCommand@2. Consulte Suporte para imagens mais recentes hospedadas do Ubuntu para obter mais detalhes.

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 é executado, gerando seu arquivo project.assets.json. A tarefa de restauração não baixará pacotes que já estejam 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)'

Essa abordagem também é válida para projetos do .NET Core se o projeto usa packages.lock.json para bloquear versões do pacote. Você pode habilitar isso definindo RestorePackagesWithLockFile para True no arquivo * Csproj* ou usando o seguinte comando: dotnet restore --use-lock-file.