Azure DevOps Pipeline - 仅获取修改或添加的文件

Azure DevOps Pipeline - Get modified or added files only

我有一个 Azure DevOps 管道,它执行 Powershell 任务以在提交拉取请求后为每个更改的文件创建工件。但是,我无法 return modified/new 文件来创建这些工件。当我在本地测试时,我可以毫无问题地获取修改后的文件名,但在管道本身中,returned 结果是 blank/empty:

$changes = git diff --name-only --relative --diff-filter=M origin/master --name-only -- .

完整的 .yml 代码:

trigger:
- master

pool:
  vmImage: windows-latest

jobs:
- job: get_changed_files
  steps:  
   - task: PowerShell@2
     inputs:
       targetType: 'inline'
       script: |
         $targetfolder = "$(Build.StagingDirectory)" + "/"
         
         function CopyFiles{
             param( [string]$source )
         
             $target = $targetfolder + $source
         
             New-Item -Force $target
             copy-item $source $target -Force
         }
         $changes = git diff --name-only --relative --diff-filter=M origin/master --name-only -- .
         write-host "test"
         $changes
         if ($changes -is [string]){ CopyFiles $changes }
         else
         {
             if ($changes -is [array])
             {       
                 foreach ($change in $changes){ CopyFiles $change }
             }
         }
   - task: PublishBuildArtifacts@1
     inputs:
      pathToPublish: $(Build.StagingDirectory)
      artifactName: MyChangedFiles

更新:我将 diff 命令切换为以下内容:git diff --name-only --relative --diff-filter=AM HEAD^ HEAD 并确认我的管道现在按预期工作。

发生这种情况的原因是因为在合并请求完成后,您正在 运行 对 master 设置管道。在那一刻,管道正在比较 masterorigin/master,它们总是相等的,所以 diff 不会找到任何东西。

另一种比较方法是将您的 HEAD 提交与其第一个父提交进行比较,如下所示:

git diff HEAD~1 HEAD
# or using @ syntax for HEAD
git diff @~1 @
# or using merge commit syntax
git diff @^ @

仅当您的 PR 使用 Merge、Semi-Linear Merge 或 Squash Merge 完成时,比较这 2 个提交才有效。

如果你使用 rebase 和 fast-forward PR 完成策略,你不会通过查看 b运行ch 历史知道有多少提交是“新的”,所以你需要存储您上次 运行 管道作为起点的提交 ID。

旁注: 如果多个 PR 可以在流水线 运行 之间完成,那么您可能会错过一些更改。克服这个问题的一些方法是将管道 运行 排队,这样每个 运行 都会针对特定提交发生并且不会跳过任何已完成的 PR,或者保存管道 [=] 的最后一个提交 ID 30=] 反对,如 rebase 和 fast-forward 完成策略所述。