Packaging dependent SharePoint projects – TFS Build 2010 tip #1


Visual Studio 2010 SharePoint Developer Tools make it extremely easy to separate your solution into logical units and yet package them in a single SharePoint Package (WSP). Although building dependent SharePoint projects using Visual Studio 2010 is straight forward, building using TFS Build 2010 produces slightly different output. Find out how to build dependent SharePoint projects using TFS Build 2010 the right way.

Packaging SharePoint assets using Visual Studio 2010 SharePoint Developer Tools

Visual Studio 2010 SharePoint Developer Tools make packaging SharePoint assets into SharePoint Packages very transparent to you. No matter how you separate your project structure in Visual Studio you are free in choosing how you want to package all the different pieces of your solution.

Packaging assets from different projects is very easy. All you have to do is to open the Package Designer and select which assets should be included in the SharePoint Package.

Packaging items from different projects into a single Package using the Visual Studio 2010 SharePoint Developer Tools

The next time you package your project in Visual Studio, the Visual Studio 2010 SharePoint Developer Tools will detect which SharePoint Project Items (SPI) from other projects have been included in the package, and will then build those projects and copy and package the references SPIs – all of this automatically without you having to do anything.

Packaging SharePoint projects with TFS Build 2010

When building projects using TFS Build 2010 the most common approach is to build the complete solution (SLN). This allows you to build all projects with a single call.

Solution selected for building in a Build Definition in TFS Build 2010

The inconvenience

In terms of SharePoint projects building a solution takes us only half way there. In most scenarios you would not only want to build the code but also to create SharePoint Packages. The most common approach of doing this is by setting the /p:IsPackaging=true MSBuild argument in the Build Definition.

Packaging argument set in a Build Definition in TFS Build 2010

Unfortunately when you build your project now using TFS Build 2010 you will get a different results than when packaging the same project using Visual Studio 2010. If you take a look at the drop folder you will see that TFS Build 2010 has built and packaged all SharePoint Project and instead of one SharePoint Package you get multiple – one for each project!

Multiple SharePoint Packages in the drop folder after building a SharePoint Project

How they do it?

When you select a solution as the item to build in your build definition, TFS Build will build all projects that belong to that solution. This works exactly the same in Visual Studio 2010 as well as in TFS Build 2010. The big difference is in how MSBuild deals with the IsPackaging parameter set in the Build Definition to package the project after building.

When working in Visual Studio 2010 we can package the project either manually, by selecting the specific project and choosing from the Build menu the Package option:

Package option highlighted in the Build menu

or automatically by editing the project file and adding the following snippet after calling the Microsoft.VisualStudio.SharePoint.targets:

<PropertyGroup>
    <BuildDependsOn>$(BuildDependsOn);CreatePackage</BuildDependsOn>
</PropertyGroup>

In both scenarios Visual Studio 2010 will execute the packaging logic only on the specific project which will result in a single WSP.

However, if you select a solution in a TFS Build 2010 Build Definition and pass the IsPackaging MSBuild parameter, it will be passed on every build that belongs to the selected solution meaning every project that will be built will also be packaged what will result in multiple SharePoint Packages instead of one.

Building dependent SharePoint Projects the right way

Although you can argue whether the default approach is right or wrong, it might be confusing especially for someone who wasn’t involved in working on the project. For this reason keeping the drop folder as clean as possible might a good idea.

To package only the root project instead of all projects, you have to do two things. First in the build definition you have to select instead of solution your root project as the item to build.

Root project selected in the build definition as the item to build

Important: Once you select a project instead of solution you also have to specify a value for the Configurations to build property. For the project to build you have to specify the AnyCPU|Release configuration (note there is no space in the AnyCPU platform name!).

The next thing that you have to do is to modify the Build Template. For this create a new Build Template off the DefaultTemplate (1) by clicking the New… (2) button in the Build Definition’s Process tab.

Creating new Build Template

In the New Process Build Template dialog ensure you have the DefaultTemplate selected as the File to copy and click OK. Once the Build Template Workflow opens, zoom in to the following block:

Sequence > Run On Agent > Try Compile, Test and Associate Changesets and Work Items > Sequence > Compile, Test, and Associate Changesets and Work Items > Try Compile and Test > Compile and Test > For Each Configuration in BuildSettings.PlatformConfigurations > Compile and Test for Configuration > If BuildSettings.HasProjectsToBuild > For Each Project in BuildSettings.ProjectsToBuild > Try to Compile the Project > Compile the Project

‘Compile the Project’ sequence highlighted in the Build Template

In the Compile the Project sequence select the Run MSBuild for Project activity and open its properties (either by clicking right mouse button and selecting Properties from the menu or by pressing F4).

In the Properties window set the value of the Targets property to

New String() { "Package" }

With that save the Build Template and check it in. When you build your project now, you will see that although you only have called the Package target, Visual Studio 2010 SharePoint Developer Tools have built the root project together will all dependent projects and have packaged everything into a single SharePoint Package just as expected.

Drop folder with a single SharePoint Package after building SharePoint Project using a custom Build Template

Acknowledgements

Huge thanks to Mike Morton and Phil Hoff for helping out with solving this challenge!

Others found also helpful: