DevOps: Release Management REST API
Author: jason
Date: 2015-09-08 16:02:42
Category: Technical

Here is a method to kick off a Release Template (deploy a release) via Release Management's REST API. This is for version 2015 of RM. Change the API number for previous versions. This script will grab TFS Project/Build information to pass to the Release Template.

Save the script as a PS1 and run it like:
.\RMRelease.ps1 -releaseTemplate "My Release Template" -componentName "My Component"


Code


param(
[string]$rmServer, # OK to be empty
[string]$rmUser, # Safe to ignore, Used only with code changes below
[string]$rmPassword, # Safe to ignore, Used only with code changes below
[string]$rmDomain, # Safe to ignore, Used only with code changes below
[string]$tfsServer, # OK to be empty, Value comes from RM's Database ID for TFS
[string]$releaseTemplate, # Needs to be KNOWN, not yet coded for auto get from RM
[string]$componentName, # Needs to be KNOWN, not yet coded for auto get from RM
[string]$targetStageId, # Removed from the RM URI Get
[string]$projectName, # OK to be empty, coded for auto get from TFS
[string]$buildDefinition, # OK to be empty, coded for auto get from TFS
[string]$waitForStatus # OK to be empty, unless Yes, then script will wait for the Release Status
)


# --------------------------------------------------------------
# Created: 8/31/2015 JFrance
# Updated:
#
# This PowerShell script is for kicking off a Release from Release Management
# Yes, that can be done via the RM Client GUI, but not scheduled via the GUI
# This script can be scheduled with Task Scheduler
#

<# --More info
Manual Usage, must have a Release Template Name and a Component Name
.RMRelease.ps1 -releaseTemplate "My Release Template" -componentName "My Component"

From Task Scheduler, put the Release Template and Component Name parameters in the argument box
powershell -file "c:somedirrelease.ps1"

Minor adjusts may be needed to the Target Stage ID
Further testing is likely needed with a Release Template with Multiple Components, Release Paths, etc...
This can likely be rewritten with better error/event handling as well, its just mucked together at this point...

Fiddler can be used to see the URL makeup on the machine with RM Client

Alot of this was taken from the following 2 links (and fiddler)
http://blogs.msdn.com/b/visualstudioalm/archive/2014/10/10/trigger-release-from-build-with-release-management-for-visual-studio-2013-update-3.aspx
http://geekswithblogs.net/jakob/archive/2015/01/14/trigger-visual-studio-release-management-vnext-from-teamcity.aspx
#>


# --------------------------------------------------------------
# Incoming Parameters are empty... Set them to something...
if ($rmServer -eq $null -or $rmServer -eq "") {
$rmServer = "mycoolserver:1000";
}
if ($tfsServer -eq $null -or $tfsServer -eq "") {
$tfsServer = "1";
}
if ($releaseTemplate -eq $null -or $releaseTemplate -eq "") {
$releaseTemplate = "My Release Template";
}
if ($componentName -eq $null -or $componentName -eq "") {
$componentName = "My Component Name";
}
if ($targetStageId -eq $null -or $targetStageId -eq "") {
$targetStageId = "0"; # I think this corresponds to the Stage in the Release Path, need fiddler
}
if ($projectName -eq $null -or $projectName -eq "") {
$projectName = "TFS Project Name";
}
if ($buildDefinition -eq $null -or $buildDefinition -eq "") {
$buildDefinition = "TFS Build Definition";
}
if ($waitForStatus -eq $null -or $waitForStatus -eq "") {
$waitForStatus = "No";
}

# --------------------------------------------------------------
# Setup Web Client to get TFS and then RM info
# Switch Default with New Cred if wanting to pass in RMUser
# rmuser should be part rm users list and should have permission to trigger the release.

$wc = New-Object System.Net.WebClient;
$wc.UseDefaultCredentials = $true; # Comment out if passing in New Cred
# $wc.Credentials = new-object System.Net.NetworkCredential("$rmUser", "$rmPassword", "$rmDomain"); # Uncomment if passing in New Cred


# --------------------------------------------------------------
# Getting newest Build Number from TFS

$tfsService = "http://$rmServer/account/releaseManagementService/_apis/releaseManagement/TfsService";
$uri = "$tfsService/GetLatestBuild?tfsServerId=$tfsServer&teamProjectName=" + $projectName + "&buildDefinition=" + $buildDefinition + "&api-version=6.0"
$latestBuild = "";

try
{
[xml]$getXML = $wc.DownloadString($uri)
$latestBuild = $getXML.Build.BuildNumber;
}
catch [System.Exception]
{
if ($exitCode -eq 0) { $exitCode = 1 }
Write-Host "`n$_`n" -ForegroundColor Red
}


# --------------------------------------------------------------
# Build Deployment Bag/String
# If you want these in the Deployment Bag, add them to the HERE string
# Fairly certain not specifying the Stage ID will start on the 1st
# , "Crescendo Web:BuildChangesetRange":"3679,7481"
# , "TargetStageId":"$targetStageId"

$DateTime = Get-Date -format u;
$componentName = $componentName + ":Build";

$deploymentPropertyBag = @"
{"ReleaseName":"$releaseTemplate $DateTime", "ReleaseBuild":"", "ReleaseBuildChangeset":null, "$componentName":"$latestBuild"}
"@

$propertyBag = [System.Uri]::EscapeDataString($deploymentPropertyBag)
$exitCode = 0


trap
{
$e = $error[0].Exception
$e.Message
$e.StackTrace
if ($exitCode -eq 0) { $exitCode = 1 }
}


# Whatever...
$scriptName = $MyInvocation.MyCommand.Name;
$scriptPath = Split-Path -Parent (Get-Variable MyInvocation -Scope Script).Value.MyCommand.Path;
Push-Location $scriptPath;


# --------------------------------------------------------------
# Push out a Release

$orchestratorService = "http://$rmServer/account/releaseManagementService/_apis/releaseManagement/OrchestratorService";
$uri = "$orchestratorService/InitiateRelease?releaseTemplateName=$releaseTemplate&deploymentPropertyBag="+ $propertyBag +"&api-version=6.0"

$status = @{
"2" = "InProgress";
"3" = "Released";
"4" = "Stopped";
"5" = "Rejected";
"6" = "Abandoned";
}



try
{
$releaseId = $wc.UploadString($uri,"")
$url = "$orchestratorService/ReleaseStatus?releaseId=$releaseId"
$releaseStatus = $wc.DownloadString($url)

Write-Host -NoNewline "`nReleasing ..."

# Wait for it...
if ($waitForStatus -eq "Yes") {
while($status[$releaseStatus] -eq "InProgress")
{
Start-Sleep -s 5
$releaseStatus = $wc.DownloadString($url)
Write-Host -NoNewline "."
}
} # end if wait...

" done.`n`nRelease completed with {0} status." -f $status[$releaseStatus]
}
catch [System.Exception]
{
if ($exitCode -eq 0) { $exitCode = 1 }
Write-Host "`n$_`n" -ForegroundColor Red
}






jason @ jasonthomasfrance.com - www.masterstationlog.com - copyright 2009