避免使用Azure Devops自托管生成代理进行git clean

问题描述

我在Azure托管的git存储库中有一个YAML构建脚本,该脚本在本地VM上运行的7个构建代理中被触发。每次运行时,由于较大的node_modules文件夹会花费很长时间进行清理,因此构建会执行git clean,这会花费大量时间。

MSDN页面here似乎表明这是可配置的,但是没有显示有关如何配置它的详细信息。我不知道是否应该在代理,YAML脚本,管道上的DevOps内或在哪里指定此设置。

还有其他文档丢失吗?

更新: YAML文件的开头在这里

variables:
  BUILD_VERSION: 1.0.0.$(Build.BuildId)
  buildConfiguration: 'Release'
  process.clean: false

jobs:
###### ######################################################
###### 1 - Build and publish .NET
#############################################################

- job: net_build_publish
  displayName: .NET build and publish
  pool:
    name: default
  steps:
  - script: echo $(BUILD_VERSION)

  - task: DotNetCoreCLI@2
    displayName: dotnet build $(buildConfiguration)
    inputs:
      command: 'build'
      projects: |
        myrepo/**/API/*.csproj
      arguments: '-c $(buildConfiguration) /p:Version=$(BUILD_VERSION)'

完整的Yaml更长,但是第一个作业的输出包括Checkout任务中的输出

Checkout myrepo@master to s

View raw log

Starting: Checkout myrepo@master to s
==============================================================================
Task         : Get sources
Description  : Get sources from a repository. Supports Git,TfsVC,and SVN repositories.
Version      : 1.0.0
Author       : Microsoft
Help         : [More information](https://go.microsoft.com/fwlink/?LinkId=798199)
==============================================================================
Syncing repository: myrepo (Git)
Prepending Path environment variable with directory containing 'git.exe'.
git version
git version 2.26.2.windows.1
git lfs version
git-lfs/2.11.0 (GitHub; windows amd64; go 1.14.2; git 48b28d97)
git config --get remote.origin.url
git clean -ffdx
Removing myrepo/Data/Core/API/bin/
Removing myrepo/Data/Core/API/customersettings.json
Removing myrepo/Data/Core/API/Obj/
Removing myrepo/Data/Core/Shared/bin/
Removing myrepo/Data/Core/Shared/obj/
....

我们还有另一项工作,它为Angular项目运行npm installnpm build,并且管道中的每个构建都需要5分钟来执行npm安装步骤,这可能是因为git clean检索存储库时是什么?

解决方法

正如我在下面提到的。在运行npm install之前,您需要计算哈希值。如果哈希与保持在node_modules附近的哈希相同,则可以跳过安装依赖项。这可以帮助您实现这一目标:

steps:
- task: PowerShell@2
  displayName: 'Calculate and save packages.config hash'
  inputs:
    targetType: 'inline'
    pwsh: true
    script: |
      # generates a hash of package-lock.json
      $newHash = Get-FileHash -Algorithm MD5 -Path (Get-ChildItem package-lock.json)
      $hashPath = "$(System.DefaultWorkingDirectory)/cache-npm/hash.txt"
      if(Test-Path -path $hashPath) {
        if(Compare-Object -ReferenceObject $(Get-Content $hashPath) -DifferenceObject $newHash) {
          
          Write-Host "##vso[task.setvariable variable=NodeModulesAreUpToDate;]true"
          $newHash > $hashPath
          Write-Host ("Hash File saved to " + $hashPath)
        } else {
          # files are the same
          Write-Host "no need to install node_modules"
        }
      } else {
        $newHash > $hashPath
        Write-Host ("Hash File saved to " + $hashPath)
      }
      
      $storedHash = Get-Content $hashPath
      Write-Host $storedHash
    workingDirectory: '$(System.DefaultWorkingDirectory)/cache-npm'

- script: npm install
  workingDirectory: '$(Build.SourcesDirectory)/cache-npm'
  condition: ne(variables['NodeModulesAreUpToDate'],true)
,

git clean -ffdx将清除源代码中源代码管理未跟踪的所有更改。您可以尝试使用Pipeline caching,它可以通过允许一次运行的输出或下载的依赖项在以后的运行中重新使用来帮助减少构建时间,从而减少或避免再次创建或重新下载相同文件的成本。检查以下链接:

https://docs.microsoft.com/en-us/azure/devops/pipelines/release/caching?view=azure-devops#nodejsnpm

variables:
  npm_config_cache: $(Pipeline.Workspace)/.npm

steps:
- task: Cache@2
  inputs:
    key: 'npm | "$(Agent.OS)" | package-lock.json'
    restoreKeys: |
       npm | "$(Agent.OS)"
    path: $(npm_config_cache)
  displayName: Cache npm