Armazenar em cache pacotes NuGet
Azure DevOps Services | Azure DevOps Server 2022 | Azure DevOps Server 2020
O cache de pipeline ajuda a reduzir o tempo de build armazenando dependências para reutilização em execuções futuras. 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.
Pré-requisitos
Produto | Requisitos |
---|---|
Azure DevOps | - Um projeto do Azure DevOps. - Permissões: – Para conceder acesso a todos os pipelines do projeto, você deve ser membro do grupo Administradores do Projeto. |
Bloquear as dependências
Antes de configurar a tarefa de cache, você precisa bloquear as dependências do projeto e gerar um arquivo package.lock.json. A chave de cache exclusiva é derivada do hash do conteúdo desse arquivo de bloqueio para garantir a consistência entre builds.
Para bloquear as dependências do projeto, adicione a propriedade RestorePackagesWithLockFile ao arquivo csproj e defina-o como verdadeiro. Quando você executa nuget restore
, ele gera um arquivo 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
Para armazenar em cache pacotes NuGet, defina uma variável de pipeline que aponte para o local dos pacotes no agente que executa o pipeline.
No exemplo a seguir, o conteúdo do packages.lock.json é convertido em hash para gerar uma chave de cache dinâmica. Isso garante que sempre que o arquivo for alterado, uma nova chave de cache será criada.
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'
Observação
Os caches são imutáveis, depois que um cache é criado, o conteúdo dele não pode ser alterado.
Restaurar cache
A tarefa a seguir só será executada se a variável CACHE_RESTORED
for falsa. Isso significa que, se ocorrer um hit no cache (os pacotes já estão disponíveis no cache), a etapa de restauração é pulada para economizar tempo e recursos. Se nenhum cache for encontrado, o comando de restauração será executado para baixar as dependências necessárias.
- 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 posterior, 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.
Lidar com erros de "project.assets.json não encontrado"
Se você encontrar o erro "project.assets.json não encontrado" durante sua tarefa de build, remova a condição condition: ne(variables.CACHE_RESTORED, true)
da tarefa de restauração. Isso garante que o comando de restauração seja executado e gere o arquivo project.assets.json. A tarefa de restauração não recarrega os pacotes que já estão presentes na pasta correspondente.
Observação
Um pipeline pode incluir várias tarefas de cache, e trabalhos e tarefas no mesmo pipeline podem acessar e compartilhar o mesmo cache.
Comparação de desempenho
O cache de pipelines reduz significativamente o tempo necessário para restaurar dependências, resultando em compilações mais rápidas. A comparação a seguir ilustra o impacto do cache no tempo de execução do pipeline para dois pipelines diferentes:
Sem cache (à direita): a tarefa de restauração levou aproximadamente 41 segundos.
Com cache (à esquerda): Adicionamos a tarefa de cache em um segundo pipeline e configuramos a tarefa de restauração para ser executada somente quando uma falha de cache ocorrer. A tarefa de restauração, nesse caso, foi concluída em apenas 8 segundos.
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 se aplica a projetos do .NET Core, desde que seu projeto use packages.lock.json para bloquear versões do pacote. Você pode habilitar isso definindo RestorePackagesWithLockFile
para True
no arquivo * Csproj* ou executando o seguinte comando: dotnet restore --use-lock-file
.