MSBuild: Развертывание файлов, которые не включены в проект

У меня есть событие Pre-build в веб-проекте, которое минимизирует и объединяет файлы JavaScript с помощью узла. Это создает папку с именем BuiltScripts в папке сценариев, которая является дубликатом папки сценариев, за исключением того, что файлы минимизированы. Когда я делаю развертывание, я хочу опубликовать папку сценариев, включая папку BuiltScripts внутри нее. Для этого я добавил в проект папку BuiltScripts. Это не идеальное решение, так как:

  1. Я должен иметь проверенную папку BuiltScripts, чтобы построить, поскольку файлы в ней только для чтения, поскольку решение находится под контролем исходного кода. Это создает неприятности при регистрации, так как у меня есть так много файлов.
  2. Когда я добавляю новый файл в проект, я должен убедиться, что не забываю добавить его в папку BuiltScripts, иначе встроенная версия файла не будет развернута.
  3. Моя сборка завершится неудачно на сервере сборки, так как файлы в папке BuiltScripts также доступны только для чтения.
  4. Наличие двух копий файла с одинаковым именем является проблемой при поиске файлов и выполнении текстового поиска.

Я хотел бы собрать сервер сборки и минимизировать файлы javascript в качестве предварительного этапа сборки, но я не хочу, чтобы папка BuiltScripts была добавлена ​​в проект. Однако когда сервер сборки упаковывает проект в конце, я хочу, чтобы он скопировал папку BuiltScripts с выводом процесса сборки. Как мне этого добиться?

3 ответа

Решение

Вместо использования события предварительной сборки свойств проекта (которое, как мне кажется, вы имеете в виду) переопределите цель BeforeBuild в файле.csproj/.vbproj.

<Project ...>
  ...
  <Target Name="BeforeBuild">
    <!-- Create the 'BuildScripts' directory. -->
    <!-- The $(IntermediateOutputPath) reference the 'obj' folder, which I like to -->
    <!-- use for these kinds of things. -->
    <MakeDir Directories="$(IntermediateOutputPath)BuiltScripts">
      <Output PropertyName="BuildScriptsPath" TaskParameter="DirectoriesCreated" />
    </MakeDir>
    <!-- Execute the javascript minifier. -->
    <Exec Command="..." />
    <!-- Create an item group for the minified scripts so we manipulate the target path. -->
    <CreateItem Include="$(BuildScriptsPath)\*.js">
      <Output ItemName="BuiltScripts" TaskParameter="Include" />
      <Output ItemName="FileWrites" TaskParameter="Include" />
    </CreateItem>
    <!-- Add the minified scripts to the Content item group, -->
    <!-- which the deployment MSBuild inspects for files to deploy. -->
    <CreateItem Include="@(BuiltScripts)"
      AdditionalMetadata="TargetPath=scripts\%(Filename)%(Extension)">
      <Output ItemName="ContentWithTargetPath" TaskParameter="Include" />
    </CreateItem>
  </Target>
  ...
</Project>

Возможно, вам придется поиграть с формой группы элементов Content, которая является результатом задачи CreateItem, если файлы не будут развернуты в нужном каталоге. Обратите внимание, что я использовал преобразование элемента, чтобы сделать целевой путь scripts\YourScript.js,

Также обратите внимание, что первая задача CreateItem объединяет вывод в группу элементов под названием FileWrites. Я обнаружил, что цель Clean проверяет эту группу элементов, чтобы узнать, какие файлы нужно удалить.

Поместите этот XML в файл вашего проекта после <Import> элементы, и вы должны быть в порядке. Не требуется проверка исходного кода, и даже ваш сервер сборки будет счастлив.

Разве вы не можете использовать событие после сборки, чтобы запустить скрипт, чтобы делать то, что вы хотите? Я использую один, чтобы переместить мои выходные файлы в местоположение, совершенно не связанное с проектом. Будь то простой пакет, VBScript/JScript или PowerShell, вы можете делать практически все, что захотите.

У меня было похожее требование, хотя оно включало только добавление существующих файлов в пакет развертывания, а не их генерацию как часть сборки. Я нашел технику на этой странице полезной.

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