好的实践:如何重用.csproj和.sln文件来创建你的CI MSBuild脚本?

7

如何以无痛/可维护的方式使用MSBuild作为构建运行程序?(原谅这篇文章的长度)

我刚尝试使用TeamCity(我必须说,从学习曲线和开箱即用功能方面来看,它很棒)。我启用了SVN> MSBuild> NUnit> NCover组合。

我好奇中大型项目如何使用MSBuild - 我只是将MSBuild指向我的主要sln文件。 几年前,我花了一些时间使用NAnt,发现MSBuild有点晦涩。对于初学者而言,文档过于复杂/详细。

MSBuild似乎有一些特殊的魔力可以处理.sln文件;我尝试手写自定义构建脚本,按顺序链接/包含.csproj文件(这样我就可以拥有自定义的预处理/后处理任务)。但是它出现了问题(引用了重复的目标导入)。我认为大多数开发人员不想去操作msbuild proj文件-他们会更改.csproj和.sln文件。是否有某个工具/MSBuild任务可以从现有的.sln+其.csproj文件反向工程出新的脚本,我不知道吗?

如果我只是使用MSBuild执行编译步骤,那么我也可以使用一个exec任务来编译解决方案的Nant?我有这种刺骨的感觉,我正在错过一些显而易见的东西。

我的最终目标是拥有一个MSBuild构建脚本

  • 构建解决方案
  • 作为构建脚本而不是编译步骤。允许自定义的预处理/后处理任务。(例如调用nunit运行nunit项目(似乎还没有通过teamcity web UI支持))
  • 不妨碍开发人员对解决方案进行更改。无冗余; 不应要求开发人员在2个地方进行相同的更改

我的解决方案对您有用吗?还是您更喜欢TeamCity的某些特定解决方案? - Filburt
@Filburt - 抱歉..我走了神/需要更多时间来亲自试验Sayed的博客文章-我想我一直在寻找<msbuild>任务。从主脚本中分叉msbuild。我的主要需求是避免在构建脚本中重复解决方案/proj配置,但仍然能够添加预/后构建自定义任务。 - Gishu
1个回答

7
我还没有尝试过TeamCity,但我已经为我们的新BizTalk项目设置了构建环境。
在开始之前,我遵循了Sayed Ibrahim Hashimi我的问题中给出的卓越建议,创建了一组MSBuild .proj和.targets脚本。
核心
一个中央的.targets脚本,用于执行您想要执行的实际构建步骤:
<Project DefaultTargets="Deploy" xmlns="...">
    <!-- omitted validation steps, see referenced post for details -->
    <PropertyGroup>
        <PullDependsOn>
            $(ValidateDependsOn);
            Validate;
        </PullDependsOn>
    </PropertyGroup>

    <PropertyGroup>
        <BuildDependsOn>
            $(PullDependsOn);
            PullFromVersionControl;
        </BuildDependsOn>
    </PropertyGroup>

    <PropertyGroup>
        <DeployDependsOn>
            $(BuildDependsOn);
            Build;
        </DeployDependsOn>
    </PropertyGroup>

    <Target Name="PullFromVersionControl" DependsOnTargets="$(PullDependsOn)">
        <Exec Command="..." />
    </Target>

    <Target Name="Build" DependsOnTargets="$(BuildDependsOn)">
        <MSBuild Projects="@(ProjectsToBuild)" />
    </Target>

    <Target Name="Deploy" DependsOnTargets="$(DeployDependsOn)">
        <Exec Command="..." />
    </Target>
</Project>

第二个核心部分是配置目标,就像您在.csproj文件中找到的那样。
<Project xmlns="...">
    <PropertyGroup Condition=" '$(Environment)' == 'DEV' ">
        <SomeConfigKey Condition=" '$(SomeConfigKey)' == '' ">Foo</SomeConfigKey>
    </PropertyGroup>

    <PropertyGroup Condition=" '$(Environment)' == 'TEST' ">
        <SomeConfigKey Condition=" '$(SomeConfigKey)' == '' ">Bar</SomeConfigKey>
    </PropertyGroup>
</Project>

项目

单个.csproj文件本身由一个.targets文件表示,其中只包含您构建所需的ItemGroups集合。

<Project xmlns="...">
    <ItemGroup>
        <!-- this group contains the list of items to pull from version control -->
        <Sources Include="@(Sources)" />
        <Sources Include="MyProjectRootDir" />
        <Sources Include="MyDependentProjectRootDir" />
    </ItemGroup>

    <ItemGroup>
        <ProjectsToBuild Include="@(ProjectsToBuild)" />
        <ProjectsToBuild Include="MyProject.csproj" />
    </ItemGroup>
</Project>

组合起来

你实际上要用MSBuild执行的.proj文件将导入你的配置、项目(源代码文件)和核心(拉取、构建和部署命令)。

<Project DefaultTargets="Deploy" xmlns="...">
    <Import Project="Config.targets"/>

    <Import Project="Project.targets"/>

    <Import Project="Core.targets"/>
</Project>

使用这种方法,我能够重复使用包含源代码的 .targets 文件来构建50个不同组合的项目,而不是创建VS解决方案来对它们进行分组。

希望您会发现这个方法有用——如果您感兴趣,我可以添加更多细节。


嗨Filburt,你能否请看一下http://stackoverflow.com/questions/34059733/multiple-hint-paths-in-csproj-file-from-an-text-file-variable? - ansar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接