.net - 用于为 CI 创建 MSBuild 脚本的良好实践 : How to reuse . csproj 和 .sln 文件?

标签 .net msbuild continuous-integration

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

我只是想尝试一下 TeamCity(我必须说,它的学习曲线和开箱即用的功能非常棒)。我的 SVN > MSBuild > NUnit > Nover 组合正在运行。

我很好奇中型到大型项目如何使用 MSBuild - 我刚刚将 MSBuild 指向我的 Main sln 文件。 几年前我花了一些时间使用 NAnt,我发现 MSBuild 有点迟钝。对于初学者来说,文档过于密集/详细。

MSBuild 似乎有一些特殊的魔力来处理 .sln 文件;我尝试手动编写自定义构建脚本,按顺序链接/包括 .csproj 文件(这样我就可以拥有自定义的预构建任务)。然而它抛出了(引用重复的目标导入)。我假设大多数开发人员不想乱搞 msbuild proj 文件 - 他们会对 .csproj 和 .sln 文件进行更改。是否有一些工具/MSBuild 任务可以从我不知道的现有 .sln + 其 .csproj 文件逆向工程新脚本?

如果我只是使用 MSBuild 来执行编译步骤,我不妨使用 Nant 和 MSBuild 的 exec 任务来编译解决方案?我有一种挥之不去的感觉,我错过了一些明显的东西。

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

  • 构建解决方案
  • 充当构建脚本而不是编译步骤。允许自定义前/后任务。 (例如,调用 nunit 来运行 nunit 项目(teamcity Web UI 似乎尚不支持))
  • 不妨碍开发人员对解决方案进行更改。无冗余;不应要求开发人员在 2 个地方进行相同的更改

最佳答案

我还没有尝试过 TeamCity,但确实为我们的新 BizTalk 项目设置了构建环境。

遵循 Sayed Ibrahim Hashimi 的出色建议上my own question before starting out ,我创建了一组 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 文件表示,其中包含构建所需的 ItemGroup 集合。

<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 解决方案来对它们进行分组。

我希望您会发现这很有用 - 如果您感兴趣,我可以添加更多详细信息。

关于.net - 用于为 CI 创建 MSBuild 脚本的良好实践 : How to reuse . csproj 和 .sln 文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3067307/

相关文章:

.net - 解决 MSB3247 - 发现同一依赖程序集的不同版本之间存在冲突

msbuild - 如何使用 MSBuild 从文本文件中删除空行?

svn - 您使用哪些工具来促进持续集成 (CI)?

C# const 保护与内部

C# - 访问从 List<string> 继承的集合的项目

c# - SECURITY_ATTRIBUTES 何时更改,为什么更改?

.net - 在单个 Web 应用程序上具有多个域的 IIS

delphi - 如何为 Delphi 项目执行 MSBUILD 的 'dry run'?

android - 获取 Firebase 测试实验室中的可用设备列表

git - 让 buildbot 轮询 git 存储库以获取新提交?