Buforowanie pakietów NuGet

Usługa Azure DevOps Services

Dzięki buforowaniu potoku można skrócić czas kompilacji, buforując zależności do ponownego użycia w kolejnych uruchomieniach. W tym artykule dowiesz się, jak buforować i przywracać pakiety NuGet przy użyciu zadania Pamięci podręcznej .

Blokowanie zależności

Aby skonfigurować zadanie pamięci podręcznej, musimy najpierw zablokować zależności projektu i utworzyć plik package.lock.json . Użyjemy skrótu zawartości tego pliku, aby wygenerować unikatowy klucz dla naszej pamięci podręcznej.

Aby zablokować zależności projektu, ustaw właściwość RestorePackagesWithLockFile w pliku csproj na wartość true. Przywracanie nuGet generuje plik blokady packages.lock.json w katalogu głównym projektu. Upewnij się, że plik packages.lock.json jest sprawdzany w kodzie źródłowym.

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

Buforowanie pakietów NuGet

Musimy utworzyć zmienną potoku, aby wskazywała lokalizację pakietów na agencie, na którym działa potok.

W tym przykładzie zawartość pliku packages.lock.json zostanie skrótem w celu utworzenia dynamicznego klucza pamięci podręcznej. Dzięki temu za każdym razem, gdy plik zostanie zmodyfikowany, zostanie wygenerowany nowy klucz pamięci podręcznej.

Zrzut ekranu przedstawiający sposób generowania klucza pamięci podręcznej w usłudze 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'

Uwaga

Pamięci podręczne są niezmienne, po utworzeniu pamięci podręcznej nie można modyfikować jego zawartości.

Przywracanie pamięci podręcznej

To zadanie zostanie uruchomione tylko wtedy, gdy zmienna CACHE_RESTORED ma wartość false.

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

Jeśli podczas zadania kompilacji wystąpi komunikat o błędzie "project.assets.json", możesz go rozwiązać, usuwając warunek condition: ne(variables.CACHE_RESTORED, true) z zadania przywracania. Dzięki temu polecenie przywracania zostanie wykonane, generując plik project.assets.json. Zadanie przywracania nie pobierze pakietów, które są już obecne w odpowiednim folderze.

Uwaga

Potok może zawierać co najmniej jedno zadanie buforowania, a zadania i zadania w tym samym potoku mogą uzyskiwać dostęp do tej samej pamięci podręcznej i udostępniać je.

Porównanie wydajności

Buforowanie potoków to doskonały sposób na przyspieszenie wykonywania potoku. Oto porównanie wydajności równoległej dla dwóch różnych potoków. Przed dodaniem zadania buforowania (po prawej) zadanie przywracania trwało około 41 sekund. Dodaliśmy zadanie buforowania do drugiego potoku (po lewej) i skonfigurowaliśmy zadanie przywracania do uruchomienia po napotkaniu błędu pamięci podręcznej. Wykonanie zadania przywracania w tym przypadku trwało 8 sekund.

Zrzut ekranu przedstawiający wydajność potoku z buforowaniem i bez buforowania.

Poniżej znajduje się pełny potok YAML do celów referencyjnych:

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