代码之家  ›  专栏  ›  技术社区  ›  Gishu

良好实践:如何重用.csproj和.sln文件来为CI创建msbuild脚本?

  •  7
  • Gishu  · 技术社区  · 16 年前

    使用msbuild作为构建运行程序的轻松/可维护的方法是什么?(请原谅这篇文章的篇幅)

    我只是在TeamCity尝试一下(我必须说这是一个很棒的W.R.T.学习曲线和开箱即用的功能)。我有一个svn>msbuild>nunit>ncover组合正在工作。

    我很好奇使用msbuild的项目有多大-我刚刚将msbuild指向了我的主sln文件。 几年前我和南特呆过一段时间,我发现msbuild有点迟钝。对于初学者来说,文档太密集/太详细了。

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

    如果我只是使用msbuild来执行编译步骤,那么我还不如使用nant和exec任务来msbuild来编译解决方案?我有一种不安的感觉,我错过了一些显而易见的东西。

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

    • 从而构建解决方案
    • 它充当构建脚本而不是编译步骤。允许自定义前/后任务。(例如,调用nunit来运行nunit项目(似乎还没有通过teamcity web ui支持该项目)
    • 不让开发人员更改解决方案。没有冗余;不应该要求开发人员在两个地方进行相同的更改
    1 回复  |  直到 11 年前
        1
  •  7
  •   Community Mohan Dere    9 年前

    我还没有尝试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文件表示,该文件只包含您需要构建的项组的集合。

    <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将导入配置、项目(源代码文件)和核心(pull、build和deployment命令)

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

    使用这种方法,我可以重用包含源代码的.targets,以许多不同的组合来构建我的大约50个项目,而不是创建vs解决方案来对它们进行分组。

    我希望你会发现这个有用的-如果你感兴趣的话,我可以补充更多的细节。