Gerhard Brueckl
Gerhard Brueckl

Reputation: 778

Get changes from all commits in an Azure DevOps YAML pipeline

I am writing a ADO YAML pipeline that does some modifications whenever a file is pushed to the repository. Everything is working fine so far except that I cannot deal with multiple commits in one push. I would need to get a list of all changed files since the last push to the branch from which the push (trigger) initially came from.

Build.SourceVersion only returns the latest commit and I could not find any other built-in variable

There is no PushId which I could use with the REST API (https://learn.microsoft.com/en-us/rest/api/azure/devops/git/commits/get-push-commits?view=azure-devops-rest-6.0)

In Github actions the previous and the latest commit IDs are exposed as variables which i can then use to get the changes since the last push but I could not find anything similar in ADO

Are there any other ways to get this information?

Upvotes: 1

Views: 6220

Answers (3)

Gerhard Brueckl
Gerhard Brueckl

Reputation: 778

thanks to the input from qbik I came up with the following YAML task that gets the GIT Commit ID before and after the push and writes those values to environment variables to be used in the following scripts:

- task: PowerShell@2
  displayName: Get GIT Commit-IDs before and after Push
  inputs:
    targetType: 'inline'
    script: |
      # print Information stream
      $InformationPreference = "Continue"

      $headers = @{ Authorization = "Bearer $env:SYSTEM_ACCESSTOKEN" }
      $uri = "$env:SYSTEM_TEAMFOUNDATIONSERVERURI$env:SYSTEM_TEAMPROJECT/_apis/build/builds/$($env:BUILD_BUILDID)/changes?api-version=5.1"
      $changes = Invoke-RestMethod -Method Get -Headers $headers -Uri $uri -Verbose

      if ($changes.count -gt 0) {
          $commit_id_before = $changes.value[$changes.count - 1].id
          $commit_id_after = $changes.value[0].id

          Write-Information "Commit ID before push: $commit_id_before"
          Write-Information "Commit ID after push:  $commit_id_after"

          Write-Host "##vso[task.setvariable variable=GIT_EVENT_BEFORE]$commit_id_before"
          Write-Host "##vso[task.setvariable variable=GIT_EVENT_AFTER]$commit_id_after"
      }
      else {
        Write-Warning "No changes found in Build $buildId"
      }
    pwsh: true
  env:
    SYSTEM_ACCESSTOKEN: $(System.AccessToken)

Upvotes: 2

qbik
qbik

Reputation: 5928

There's a method in DevOps API that will get all the changes associated with a specific build.

Here's a snippet from a script that I'm using for a similar purpose:

$changes = Invoke-RestMethod -Method Get -Headers $headers "https://dev.azure.com/$organization/$project/_apis/build/builds/$buildId/changes?api-version=5.1" -verbose

$changedPaths = @()
if ($changes.count -gt 0) {
    $commitId = $changes.value[$changes.value.length - 1].id
    write-verbose "first change: $commitId" -Verbose

    $commitId = $changes.value[$changes.value.length - 1].id
    $head = $changes.value[0].id
    
    $changedPaths = git diff "$($commitId)~1" $head --name-only
}

Upvotes: 2

Romain Valeri
Romain Valeri

Reputation: 22047

Something along the lines of

git log --pretty=format:"" --name-only <oldCommitHash>..<newCommitHash> | sort -u

it will find all commits between the last push and the current one, output the list of changed files for each (--pretty=format:"" is here to prevent commit metadata output, and --name-only to turn the diff into a mere list of changed files), and sort -u will help reordering and getting rid of doubles / whitespace.

Upvotes: 1

Related Questions