Доступны ли значения возможностей пользователя агента сборки TFS на этапах сборки?
Я пытаюсь написать шаг сборки в TFS, основанный на знании, где хранится агент Build nuget.exe (стандартный шаг установки nuget изменяет порядок аргументов таким образом, что нарушает выполнение сборки, поэтому я хочу сам запускаю exe, используя один из шагов batch/shell/ ps).
Может показаться, что установка возможности для Агента сборки с этим путем имела бы смысл, но я не могу ссылаться на значение на любом из моих этапов сборки, и я не могу найти ничего полезного в MSDN.
Я ожидаю, что это будет что-то вроде $(Env.MyUserCapability)
, но это никогда не разрешается до значения.
Можно ли получить значение возможности на этапе сборки? И если да, то как ты это делаешь? И если нет, что является жизнеспособной альтернативой?
2 ответа
Пользовательские возможности являются только метаданными. Но вы можете установить глобальную переменную среды (например, NUGET
) и установите это путь к nuget.exe
Когда вы перезапускаете агент, среда всей машины затем обнаруживается как возможность, и вы можете использовать ее.
Если вы пишете пользовательское задание, вы также можете добавить nuget.exe
к задаче, которая будет загружена в исполняющий агент.
В TFS 2018u1 работает следующее:
Import-Module "Microsoft.TeamFoundation.DistributedTask.Task.Common"
Import-Module "Microsoft.TeamFoundation.DistributedTask.Task.Internal"
Add-Type -Assembly "Microsoft.TeamFoundation.DistributedTask.WebApi"
$VSS = Get-VssConnection -TaskContext $distributedTaskContext
$AgentCli = $VSS.GetClient([Microsoft.TeamFoundation.DistributedTask.WebApi.TaskAgentHttpClient])
$AgentConfig = Get-Content "$Env:AGENT_HOMEDIRECTORY\.agent" -Raw | ConvertFrom-Json
$Agent = $AgentCli.GetAgentAsync($AgentConfig.PoolId, $Env:AGENT_ID, $TRUE, $FALSE, $NULL, $NULL, [System.Threading.CancellationToken]::None).GetAwaiter().GetResult()
if($Agent.UserCapabilities.MyCapability)
{
Write-Host "Got the capability!";
}
Длинная строка аргументов по умолчанию, заканчивающаяся на CancellationToken::None
для совместимости с Powershell 4. PS4 не поддерживает значения по умолчанию для параметров метода с типизированным значением, PS5 поддерживает.
Этот фрагмент делает что-то очень сомнительное - он зависит от местоположения и структуры файла конфигурации агента. Это хрупко Проблема в том, что GetAgentAsync
Для этого метода требуются и идентификатор пула, и идентификатор агента, а первый не отображается в переменных среды. Немного менее хакерский подход проверит все пулы и найдет правильный по идентификатору агента:
$Pools = $AgentCli.GetAgentPoolsAsync($NULL, $NULL, $NULL, $NULL, $NULL, [System.Threading.CancellationToken]::None).GetAwaiter().GetResult()
$Demands = New-Object 'System.Collections.Generic.List[string]'
foreach($Pool in $Pools)
{
$Agent = $AgentCli.GetAgentsAsync($Pool.ID, $Env:AGENT_NAME, $TRUE, $FALSE, $NULL, $Demands, $NULL, [System.Threading.CancellationToken]::None).Result
if($Agent -and $Agent.Id -eq $Env:AGENT_ID)
{
Break
}
}
Это зависит от еще одной недокументированной детали реализации, а именно от того, что идентификаторы агентов являются глобально уникальными. Кажется, это относится к TFS 2018, но кто знает.
Когда вы используете $distributedTaskContext
задание подключается обратно к TFS с искусственным удостоверением пользователя "Служба сборки коллекции проектов" (не с учетной записью службы агента). В каждой коллекции один такой пользователь, они разные. Чтобы задачи, выполняемые в выпусках в коллекции, могли запрашивать у агента возможности пользователя, необходимо предоставить роль "Читатель" соответствующим пулам (или всем пулам) учетной записи пользователя с именем "Служба построения коллекции проектов (TheCollectionName").) "из этой коллекции.
Также похоже, что некоторые действия также предоставляют неявную роль Reader в пуле для идентификации задачи.
Кроме того, вы можете построить VssConnection
с нуля, используя учетные данные Windows, и предоставьте роль считывателя учетных записей агентов в пуле (ах).