I always had a lot of problems triggering a release from a build (Vnext or Xaml) on premise if I work with agentless deployments. In the cloud this works like a charm – but on premise it never worked for me. I tried it with the blog post on msdn – but no success.
Today I started to use Fiddler to monitor the api calls that the Release Management Client makes. (BTW: I know now, why the app is so slow if you have limited network bandwidth. The client is really chatty!).
With Fiddler and the Invoke-RestMethod commandlet its quite easy to make the same calls as the client does. If you want to get the id of a releasePath you can execute
$releasePaths = Invoke-RestMethod "$releaseManagementService/ReleaseDefinitionService/ListReleaseDefinitions?api-version=$ApiVersion" -UseDefaultCredentials -Method Post
The result is a XMLDocument that is pretty easy to parse in PowerShell.
$releasePathId = $releasePaths.ApplicationVersionList.ApplicationVersion | ? { $_.Name -eq $ReleasePathName } | % { $_.ReleasePathId }
The most difficult part is to build the property bag for “InitiateRelease”. You can use [URI]::UnescapeDataString() to extract the json from the encoded string.
I’ve build up a script that accepts ReleaseDefinition, ReleasePath and TargetStage as parameters. This is only tested with one solution. You might have to adjust the property bag to your need – especially when you have more components. You can download the script directly from github.
<# .Synopsis Triggers a release from a build for Visual Studio Release Management 2015 on premises .DESCRIPTION Use this script in your builds to trigger a release in Visual Studio Release Management 2015 on premises. .EXAMPLE .\Start-Release.ps1 -ReleaseDefinition MyReleaseDefinition -ReleasePath MyPath -TargetStage Dev .EXAMPLE .\Start-Release.ps1 -ReleaseDefinition MyReleaseDefinition -ReleasePath MyPath #> [CmdletBinding()] [OutputType([int])] Param ( # The name of the release definition [Parameter(Mandatory=$true, Position=0)] [ValidateNotNullOrEmpty()] [string]$ReleaseDefinition, # The name of the release path [Parameter(Mandatory=$true, Position=1)] [ValidateNotNullOrEmpty()] [string]$ReleasePathName, # The build number. This is automatically set by the build. [Parameter(Mandatory=$false, Position=2)] [ValidateNotNullOrEmpty()] [string]$BuildNumber = $env:TF_BUILD_BUILDNUMBER, # The target stage. Adjust the validation set acording to your values # from the Administration / Manage Picklist / Stage Type in RM Client... [Parameter(Mandatory=$false, Position=2)] [ValidateSet("Dev", "Test", "QA", "Prod", "Last")] [string]$TargetStage = "Last", # The api version of the rest api. This might change with later updates. # Use fiddler to check the version that is used by rm client. [string]$ApiVersion = "6.0" ) # Set the name of your release management server and the port (default 1000) $serverName = "<your server fqdn>:1000" $releaseManagementService = "http://$serverName/account/releaseManagementService/_apis/releaseManagement" # Get the ReleasePathId $releasePaths = Invoke-RestMethod "$releaseManagementService/ReleaseDefinitionService/ListReleaseDefinitions?api-version=$ApiVersion" -UseDefaultCredentials -Method Post $releasePathId = $releasePaths.ApplicationVersionList.ApplicationVersion | ? { $_.Name -eq $ReleasePathName } | % { $_.ReleasePathId } # Get the TargetStageId $releasePath = Invoke-RestMethod "$releaseManagementService/ConfigurationService/GetReleasePath?id=$releasePathId&api-version=$ApiVersion" -UseDefaultCredentials -Method Post $stages = $releasePath.ReleasePath.Stages.Stage if ($TargetStage -ne "Last") { $targetStageId = $stages | ? { $_.StageTypeName -eq "Dev" } | % { $_.Id } }else { $targetStageId = $stages | Select-Object -Last 1 | % { $_.Id } } # Create the release name $releaseName = "Release: $(Get-Date -Format G)" # Create the property bag $deploymentPropertyBag = "{""ReleaseName"" : ""$releaseName"",""ReleaseBuild"": ""$BuildNumber"",""ReleaseBuildChangeset"" : """",""TargetStageId"": ""$targetStageId"",""ProviderHostedApp:Build"" : """",""ProviderHostedApp:BuildChangesetRange"" : ""-1,-1""}" $propertyBag = [System.Uri]::EscapeDataString($deploymentPropertyBag) $uri = "$releaseManagementService/OrchestratorService/InitiateRelease?releaseTemplateName=$releaseDefinition&deploymentPropertyBag=$propertyBag&api-version=6.0" $result = Invoke-RestMethod -Uri $uri -Method Post -UseDefaultCredentials if ($result.ErrorMessage) { throw $result.ErrorMessage } return $result