如何使用 Azure DevOps 管道仅获取更改的文件 [英] How to get only changed files using Azure devops pipelines

查看:90
本文介绍了如何使用 Azure DevOps 管道仅获取更改的文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在源代码中有这样的文件夹结构.f1f2f3f4

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

yaml:触发:

无水池:vmImage: 'windows-最新'变量:FR1PHPPRDAPP1VFlag: 假FR1PHPPRDAPP4VFlag: 假FR1PHPPRDAPP5VFlag: 假FR1PHPPRDSRE1VFlag: 假FR1PHPPRDAPP7VFlag: 假阶段:-stage:压缩修改过的文件夹脚步:- 电源外壳:|##获取修改后的文件$files=$(git diff HEAD HEAD~ --name-only)$temp=$files -split ' '$count=$temp.Lengthecho "Total Changed $count files";对于 ($i=0; $i -lt $temp.Length; $i++){$name=$temp[$i]echo "这是 $name 文件";if ($name -like 'FR1PHPPRDAPP1V/*'){cd $(Build.ArtifactStagingDirectory)mkdir 输出 -force压缩归档 -Path $(system.defaultworkingdirectory)/FR1PHPPRDAPP1V -DestinationPath $(Build.ArtifactStagingDirectory)/Output/APP1V.zip##设置标志变量FR1PHPPRDAPP1VFlag为true写主机##vso[task.setvariable variable=FR1PHPPRDAPP1VFlag]true"}if ($name -like 'FR1PHPPRDAPP4V/*'){cd $(Build.ArtifactStagingDirectory)mkdir 输出 -force##achive 文件夹 FR1PHPPRDAPP4V 如果更改.压缩归档 -Path $(system.defaultworkingdirectory)/FR1PHPPRDAPP4V -DestinationPath $(Build.ArtifactStagingDirectory)/Output/APP4V.zip##设置标志变量FR1PHPPRDAPP4VFlag为true写主机##vso[task.setvariable variable=FR1PHPPRDAPP4VFlag]True"}if ($name -like 'FR1PHPPRDAPP5V/*'){cd $(Build.ArtifactStagingDirectory)mkdir 输出 -force##achive 文件夹 FR1PHPPRDAPP5V 如果更改.压缩归档 -Path $(system.defaultworkingdirectory)/FR1PHPPRDAPP5V -DestinationPath $(Build.ArtifactStagingDirectory)/Output/APP5V.zip##设置标志变量FR1PHPPRDAPP5VFlag为true写主机##vso[task.setvariable variable=FR1PHPPRDAPP5VFlag]True"}if ($name -like 'FR1PHPPRDSRE1V/*'){cd $(Build.ArtifactStagingDirectory)mkdir 输出 -force##achive 文件夹 FR1PHPPRDSRE1V 如果更改.压缩归档 -Path $(system.defaultworkingdirectory)/FR1PHPPRDSRE1V -DestinationPath $(Build.ArtifactStagingDirectory)/Output/SRE1V.zip##设置标志变量FR1PHPPRDSRE1VFlag为true写主机##vso[task.setvariable variable=FR1PHPPRDSRE1VFlag]True"}if ($name -like 'FR1PHPPRDAPP7V/*'){cd $(Build.ArtifactStagingDirectory)mkdir 输出 -force##achive 文件夹 FR1PHPPRDAPP7V 如果更改.压缩归档 -Path $(system.defaultworkingdirectory)/FR1PHPPRDAPP7V -DestinationPath $(Build.ArtifactStagingDirectory)/Output/APP7V.zip##设置标志变量FR1PHPPRDAPP7VFlag为true写主机##vso[task.setvariable variable=FR1PHPPRDAPP7VFlag]True"}}- 任务:PublishBuildArtifacts@1输入:PathtoPublish: '$(Build.ArtifactStagingDirectory)/输出'工件名称:'scripts-f2p'发布位置:'容器'条件: and(succeeded(), or(eq(variables.FR1PHPPRDAPP1VFlag, true),eq(variables.FR1PHPPRDAPP4VFlag, true),eq(variables.FR1PHPPRDAPP5VFlag, true),eq(variables.FR1PHPPRDSRE1VFlag, true),eq(variables.FR1PHPPRDAPP5VFlag, true),eq(variables.FR1PHPPRDAPP5VFlag, true)FR1PHPPRDAPP7VFlag,真)))

解决方案

你可以在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 脚本中将标志设置为 true.然后使用 条件 用于以下步骤.

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

##set 标志变量以指示文件夹是否已更改.变量:f1Flag: 假f2Flag: 假f3Flag: 假脚步:- 电源外壳:|##获取修改后的文件$files=$(git diff-tree --no-commit-id --name-only -r $(Build.SourceVersion))$temp=$files -split ' '$count=$temp.Lengthecho "Total Changed $count files";对于 ($i=0; $i -lt $temp.Length; $i++){$name=$temp[$i]echo "这是 $name 文件";if ($name -like 'f1/*') #if f1 是文件夹下的子文件夹 use "-like '*/f1/*'";{##achive 文件夹 f1 如果更改.##Compress-Archive -Path $(system.defaultworkingdirectory)/f1 -DestinationPath $(Build.ArtifactStagingDirectory)/f1.zip##设置标志变量f1Flag为true写主机##vso[task.setvariable variable=f2Flag]true";}if ($name -like 'f2/*'){##achive 文件夹 f2 如果更改.##Compress-Archive -Path $(system.defaultworkingdirectory)/f2 -DestinationPath $(Build.ArtifactStagingDirectory)/f2.zip##设置标志变量f2Flag为true写主机##vso[task.setvariable variable=f2Flag]True"}}## 创建一个临时文件夹来保存更改的文件New-Item -ItemType 目录 -Path $(system.defaultworkingdirectory)\tempforeach($temp 中的 $file){if(Test-Path -path $file){Copy-Item -Path $file -Destination $(system.defaultworkingdirectory)\temp}}## 压缩只有更改过的文件的临时文件夹压缩归档 -Path $(system.defaultworkingdirectory)\temp\* -DestinationPath $(Build.ArtifactStagingDirectory)\changedfiles.zip

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

条件:and(succeeded(), or(eq(variables.f1Flag, true),eq(variables.f2Flag, true),eq(variables.f3Flag, true)))>

查看这个的答案线程了解更多信息.

更新:

步骤:- 电源外壳:|#获取修改后的文件....- 任务:PublishBuildArtifacts@1输入:PathtoPublish: '$(Build.ArtifactStagingDirectory)/输出'工件名称:'掉落'发布位置:'容器'条件:and(succeeded(), or(eq(variables.f1Flag, true),eq(variables.f2Flag, true),eq(variables.f3Flag, true)))

I have folder structure this way in source code. f1 f2 f3 f4

I have added gitcopy diff task in my pipeline which lists and copies files which are modified to a destination folder. Now, I want to have a conditional loop as powershell script to only zip those folders which have modified files with a particular names for example if files from f1 are modified..I want particular steps to be performed and so on.. How can I do it as a loop? edit: I have written my pipeline in this way. But its failing in publish step with errors as listed.

yaml: trigger:

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

解决方案

You can directly run below git commands in the powershell task to check the changed files. It is much easier than Rest api.

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

When you get the changed files, you can use the zip the changed folders directly in the powershell task using Compress-Archive command: See below example:

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

If you want some particular steps to be performed based on the the changed folders. You can define the flag variables and using the logging commands in the powershell scripts to set the flags to true. And then use the condtions for the following steps.

See below full example scripts:

##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

Then you can use the condition for some particular steps just as Krzysztof mentioned

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

See the answer to this thread for more information.

Update:

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

这篇关于如何使用 Azure DevOps 管道仅获取更改的文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆