'Is it possible to use a variable in the Agent.Name demand for tfs?

I am trying to force the run of a specific agent phase on a specific agent. My variable however does not seems to be picked up. I get the error:

No agent found in pool TEST which satisfies the specified demands: Agent.Name -equals $(Release.ReleaseName) vstest Agent.Version -gtVersion 2.103.0

Is this possible?

Specifying Agent.Name from a variable



Solution 1:[1]

I wanted to do something similar. I had 2 "environments" in the TFS release definition. The first one ("MyEnvironment-Setup") did setup like big file copies and database script generation. The second ("MyEnvironment") did the actual deployment. I needed them both to run on the same agent.

What I ended up doing is using the TFS API during "MyEnvironment-Setup" to modify the currently running release instance and set the agent demand for "MyEnvironment".

Several things were necessary to make this happen.

  1. In "MyEnvironment-Setup" > Run on Agent > Additional Options, I enabled "Allow scripts to access the OAuth token"
  2. In the left pane of the release definition screen where it lists all release definitions, I clicked the ellipsis next to "All release definitions" and selected "Security". Then for the "Project Collection Build Service (TEAM FOUNDATION)" user, I set "Edit release definition" and "Manage releases" to "Allow".
  3. I called the following Powershell method in "MyEnvironment-Setup"
function Set-FinalAgent() 
{
    # Force the "MyEnvironment" step to run on the same agent as the "MyEnvironment-Setup" step 
    $baseApiUrl = "$($env:SYSTEM_TEAMFOUNDATIONCOLLECTIONURI)$env:SYSTEM_TEAMPROJECTID/_apis"
    $apiVersion = "3.1-preview" 
    $header = @{ Authorization = "Bearer $env:SYSTEM_ACCESSTOKEN" }
    $environmentToModify = $($env:Release_EnvironmentName).Replace("-Setup",  "")

    $releaseID = $env:Release_ReleaseID
    $release = Invoke-RestMethod -Uri "$baseApiUrl/release/releases/$($releaseID)?api-version=$apiVersion" -Method GET -Header $header
    ($release.environments | where name -eq $environmentToModify).deployPhasesSnapshot[0].deploymentInput.demands += "Agent.Name -equals $($env:Agent_Name)"

    # Compression is needed for the body to contain all of the info for larger release definitions when running on older servers
    $body = $release | ConvertTo-Json -Depth 100 -Compress 
    Invoke-RestMethod -Uri "$baseApiUrl/release/releases/$($releaseID)?api-version=$apiVersion" -Method PUT -Header $header -ContentType application/json -Body $body

}

If you want to test and tweak this in Powershell ISE or something where you don't have access to the OAuth token, you can use a personal access token instead. In the top-right of your TFS Web UI, click your profile picture and select "Security" to generate a PAT. Then you can replace the header in the script above with the following:

$header = @{Authorization = 'Basic ' + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$($personalAccessToken)"))}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1