Hello!

I can't quite believe it, but I'm working with TFS-on prem again. Thankfully it is TFS 2017, so there's an awful lot of familiarity as it is basically VSTS from not even two years ago (thanks to updates). And one of those things is the API! I've been needing to get the last good deployment to a specific environment, so that then I can kick off a deployment to another environment. This has to be run from Jenkins (long story).

This has taken a bit of fiddling as you have to get a deployment that is successful to a specific environment rather than a release. HTen you have the version number and you can kick off the pertinent release version/name to the other environment you want to deploy to.

A further complication is that I'm needing to use the ContinuationToken, and what isn't totally clear is that the token will appear as null when there are no more pages to return. This is probably obvious to people who use API's all the time, IDK.

But at any rate, nevertheless, otherwise-than-that, this function below will return the last successful deployment to a given environment for a specific release. There is a slight issue here in that the TFS API I am using (3.2 preview 1) does not have all the optional parameters that are available on TFS 2018, I think. I say this because I am not able to filter on the uri via minStartedTime, and the docs pages only go back as far as TFS 2018, which is a bit rubbish.

Function Get-TfsDeployment {
    [CmdletBinding()]
    param(
        [string]
        [ValidateNotNullOrEmpty()]
        $tfsUrl
        , [string]
        [ValidateNotNullOrEmpty()]
        $releaseName,
        [ValidateNotNullOrEmpty()]
        $releaseEnvironmentName
        , [string]
        $user
        , [string]
        $token
    )
    $base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $user, $token)))
    $uri = $tfsUrl + '/_apis/release/deployments?deploymentStatus=succeeded&maxStartedTime=2016-01-01T00:00:00Z'
    Write-Host $uri
    $Headers = @{}
    try {
            $result = Invoke-WebRequest -Uri $uri -Method GET -ContentType "application/json" -Headers @{Authorization = ("Basic {0}" -f $base64AuthInfo) }
            $Headers = $result.Headers
            $continuationToken = $headers['x-ms-continuationtoken']
            do{
                $ThisUri =  "$($uri)&continuationToken=$($continuationToken)"
                $result = Invoke-WebRequest -Uri $ThisUri -Method GET -ContentType "application/json" -Headers @{Authorization = ("Basic {0}" -f $base64AuthInfo) }
                $Headers = $result.Headers
                $continuationToken = $headers['x-ms-continuationtoken']
            }
            until(
                $null -eq $continuationToken
            )
        $bob = $result | ConvertFrom-Json
        $e = $bob.Value | Where-Object { $_.releaseDefinition.name -eq $releaseName -and $_.releaseEnvironment.name -eq $releaseEnvironmentName }
        $releaseToCheck = $e | Select-Object -First 1
        return $releaseToCheck
    }
    catch {
        Throw $_
    }
}

$_tfsUrl = 'http://mytfsurl:8080/tfs/team/project'
$_releaseName = 'my-super-release'
$_releaseEnvironmentName = 'dev-env'
$_user = 'domain\tfsadmin'
$_token = 'c6ylh4y3wu44e4gjki62it3gwh83174361923229838682'

$myDeployment = Get-TfsDeployment -tfsUrl $_tfsUrl -releaseName $_releaseName -releaseEnvironmentName $_releaseEnvironmentName -user $_user -token $_token

$myDeployment