Jun 16, 2015

Accessing TeamCity REST API from powershell

devops, powershell, teamcity

Just a quick post on accessing TeamCity REST API from PowerShell. Why would you want top do this? Well in this particular eample I will be using PowerShell to access the build change list from TeamCity. One would think that it is something trivial (and it really isn’t too complex) that would be available out of the box but it isn’t.

First how can we call the REST API from PowerShell? It turns out that is quite simple:

    [xml]$changes = Invoke-WebRequest -Uri http://teamcity:8080/guestAuth/app/rest/changes?locator=build`:(id`:12345) -UseBasicParsing

This will load the changes response into an XML document. From here you can look trough each change and load the change details. This will contain a comments node which is the check-in comments the developer provided with the commit.

The TeamCity locator string can also include other parameters which are documented here. The documentation is unfortunately not comprehensive and I could not find a way to get a list of changes from the last pinned build. I think this might require an extra call to find the build id for the last pinned build and provide a range in the locator string. Homework for you the reader. ;)

Below is a more complete example of how to get the changes for one build. This will include all the comments for the commits since the previous build. It would probably be more useful to include all the changes from the previously pinned build.

function Get-ChangeLog {
  param(
    [string] $server   = "",
    [string] $port     = "8080",
    [string] $buildId  = "0"
  )

  if($buildId -ne 0) {
    $changeList = {@()}.Invoke()
    $baseUrl   = "http://$server`:$port"
    $changesUrl = "$baseUrl/guestAuth/app/rest/changes?locator=build`:(id`:$buildId)"

    [xml] $changesDoc = Invoke-WebRequest -Uri $changesUrl -UseBasicParsing
    $changesDoc.SelectNodes("//changes/change") | % {

      $changeUrl = "$baseUrl$($_.href)"
      [xml] $changeDoc = Invoke-WebRequest -Uri $changeUrl -UseBasicParsing
      $changeList.Add(" * $($changeDoc.change.comment)")
    }

    $changeList
  } else {
    @(" * Change list is not available")
  }
}

I hope this gets you started adding some cool features to your builds. Hopefully I will find the time and cover some of the deployment side scripts I have built using psake there are some cool features I would like to talk about.