Good-practices: How to reuse .csproj and .sln files to create your MSBuild script for CI?

前端 未结 1 1586
庸人自扰
庸人自扰 2020-12-18 01:53

What is the painless/maintainable way of using MSBuild as your build runner ? (Forgive the length of this post)

I was just trying my hand at TeamCity (which I must s

相关标签:
1条回答
  • 2020-12-18 02:20

    I didn't try TeamCity yet but did set up a Build environment for our new BizTalk project.

    Following the excellent advice of Sayed Ibrahim Hashimi on my own question before starting out, I created a set of MSBuild .proj and .targets scripts.

    The Core

    A central .targets script for the actual build steps you want to perform:

    <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>
    

    The second core part are the configuration targets like you find them in your .csproj files

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

    The Projects

    The single .csproj itself is represented by a.targets file with just a collection of ItemGroups you need for building.

    <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>
    

    Putting it together

    The .proj you are actually going to execute with MSBuild will import your Configuration, your Project (source code files) and the Core (Pull, Build and Deployment commands)

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

    Using this approach I was able to reuse the .targets containing the sources to build my some 50 projects in many different combinations instead of creating VS solutions to group them.

    I hope you'll find this useful - I can add more details if you're interested.

    0 讨论(0)
提交回复
热议问题