Не удается получить доступ к переменной ArtifactStagingDirectory в MSBuild

В процессе сборки я пытаюсь скопировать папку в папку артефактов (\myserver\d$\TFBuild-Agent01\66\a).

Поэтому я поместил это в файл.csproj:

  <Target Name="BeforeBuild">
    <Exec 
     Command="xcopy.exe  Databases &quot;$(Build.ArtifactStagingDirectory)\Databases&quot; /i /e /y /d" />
  </Target>

Это получает меня

ошибка MSB4184: выражение """.ArtifactStagingDirectory" не может быть оценено. Метод 'System.String.ArtifactStagingDirectory' не найден

Все, что я могу найти в Интернете, говорит о том, что $(Build.ArtifactStagingDirectory) - это способ сделать это. Но это не работает.

Сборка с Visual Studio 2015 на TFS 2015

Это тоже не работает:

<Exec 
Command="xcopy.exe  Databases &quot;$($Env:BUILD_ARTIFACTSTAGINGDIRECTORY)\Databases&quot; /i /e /y /d" />

Выражение "$Env:BUILD_ARTIFACTSTAGINGDIRECTORY" не может быть оценено.

Это не ошибка, но похоже, что%BUILD_ARTIFACTSTAGINGDIRECTORY% заменяется пустой строкой:

 <Exec Command="xcopy.exe  Databases &quot;%BUILD_ARTIFACTSTAGINGDIRECTORY%\Databases&quot; /i /e /y /d" /> 

2 ответа

Решение

Вы смешивали способы доступа к переменным сборки, которые позволяет вам агент. Синтаксис с использованием $(some.variable) интерпретируется самим агентом. MSBuild имеет похожий синтаксис - $(PropertyName) - который делает что-то другое - он дает доступ к свойствам msbuild и не допускает точек (.) в его названии, поскольку вы можете использовать точку для вызова функций со значением (например, $(OutputPath.Substring(3))).

Если вы хотите сослаться на переменные сборки из MSBuild, вам нужно сослаться на переменную среды, которую устанавливает агент. Это возможно, потому что MSBuild делает все переменные среды доступными как глобальные свойства, используя синтаксис своего свойства. Переменная среды для Build.ArtifactStagingDirectory является BUILD_ARTIFACTSTAGINGDIRECTORY так что вы можете использовать его в MSBuild, используя $(BUILD_ARTIFACTSTAGINGDIRECTORY),

Я успешно использовал его в этом сценарии для установки свойства по умолчанию при запуске как часть сборки TFS/VSTS (PublishBaseDir это пользовательское свойство, используемое позже):

<PropertyGroup>
  <!-- Default artifact staging directory when built via VSTS / TFS agent -->
  <PublishBaseDir Condition="'$(PublishBaseDir)' == '' and '$(BUILD_ARTIFACTSTAGINGDIRECTORY)' != '' ">$(BUILD_ARTIFACTSTAGINGDIRECTORY)</PublishBaseDir>

  <!-- If not built on a known agent, use a "publish" subdir next to this file -->
  <PublishBaseDir Condition="'$(PublishBaseDir)' == ''">$(MSBuildThisFileDirectory)publish\</PublishBaseDir>

  <!-- Normalize directory if set manually or through ENV var -->
  <PublishBaseDir Condition="!HasTrailingSlash('$(PublishBaseDir)')">$(PublishBaseDir)\</PublishBaseDir>
</PropertyGroup>

Хорошо, я предполагаю, что, поскольку я использую Visual Studio для построения своего решения, я не могу получить доступ к $(Build.StagingDirectory) из.csproj. Однако он передается в командной строке шагу сборки Visual Studio Build как свойство:

/p:OutDir="$(Build.StagingDirectory)"

Так что это можно сделать, выполнив

<Exec Command="xcopy.exe  Databases &quot;$(OutDir)\Databases&quot; /i /e /y /d" />
Другие вопросы по тегам