TFS 2013 - MSBuild Project with Nested Dependencies - tfs

All,
I have several top level projects (console apps, websites, etc) that have internally built dependency projects. Some of these sub-projects are referenced in the top level projects by including the DLL from the sub-project's bin folder, and some are referenced by including the project in the solution. I have no idea which way is the "right" way, but I do know I can't get any of my top level projects to build using TFS Continuous build. They build locally, but not in TFS Continuous build. They usually fail with a series of "can't find reference" errors.
My though is that I will need to take each of the sub-projects (models, repositories, etc) and have them build to a central location, then reference that central location in the top level projects. The only thing I don't like is that I don't see a way to only let DEV branch builds copy to the central location unless I just use a post-build event script on the DEV branch project.
If anyone out there can help me find some Zen with this process, I would appreciate it. I am a software engineer, not a build engineer...

If you're versioning dependencies separately from applications that use them, then use NuGet for managing the dependencies. As part of the build process, the packages will be restored.
Binaries should basically never be in source control.

Related

TFS Online/VSO Build with Common Assemblies

I was wondering if anyone could help.We have the following project structure in our company :
Code/Common
Code/Project1
Code/Project2
etc...
When the Common Project builds, it has a PostBuild Event that copies all the relevant files into the Code/Common/Binaries folder. Then all the other Projects reference the Common components in this folder.
However, what we are struggling with is that when TFS Online checks-out the solution it does so to c:\a\src and the Common binaries are placed in c:\a\src\Binaries. Now, when the other projects (Project1 etc) do their build it cannot find the Common Assemblies, as not only are they removed, but the paths are different from what it expects them to be in c:\a\src\Common\Binaries instead of c:\a\src\Binaries.
Is there anyway to tell the build server to not delete those files in the "Binaries" directory and to specify the folder location to checkout to? Or how one one go about solving such a problem?
Thanks very much
A build server is a transient thing, you cannot rely on files to be there.
You need to either Create Nuget Packages for you common output and then consume these in your other projects (the 'proper' way), or you will need to check your dependencies into source control after each build so you can then reference them in subsequent builds (the 'really frowned apon' way).

How do I make an automated build use same output folders as a manual build?

Background
Currently I have many C# projects in many TFS team projects.
Several C# projects reference C# projects in different team projects. I do this by referencing the output dll in the Bin/Release folder of the other C# project.
As long as we checkout & build the solutions in the team projects in the correct order everything works fine on all dev's machines.
We're moving to Visual Studio Online and I'm playing around with automated builds.
Problem
The problem I'm having is that it can't find the dlls to reference, even after the project that would output them (to \Bin\Release) has ran.
I've disabled parallel builds (to ensure the referenced projects get built first) and this seems to be the case based on the build logs. The issue is that the projects that depend on these can't find the dlls and as a result I get "the type or namespace could not be found" errors everywhere.
What's the easiest way of resolving this?
Note that I've read several posts/tutorials etc. about this but all seem to involve changing the source control structure, or fiddling about with workspaces etc. I want something where I can keep the simple workspace mapping on the dev's machines where we map "$\" to "C:\TFS\". I don't want to have to remember to periodically merge in changes from a shared library, or maintain lots of folder mappings within a workspace (on dev machines).
Open your process template xaml (usually DefaultTemplate.11.1.xaml or TfvcTemplate.12.xaml with XML editor, not the designer). Look for mtbwa:MSBuild on Run MSBuild for Project activity. Remove the OutDir attribute, save and check-in. This will force MSBuild to use the default OutDir for each project.

Using wixlibs from another solution with TFS builds

We have installers referencing a wixlib file to get some common functionality. The wixlib is built in another solution then moved to a folder within that solution. When we try to build the installers with a TFS build, we get an error from light.exe:
light.exe: The system cannot find the file '..\..\..\Core\Common\assemblies\v1.0\Common.Wix.wixlib' with type 'Source'.
Our regular projects can reference \assembiles\v1.0, since we have some other common assemblies stored there. How do we get WiX to recognize this location during build?
You are referencing wixlib directly. So as far as I understand the TFS build process, it should be added to TFS project of your solution. TFS project shouldn't be dependent on the output of another non-dependent solution. It is at least bad practice. And in any case you can't guarantee this output would be generated before your project build on server.
As far as I remember, TFS build creates separate folder for each build and gets sources there. So your solutions are no longer on the same folder hierarchy level.
One more point in favor of explicitly copying wixlibs into your installer project: versioning - in this case any bugs made in the common library will not immediately break all projects that reference it. And you can gradually upgrade and test every project. Can you imagine auomatically downloading new version of any 3rd party dll on every build? Any change in that dll will immediately break your application even if changes are not critical to you.
Since the shared component and the active solution are in two separate projects in TFS, the workspace must be setup so that the relative paths for references remain intact. The easiest way to do this is to set your Build Agent Folder structure in Workspace in your TFS Build to have $(SourceDir) represent your root. However, don't change your Source Control Folder - that stays the same.
For example, say you have the following structure:
-TFS
|-SharedComponents
||-MyComponents
|-ProjectArea
||-MyProject
You would want to have the following two items in the build Workspace:
Source Control Folder Build Agent Folder
---------------------------------------------------------------------------------
$/ProjectArea/MyProject $(SourceDir)\ProjectArea\MyProject
$/SharedComponents/MyComponents $(SourceDir)\SharedComponents\MyComponents
This mimics the structure in TFS in your build folder, thus allowing all relative paths to remain intact.
One more note about this configuration: Since you have the shared components in another location, you may want to create a solution folder in MyProject and add the components that you are using to it. This will ensure they get pulled automatically when anyone loads your project from TFS - they won't have to go back and pull down the share components folder separately after discovering a build error.

Filter projects which trigger build in tfs

Is there any within team build 2010 (tfs) to decouple the projects found under the build's workspace from the projects which will trigger a build?
I'd like to be able to specify a subset of the projects in my workspace as being those that trigger a build when changed. At the moment any change in the active paths of the workspace will trigger a build.
You can create more build definitions to build only specific projects. I had two sets of projects, framework and modules projects. I had two CI build definitions, one for framework set and one for modules. If I changed framework project, framework build was triggered and all output assemblies were checked-in into TFS into BuildAssemblies folder. This folder is included in Modules build definition workspace because BuildAssemblies are referenced from modules projects. Normally if I change BuildAssemblies content modules build should be triggered, but I checked my changes with ***NO_CI*** prefix to not trigger modules build.
But this is not good design. If you change framework assembly and break modules build by this change, you don't know about it until you manually trigger modules build. It makes no sense to use gated check-in feature for modules build.
In general, I tend to agree with John Saunders, still:
You can have the projects you wish to not trigger your build in a separate spot within your source control. Remove them from your main solution as projects & add them as assemblies.
This way, any change in your secondary sources will not trigger your main build - merging the compiled assembly will. The gain is that the latter can be done at any time you choose to.
Using file reference has several disadvantages in your case, the main being you can't directly debug the compiled assembly. See also here.
The only way is to remove those projects from the build definition's workspace mappings. The projects, of course, are still in the branch and your workspace.

TFS 2010 mapping dependent files for builds

I am pretty new to TFS and Build configuration tasks so forgive me if this problem has a simple answer.
I have a team project that is sort of a common library(CL) that contains dlls and apis that I commonly use throughout my projects. All my other projects reference files directly from the mapped folder for the CL on my dev machine.
I am trying to set up a build definition for Project A(Build server is on a different machine). I want always ensure that the CL is the latest before each build so is it possible to have the build definition pull the latest files first? The only other alternative is to start including the CL in of every project directly.
I tried adding a working folder for the CL, but it does not seem to get the files before it attempts to build project A. And then after when I try to rebuild after the failure, I receive a error saying that the CL working folder "is already mapped in workspace".
Instead of mapping in the sources, why not build the common library, deploy it to a common location, and have all the projects that use it reference it at the common location?
In addition to simply making more sense (it should be common binary, not common source), this greatly improves Continuous Integration builds. If several builds map the same source into their workspace, then when the common source is changed, all of those CI builds will be kicked off.

Resources