Home > OS >  Azure DevOps Pipeline - Get modified or added files only
Azure DevOps Pipeline - Get modified or added files only

Time:06-02

I have an Azure DevOps pipeline that executes a Powershell task to create artifacts for each changed file after a pull request is submitted. However, I am not able to return modified/new files in order to create these artifacts. When I test locally I have no problem grabbing the modified file name, but within the pipeline itself the returned result is blank/empty:

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

Full .yml Code:

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

Update: I switched my diff command to the following: git diff --name-only --relative --diff-filter=AM HEAD^ HEAD and confirmed my pipeline now works as expected.

CodePudding user response:

The reason this is happening is because you are running the pipeline against master after the Pull Request is completed. At that moment the pipeline is comparing master with origin/master and they are always equal, so the diff will not find anything.

An alternative way to do the diff is to compare your HEAD commit with it's first parent commit, like this:

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

Comparing these 2 commits will only work if your PRs are completed using Merge, Semi-Linear Merge, or Squash Merge.

If you use a rebase and fast-forward PR completion strategy, you won't know from looking at the branch history how many commits are "new", so you'll need to store the commit ID you were on the last time you ran the pipeline as the starting point.

Side Note: if multiple PRs can be completed between pipeline runs, then it's possible you'll miss some changes. Some ways to overcome this are to queue up pipeline runs such that each run happens against a specific commit and no completed PR is skipped, or to save off the last commit ID that the pipeline was run against, as described for a rebase and fast-forward completion strategy.

  • Related