Last week I was busy with some work on a vNext Release template. When my release worked I wanted to trigger that release from my build definition. Where as in the agent-based Release Management it was a matter of checking a checkbox and using a different Build Template that triggers this release, in the vNext way it is significantly different.
vNext does not use the “mechanism” from the old Release Templates, but uses a REST API call instead. All fine, but there is not much documented on this stuff yet. Only Anand Gaurev from Microsoft describes how to do it on his blog. He also provides a nice PowerShell that you can use.
In short, you use the Default Build Template to build the application, and the use the Post-Build PowerShell script to trigger Release Management. This PowerShell uses the REST API from Release Management.
When I implemented the script in my Build template and started my build my build failed with the following exception
Exception Message: TF270015: 'InitiateReleaseFromBuild.ps1' returned an
unexpected exit code. Expected '0'; actual '1'.
When I dove into the diagnostics I saw that the actual error was a HTTP 401 Unauthorized. I looked into the PowerShell provided by the MSDN blog post and saw this line.
The username,password and domain were hardcoded. I created a Powershell that had these as a parameter and put this in the build definition.
Then I ran again, Now I received a HTTP Error 500. Internal Server Error. The build diagnostic log did not clear things up and I started my search. I landed on this great post by Jakob Ehn about how to trigger Release Management from Team City. Jakob’s post describes how to trigger RM from a UNC Path. I wanted to trigger from the build drop and that meant I had to follow the MSDN post and the REST API. But, since he is also an ALM MVP we had some contact and he gave me some good pointers that directed me to the solution.
First I tried to find the real error. The diagnostic log gave me nothing, so I tried to make the call directly from PowerShell. Because the script from the MSDN blog uses the TFS Build variables for TFS Uri and Build Definition (more here) I could not execute it right away.
I created Powershell variables for this as well and made some checks that the script uses either the build variables or the arguments from commandline.
param ( [string]$rmserver = $Args[0], [string]$port = $Args[1], [string]$teamProject = $Args[2], [string]$targetStageName = $Args[3], [string]$rmusername = $Args[4], [string]$rmpassword = $Args[5], [string]$rmdomain = $Args[6], [string]$teamFoundationServerUrl = $Args[7], [string]$buildDefinition = $Args[8], [string]$buildNumber = $Args[9] ) Write-Host "teamFoundationServerUrl $teamFoundationServerUrl" Write-Host "buildDefinition $buildDefinition" Write-Host "buildNumber $buildNumber" if(-not([string]::IsNullOrEmpty($env:TF_BUILD_COLLECTIONURI))) { Write-Host "Setting Build Collection URI to: $env:TF_BUILD_COLLECTIONURI" Set-Variable -Name teamFoundationServerUrl –Value
$env:TF_BUILD_COLLECTIONURI } if(-not([string]::IsNullOrEmpty($env:TF_BUILD_BUILDDEFINITIONNAME))) { Write-Host "Setting buildDefinition to: $env:TF_BUILD_BUILDDEFINITIONNAME" Set-Variable -Name buildDefinition –Value
$env:TF_BUILD_BUILDDEFINITIONNAME } if(-not([string]::IsNullOrEmpty($env:TF_BUILD_BUILDNUMBER))) { Write-Host "Setting buildNumber to: $env:TF_BUILD_BUILDNUMBER" Set-Variable -Name buildNumber -Value $env:TF_BUILD_BUILDNUMBER }
You can find the renewed Powershell here.
When I did this I received the same message in Powershell. But by using Fiddler I saw what happened! TFS Build called Release Management with the wrong URL.
{"Message":"An error has occurred.","ExceptionMessage":"The TFS collection
(http://localhost:8080/tfs/DefaultCollection) does not exist in the Release
Management Server.","
That’s strange. What happens here. Build calls RM by using localhost. Why? When I looked at the TFS Management Console and navigated to the Application Tier Tab, I saw that the server URL was pointing to “localhost”. I changed the URL by pressing the button and let it point to my server name.
After restarting the build, I received the same message. It seemed that my Build Service was also pointing to localhost, so I changed that too.
When restarting again I got another error in my build output. Cannot index into a null array.
Grumble… What happened here? when executing the Powershell from Powershell it runs… TFS Build wraps the powershell call and call it from command line. There is the caveat. The parameters are not received. So I changed my build definition and added 3 empty string for the 3 optional parameters.
After this it worked !
Another option
Later I realized that I did not have to change the Server URL in the admin console. What is also possible is to register localhost as a TFS in Release Management.
In RM I navigated to Administration | Manage TFS and added localhost
I walked into a slight issue, that my user was not allowed to make calls on behalf of others but fortunately Roopesh Nair has described this in his blog post. Also Martin Hinshelwood has a nice solution post
After that and changing back the server url to localhost it worked like a charm !
Hope this helps !
PS: Thanks again Jakob Ehn !
Resources:
- Trigger a vNext Release from TFS Build
- Trigger a Release from a Team City Build by Jakob Ehn
- Build variables you can use in your PowerShell Script (use as $ENV: BUILD_VAR)
- Trigger a agent based release from build
- Make request on behalf of others. Roopesh Nair and Martin Hinshelwood
- Download new and improved Powershell
Great Post. Very Helpful. Personally, I’m working with SharePoint and require coded ui tests post release. I use vstest to run them. If they fail I copy over deployment script with a revert one and kick off the release again. My only problem is that for some reason, release manager is releasing the last revision instead of the current one. It is very very odd and I dont see why. In release manager it states the correct revision but in the log it states it release the old one. Ex.
WebProject 2.5$(Rev:.r) build number
Build triggered: WebProject 2.5.3
Build that is actually released: WebProject 2.5.2
Have you tried to empty the cache/reboot the server?
Enjoying your posts on RM vNext, I’m having a slightly different problem though. Triggering RM vNext from a TFS 2015 RC vNext build. RM doesn’t show the builds in the drop downs, I could probably get around this using ‘Builds externally’ but it doesn’t seem right. Any ideas?
Unfortunately this is the case. It will be fixed soon..