如何为 Build/Rebuild 等 msbuild 内置目标设置条件?

How do I put a condition on msbuild built-in targets like Build/Rebuild?

我正在以差异化方式构建一个包含大约 80 个项目的庞大整体解决方案。现在,在我的构建管道中,我包括一个构建整个解决方案的步骤。但我想做的是构建解决方案,但提供条件作为 msbuild 参数,以便我可以排除一些可能没有任何关联更改的项目。我已经有了脚本来检查我的提交并意识到发生了什么变化以及需要构建哪些项目。

我只需要一种将该信息发送到 MSBuild 的方法,这样它就不会每次都构建所有项目。我尝试单独构建项目,但这比一起构建解决方案花费的时间要多得多。

因此,我正在寻找任何解决方案,通过这些解决方案我可以指定跳过特定项目的 MSBuild 会有很大帮助。非常感谢!

I already have scripts to go through my commits and realize what changed and which projects need to be built.

因为我可以清楚地知道您使用哪个脚本来实现更改的内容以及需要构建哪些项目。我假设您正在使用 xx.csproj 中的 MSbuildTarget 脚本来进行这些判断。

=如果我没有误会,你可以从这个similar issue得到帮助(参见ilya的回答)。

参见this document,您会发现构建操作是由这三个目标执行的,BeforeBuild、CoreBuild 和AfterBuild。因此,假设你有一个目标来完成我的提交并意识到发生了什么变化,如果需要构建一个项目,你可以将如下脚本添加到 xx.csproj:

<PropertyGroup>
    <BuildWrapperDependsOn>$(BuildDependsOn)</BuildWrapperDependsOn>
    <BuildDependsOn>CheckIfBuildIsNeeded;BuildWrapper</BuildDependsOn>
  </PropertyGroup>

  <Target Name="CheckIfBuildIsNeeded">
    <!-- Execute command here that checks if proceed with the build and sets the exit code -->
    <Exec Command="exit /b 1" WorkingDirectory="$(SourcesPath)" IgnoreExitCode="true">   
      <Output TaskParameter="ExitCode" PropertyName="ExecExitCode"/>
    </Exec>
    <Message Text="Exit Code: $(ExecExitCode)" Importance="high" />
    <PropertyGroup Condition="'$(ExecExitCode)' == '1'">
      <DoBuild>false</DoBuild>
    </PropertyGroup>
  </Target>

  <Target Name="BuildWrapper" Condition=" '$(DoBuild)' != 'false' " DependsOnTargets="$(BuildWrapperDependsOn)" Returns="$(TargetPath)" />

以上是来自ilys的脚本,希望我的描述能帮助您理解。使用此脚本,当我们启动构建目标时,它首先会 运行 它所依赖的目标,因此它会 运行 CheckIfBuildIsNeeded 目标和 BuildWrapper 目标。只有当 DoBuild 属性 为真时,BuildWrapper 才会真正执行。由于 buildwrapper 依赖于原始的 $(BuildDependsOn),它将继续真正的构建过程。

总的逻辑是:运行CheckIfBuildIsNeeded脚本和输出值表示是否需要构建=>尝试运行BuildWrapper=>如果需要构建,则运行 real build success(BeforeBuild, Corebuild,Afterbuild),如果值为false,完成构建过程。所以我认为您可以对该脚本做一些小改动,然后它就可以适合您的情况。 (不确定你的脚本是什么样的,我无法为你完成)

并且由于您有很多项目,因此不需要手动将此脚本添加到每个项目。您可以创建一个 Directory.Build.props 文件,将脚本复制到其中,并将该文件放在解决方案文件夹中,然后它将适用于解决方案中的所有项目。