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
设置管道。在那一刻,管道正在比较 master
和 origin/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 完成策略所述。
我有一个 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
设置管道。在那一刻,管道正在比较 master
和 origin/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 完成策略所述。