MSBuild: Развертывание файлов, которые не включены в проект
У меня есть событие Pre-build в веб-проекте, которое минимизирует и объединяет файлы JavaScript с помощью узла. Это создает папку с именем BuiltScripts в папке сценариев, которая является дубликатом папки сценариев, за исключением того, что файлы минимизированы. Когда я делаю развертывание, я хочу опубликовать папку сценариев, включая папку BuiltScripts внутри нее. Для этого я добавил в проект папку BuiltScripts. Это не идеальное решение, так как:
- Я должен иметь проверенную папку BuiltScripts, чтобы построить, поскольку файлы в ней только для чтения, поскольку решение находится под контролем исходного кода. Это создает неприятности при регистрации, так как у меня есть так много файлов.
- Когда я добавляю новый файл в проект, я должен убедиться, что не забываю добавить его в папку BuiltScripts, иначе встроенная версия файла не будет развернута.
- Моя сборка завершится неудачно на сервере сборки, так как файлы в папке BuiltScripts также доступны только для чтения.
- Наличие двух копий файла с одинаковым именем является проблемой при поиске файлов и выполнении текстового поиска.
Я хотел бы собрать сервер сборки и минимизировать файлы 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, вы можете делать практически все, что захотите.
У меня было похожее требование, хотя оно включало только добавление существующих файлов в пакет развертывания, а не их генерацию как часть сборки. Я нашел технику на этой странице полезной.