MSBuild Post-Build

У меня есть сценарий MSBuild, который почти выполняет все, что мне нужно, кроме шага после сборки (см. Предыдущий вопрос, который я задал: условный Exec MSBuild?).

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

В моем скрипте MSBuild у меня есть что-то вроде следующего для каждого из моих файлов csproj:

<Target Name="ProjectName">
   <MSBuild Projects="PathToProject" Properties="Configuration=$(buildtype)" />
</Target>

Изменить: я думаю, что я действительно хочу сделать, это определить, когда задача CoreCompile выполняется для каждого проекта. Если бы был какой-то способ проверить это в состоянии?

Есть идеи?

Я новичок в MSBuild, так что, возможно, я на неправильном пути!

Спасибо алан

3 ответа

Решение

После долгих поисков простого решения этой проблемы я не нашел его и в итоге нашел собственное решение, которое работает, но, возможно, не является лучшим решением. Тем не менее, я хотел бы поделиться этим с кем-то, у кого есть такая же проблема, чтобы вы могли по крайней мере иметь рабочее решение и, надеюсь, избавить вас от большого количества ударов головой.

Напомним, что я хотел сделать, это запустить инструмент командной строки после того, как мой проект был построен, но только если сборка была обновлена ​​(т.е. изменилась временная метка). Я не хотел помещать это в раздел пост-сборки каждого проекта, потому что я хотел, чтобы пост-сборка происходила только на нашем сервере сборки (не на машинах разработки).

Я не нашел никакого способа сделать это внешне в моем основном файле.proj и в конечном итоге изменил раздел после сборки каждого файла.csproj. Однако я поставил перед ним условие if примерно так:

if '$(ExecuteCommand)' == 'true' command.exe

Это означает, что команда никогда не будет выполнена на компьютере разработчика, но когда я вызываю сборку из моего файла.proj, я могу установить для этого флага значение true следующим образом:

<!-- Define common properties -->
<PropertyGroup>
    <ExecuteCommand>true</ExecuteCommand>
</PropertyGroup>

<Target Name="YourTarget">
    <!-- Build project -->
    <MSBuild Projects="Path to project" Properties="ExecuteCommand=$(ExecuteCommand)" />
</Target>

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

Спасибо алан

Вы также можете сделать это на основе конфигурации, выбранной в процессе сборки. Для CI вы всегда должны использовать "Release" или "Production" (вы можете определить свой собственный)

<Exec Condition="'$(ConfigurationName)'=='Release'" Command="your command goes here ..."/>

Если вы можете добавить следующее к каждому из ваших проектов:

<Target Name="DoStuffWithNewlyCompiledAssembly">
    <Exec Command="command.exe" />
</Target>

... тогда вам нужно только добавить свойство:

<Target Name="Name">
  <MSBuild Projects="" Properties="TargetsTriggeredByCompilation=DoStuffWithNewlyCompiledAssembly" />
</Target>

Это работает, потому что кто-то умный в Microsoft добавил следующую строку в конце CoreCompile цель в Microsoft.[CSharp|VisualBasic][.Core].targets (имя файла зависит от языка и версии MSBuild/Visual Studio).

<CallTarget Targets="$(TargetsTriggeredByCompilation)" Condition="'$(TargetsTriggeredByCompilation)' != ''"/>

Так что, если вы укажете имя цели в TargetsTriggeredByCompilation свойство, ваша цель будет работать, если CoreCompile работает - и ваша цель не будет работать, если CoreCompile пропускается (например, потому что выходная сборка уже обновлена ​​по отношению к коду).

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