Доступны ли значения возможностей пользователя агента сборки 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, и предоставьте роль считывателя учетных записей агентов в пуле (ах).

Другие вопросы по тегам