【问题标题】:How to get only changed files using Azure devops pipelines如何使用 Azure devops 管道仅获取更改的文件
【发布时间】:2020-12-01 10:06:55
【问题描述】:

我在源代码中有这种文件夹结构。 f1 f2 f3 f4

我在管道中添加了 gitcopy diff 任务,该任务列出并复制修改到目标文件夹的文件。 现在,我希望有一个条件循环作为 powershell 脚本,以仅压缩那些修改了具有特定名称的文件的文件夹,例如,如果 f1 中的文件被修改..我想要执行特定的步骤等等.. 我怎么能做一个循环? 编辑:我以这种方式编写了我的管道。但它在发布步骤中失败,并出现所列错误。

yaml: 触发器:

none

pool:
  vmImage: 'windows-latest'

variables:
  FR1PHPPRDAPP1VFlag: false
  FR1PHPPRDAPP4VFlag: false
  FR1PHPPRDAPP5VFlag: false
  FR1PHPPRDSRE1VFlag: false
  FR1PHPPRDAPP7VFlag: false
  stages:
  -stage: Zipping modified folders
steps:

- powershell: |

      ## get the changed files
      $files=$(git diff HEAD HEAD~ --name-only)
      $temp=$files -split ' '
      $count=$temp.Length
      echo "Total changed $count files"
      For ($i=0; $i -lt $temp.Length; $i++)
        {
          
          $name=$temp[$i]
          echo "this is $name file"
          if ($name -like 'FR1PHPPRDAPP1V/*') 
          {
            cd $(Build.ArtifactStagingDirectory)
            mkdir Output -force
           
          Compress-Archive -Path $(system.defaultworkingdirectory)/FR1PHPPRDAPP1V -DestinationPath $(Build.ArtifactStagingDirectory)/Output/APP1V.zip
          
          ##set the flag variable FR1PHPPRDAPP1VFlag to true
          Write-Host "##vso[task.setvariable variable=FR1PHPPRDAPP1VFlag]true"
          }
          if ($name -like 'FR1PHPPRDAPP4V/*')
          {
            cd $(Build.ArtifactStagingDirectory)
            mkdir Output -force
            ##achive folder FR1PHPPRDAPP4V if it is changed.
          Compress-Archive -Path $(system.defaultworkingdirectory)/FR1PHPPRDAPP4V -DestinationPath $(Build.ArtifactStagingDirectory)/Output/APP4V.zip
          ##set the flag variable FR1PHPPRDAPP4VFlag to true
          Write-Host "##vso[task.setvariable variable=FR1PHPPRDAPP4VFlag]True"
          }
           if ($name -like 'FR1PHPPRDAPP5V/*')
          {
            cd $(Build.ArtifactStagingDirectory)
            mkdir Output -force
            ##achive folder FR1PHPPRDAPP5V if it is changed.
          Compress-Archive -Path $(system.defaultworkingdirectory)/FR1PHPPRDAPP5V -DestinationPath $(Build.ArtifactStagingDirectory)/Output/APP5V.zip
          ##set the flag variable FR1PHPPRDAPP5VFlag to true
          Write-Host "##vso[task.setvariable variable=FR1PHPPRDAPP5VFlag]True"
          }
            if ($name -like 'FR1PHPPRDSRE1V/*')
          {
            cd $(Build.ArtifactStagingDirectory)
            mkdir Output -force
            ##achive folder FR1PHPPRDSRE1V if it is changed.
          Compress-Archive -Path $(system.defaultworkingdirectory)/FR1PHPPRDSRE1V -DestinationPath $(Build.ArtifactStagingDirectory)/Output/SRE1V.zip
          ##set the flag variable FR1PHPPRDSRE1VFlag to true
          Write-Host "##vso[task.setvariable variable=FR1PHPPRDSRE1VFlag]True"
          }
            if ($name -like 'FR1PHPPRDAPP7V/*')
          {
            cd $(Build.ArtifactStagingDirectory)
            mkdir Output -force
            ##achive folder FR1PHPPRDAPP7V if it is changed.
          Compress-Archive -Path $(system.defaultworkingdirectory)/FR1PHPPRDAPP7V -DestinationPath $(Build.ArtifactStagingDirectory)/Output/APP7V.zip
          ##set the flag variable FR1PHPPRDAPP7VFlag to true
          Write-Host "##vso[task.setvariable variable=FR1PHPPRDAPP7VFlag]True"
          }
        }
- task: PublishBuildArtifacts@1
  inputs:
    PathtoPublish: '$(Build.ArtifactStagingDirectory)/Output'
    ArtifactName: 'scripts-f2p'
    publishLocation: 'Container'
  condition: and(succeeded(), or(eq(variables.FR1PHPPRDAPP1VFlag, true),eq(variables.FR1PHPPRDAPP4VFlag, true),eq(variables.FR1PHPPRDAPP5VFlag, true),eq(variables.FR1PHPPRDSRE1VFlag, true),eq(variables.FR1PHPPRDAPP7VFlag, true)))

【问题讨论】:

    标签: azure-devops azure-pipelines pipeline


    【解决方案1】:

    你可以直接在powershell任务中运行git commands下面查看修改过的文件。它比 Rest api 容易得多。

    git diff-tree --no-commit-id --name-only -r $(Build.SourceVersion)

    当你得到更改的文件时,你可以使用Compress-Archive命令直接在powershell任务中使用zip更改的文件夹:见下面的例子:

    Compress-Archive -Path C:\f1 -DestinationPath f1.zip

    如果您希望根据更改的文件夹执行某些特定步骤。您可以定义标志变量并在 powershell 脚本中使用logging commands 将标志设置为true。然后使用condtions 进行以下步骤。

    请参阅下面的完整示例脚本:

    ##set flag variables to indicate if the folder is changed.
    
    variables:
      f1Flag: false
      f2Flag: false
      f3Flag: false
      
    steps:
    
    - powershell: |
          ## get the changed files
          $files=$(git diff-tree --no-commit-id --name-only -r $(Build.SourceVersion))
          $temp=$files -split ' '
          $count=$temp.Length
          echo "Total changed $count files"
         
          For ($i=0; $i -lt $temp.Length; $i++)
          {
            $name=$temp[$i]
            echo "this is $name file"
            if ($name -like 'f1/*')  #if f1 is a subfolder under a folder use "- like '*/f1/*'"
            { 
              ##achive folder f1 if it is changed.
              ##Compress-Archive -Path $(system.defaultworkingdirectory)/f1 -DestinationPath $(Build.ArtifactStagingDirectory)/f1.zip
              
              ##set the flag variable f1Flag to true
              Write-Host "##vso[task.setvariable variable=f2Flag]true"
            }
            if ($name -like 'f2/*')
            {
              ##achive folder f2 if it is changed.
              ##Compress-Archive -Path $(system.defaultworkingdirectory)/f2 -DestinationPath $(Build.ArtifactStagingDirectory)/f2.zip
              ##set the flag variable f2Flag to true
              Write-Host "##vso[task.setvariable variable=f2Flag]True"
            }
          }
          ## create a temp folder to hold the changed files
          New-Item -ItemType directory -Path $(system.defaultworkingdirectory)\temp
    
          foreach($file in $temp){
            if(Test-Path -path $file){
            Copy-Item -Path $file -Destination $(system.defaultworkingdirectory)\temp
            }
          }
          ## zip the temp folder which only have the changed files
          Compress-Archive -Path $(system.defaultworkingdirectory)\temp\* -DestinationPath $(Build.ArtifactStagingDirectory)\changedfiles.zip
    

    然后您可以将条件用于某些特定步骤,就像 Krzysztof 提到的那样

    condition: and(succeeded(), or(eq(variables.f1Flag, true),eq(variables.f2Flag, true),eq(variables.f3Flag, true)))

    更多信息请查看this thread的回复。

    更新:

    steps:
    
    - powershell: |
         #get the changed files
         ....
    
            
    - task: PublishBuildArtifacts@1
      inputs:
         PathtoPublish: '$(Build.ArtifactStagingDirectory)/Output'
         ArtifactName: 'drop'
         publishLocation: 'Container'
      condtion: and(succeeded(), or(eq(variables.f1Flag, true),eq(variables.f2Flag, true),eq(variables.f3Flag, true)))
       
    

    【讨论】:

    • 嗨,你能检查我的编辑吗?我已经对管道进行了更改。现在它在条件语句中失败了
    • @priya 您必须在stages 部分下使用stage。您可以使用条件进行步骤。无需使用舞台。见上面的更新
    • @priya 进展如何?成功了吗?
    • @priya 您可以使用or 表达式。见上文更新。更多信息请查看here
    • 这看起来只有在每次推送都执行一次提交时才有效,否则 build.sourceversion 只是被推送的提交之一。有没有人想出一种方法来处理多提交推送?
    【解决方案2】:

    没有什么开箱即用的解决方案。但是您可以使用 REST API Commits - Get Changes 调用来检查:

    GET https://dev.azure.com/fabrikam/_apis/git/repositories/278d5cd2-584d-4b63-824a-2ba458937249/commits/be67f8871a4d2c75f13a51c1d3c30ac0d74d4ef4/changes?top=2&skip=10&api-version=5.0

    {
      "changeCounts": {
        "Add": 456
      },
      "changes": [
        {
          "item": {
            "gitObjectType": "blob",
            "path": "/MyWebSite/MyWebSite/favicon.ico",
            "url": "https://dev.azure.com/fabrikam/_apis/git/repositories/278d5cd2-584d-4b63-824a-2ba458937249/items/MyWebSite/MyWebSite/favicon.ico?versionType=Commit"
          },
          "changeType": "add"
        },
        {
          "item": {
            "gitObjectType": "tree",
            "path": "/MyWebSite/MyWebSite/fonts",
            "isFolder": true,
            "url": "https://dev.azure.com/fabrikam/_apis/git/repositories/278d5cd2-584d-4b63-824a-2ba458937249/items/MyWebSite/MyWebSite/fonts?versionType=Commit"
          },
          "changeType": "add"
        }
      ]
    }
    

    如果您使用 gitcopy diff task 并且您没有展平目标文件夹,您应该使用命令行 - powershell/bashh - 并基于此设置变量来分析您的目标文件夹。

    $f1Changed = ((Get-ChildItem -Path .\destination\f1\ | Measure-Object).Count -gt 0)
    

    然后您可以分析此响应并检查更改的内容。基于此,您可以使用logging command 设置变量:

    Write-Host "##vso[task.setvariable variable=f1changed;]$f1Changed"
    

    然后在您的步骤中使用此变量在此处压缩此特定文件夹。

     condition: and(succeeded(), eq(variables.f1changed, true))
    

    【讨论】:

    • 我正在为此目的使用 git copy diff 任务..现在我有更改的文件。但是我想对可以成为任何文件夹的一部分的更改文件执行 zip 操作..你可以请重新审视我的问题..我已经编辑了它
    • 请检查我的编辑。我在那里添加了powershell脚本来检查destination/f1文件夹中是否有文件,然后在日志命令中使用它。
    • @krzystof 您好,感谢您的建议...您能检查我的编辑吗?我不需要压缩整个文件夹..我只需要将更改的文件压缩到目标文件夹中..你能建议任何更改吗?
    • 那么在这种情况下,请在复制刚刚修改的文件时压缩您的目标文件夹。我错过了你想复制刚刚修改过的文件的那部分。
    • 我这里没有使用复制差异任务..使用powershell任务通过git diff命令获取修改后的文件。在这里查看stackoverflow.com/q/65088433/13460189
    猜你喜欢
    • 2020-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-09
    • 2022-10-14
    • 1970-01-01
    • 2020-12-08
    相关资源
    最近更新 更多