Skip to content

Instantly share code, notes, and snippets.

@jsblock78
Last active December 16, 2017 21:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jsblock78/87ddefe3555ee8df28a631153638822e to your computer and use it in GitHub Desktop.
Save jsblock78/87ddefe3555ee8df28a631153638822e to your computer and use it in GitHub Desktop.
This script queues a build in VSTS/TFS, based on the build definition ID or the build definition name and waits until the build completes.
<#
.SYNOPSIS
Queues a build in TFS, and waits until it completes successfully.
.DESCRIPTION
This script queues a build in VSTS/TFS, based on the build definition ID or the build definition name and waits until the build completes.
.INPUTS
No objects can be piped to this script.
.OUTPUTS
System.Management.Automation.PSObject. Returns a PSObject representing details about the build.
.PARAMETER TeamFoundationCollectionUri
The URI of the team foundation collection. For example: https://fabrikamfiber.visualstudio.com/.
.PARAMETER TeamProject
The name of the team project that contains the build to modify.
.PARAMETER DefinitionId
The ID of the build definition.
.PARAMETER DefinitionName
The name of the build definition.
.PARAMETER PersonalAccessToken
The personal access token used to authenticate with TFS/VSTS. If omitted, the script will attempt to use the system OAUTH token or default credentials.
.PARAMETER UseDefaultCredentials
Uses the credentials of the current user to make the request.
.PARAMETER Timeout
The amount of time, in minutes, before the script times out. This defaults to 30 minutes.
.PARAMETER Interval
The amount of time, in seconds, between each request for the status of the build. This defaults to 5 seconds.
.EXAMPLE
# Start a new build for build definition id 42, and return the build information when it completes.
.\Invoke-TfsBuild.ps1 -DefinitionId 42
.EXAMPLE
# Start a new build for the definition named "TestBuild" using a personal access token, and return the build information when it completes.
.\Invoke-TfsBuild.ps1 -DefinitionName TestBuild -PersalAccessToken $personalAccessToken
.NOTES
Author: Jeff Block <jeff.block@nosnitor.net>
About: http://www.rcsit.com/2017/12/16/executing-a-vsts-tfs-build/
Location: https://gist.github.com/jsblock78/87ddefe3555ee8df28a631153638822e
#>
[CmdletBinding()]
Param(
[string] $TeamFoundationCollectionUri = $env:SYSTEM_TEAMFOUNDATIONCOLLECTIONURI,
[string] $TeamProject = $env:SYSTEM_TEAMPROJECT,
[int] $DefinitionId,
[string] $DefinitionName,
[string] $PersonalAccessToken = "",
[switch] $UseDefaultCredentials,
[int] $Timeout = 30,
[int] $Interval = 5
)
# Validate parameters
If ([string]::IsNullOrEmpty($TeamFoundationCollectionUri)) {
Throw "TeamFoundationCollectionUri parameter cannot be null or empty."
}
If ([string]::IsNullOrEmpty($TeamProject)) {
Throw "TeamProject parameter cannot be null or empty."
}
If ((($DefinitionId -eq 0) -and ([string]::IsNullOrEmpty($DefinitionName))) -or (($DefinitionId -gt 0) -and (![string]::IsNullOrEmpty($DefinitionName)))) {
Throw "Either DefinitionId or DefinitionName parameter must be supplied, but not both."
}
If (!([string]::IsNullOrEmpty($PersonalAccessToken)) -and ($UseDefaultCredentials -eq $true)) {
Throw "PersonalAccessToken and UseDefaultCredentials parameters can not both be supplied."
}
Write-Verbose "TeamFoundationCollectionUri : $TeamFoundationCollectionUri"
Write-Verbose "TeamProject : $TeamProject"
$baseUrl = "$TeamFoundationCollectionUri/$TeamProject/_apis"
# Auth
$token = ""
$headers = $null
If (!($UseDefaultCredentials)) {
If (!([string]::IsNullOrEmpty($PersonalAccessToken))) {
Write-Verbose "Using personal access token."
$creds = ":$($PersonalAccessToken)"
$encodedCreds = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($creds))
$token = "Basic $encodedCreds"
$headers = @{Authorization = $token}
}
ElseIf (!([string]::IsNullOrEmpty($env:System_AccessToken))) {
Write-Verbose "Using system access token."
$token = "Bearer $($env:System_AccessToken)"
$headers = @{Authorization = $token}
}
Else {
$UseDefaultCredentials = $true
}
}
Write-Verbose "BaseUrl: [$baseUrl]"
Write-Verbose "Token: [$token]"
If ($DefinitionName) {
Write-Verbose "Definition Name : $DefinitionName"
# Get Definition ID
Try {
$Uri = "$baseUrl/build/definitions?api-version=2.0&name=$DefinitionName"
$response = Invoke-RestMethod -Uri $Uri -Method Get -Headers:$headers -UseDefaultCredentials:$UseDefaultCredentials
if ($response.GetType().Name -eq "String") {
if ($response.Contains("Visual Studio Team Services | Sign In")) {
Throw "Unable to authenticate using supplied authorization."
}
}
If ($response.Count -eq 0)
{
Throw "No build definitions returned."
}
$DefinitionId = $response.value[0].Id
}
Catch {
Write-Host "##vso[task.logissue type=error;]Could not determine build definition ID from name `"$DefinitionName`". $($_.Exception.Message)"
Throw "Could not determine build definition ID from name `"$DefinitionName`". $($_.Exception.Message)"
}
}
Write-Verbose "DefinitionId : $DefinitionId"
If ($DefinitionId -gt 0) {
Try {
$body = @"
{
"definition": {
"id": $DefinitionId
}
}
"@
$buildUrl = "$baseUrl/build/builds`?api-version=2.0"
$response = Invoke-RestMethod -Uri $buildUrl -Method Post -Headers:$headers -UseDefaultCredentials:$UseDefaultCredentials -ContentType application/json -Body $body
if ($response.GetType().Name -eq "String") {
if ($response.Contains("Visual Studio Team Services | Sign In")) {
Throw "Unable to authenticate using supplied authorization."
}
}
$buildId = $response.id
}
Catch {
Write-Host "##vso[task.logissue type=error;]Could not start build with definition ID $DefinitionId."
Throw "Could not start build with definition ID $DefinitionId. $($_.Exception.Message)"
}
Try {
$buildUrl = "$baseUrl/build/builds/$BuildId`?api-version=2.0"
$ts = New-TimeSpan -Minutes $Timeout
$sw = [Diagnostics.Stopwatch]::StartNew()
while ($sw.elapsed -lt $ts) {
$response = Invoke-RestMethod -Method Get -Headers:$headers -UseDefaultCredentials:$UseDefaultCredentials -ContentType application/json -Uri $buildUrl
if ($response.GetType().Name -eq "String") {
if ($response.Contains("Visual Studio Team Services | Sign In")) {
Throw "Unable to authenticate using supplied authorization."
}
}
if ($response.status -eq "completed") {
Write-Verbose "Response:`r`n$response"
if ($response.result -ne "succeeded")
{
Write-Host "##vso[task.logissue type=error;]Build $($response.buildNumber) failed."
Throw "Build $($response.buildNumber) failed."
}
return $response
}
Start-Sleep -Seconds $Interval
}
}
Catch {
Throw "An exception was encountered while checking status of build $buildId. $($_.Exception.Message)"
}
Throw "Timed out waiting for build to complete."
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment