TFS Online/VSO Build with Common Assemblies - tfs

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

Related

TFS - Workspace to build definition with only required files

In our project we are building project with TFS build definition feature.In TFS build definition there is one option like "workspace" where we mention all require folders which contains file which used to build project successfully. We have separate folders as per requirements which contain different units. this units are in large numbers hence when we build project and mention any folder in workspace then it extract all files in that particular folder. actually we require only few of them for project build because we used different files per project but that files under same roof.
could any one help us that how we build our project with only require files in workspace rather than whole folder?
Status =Active Source control folder =$/Artiion/ADO/LibForms/Loginf.pas: Build agent Folder=$(SourceDir)\LibForms\Loginf.pas
above example works fine
There is no reasonable way to do this. When you tell TFS Build what source folders to use, that is what you are telling it: get these folders. In theory I suppose you could modify or write your own process template and provide custom fields in which you could provide data to the build process about what files you need for that build, and then create some custom action to call out that would then replace the standard TFS Get function in the process template. But what would be the purpose? If you have certain files that are to be included in the solution build, then simply have separate solutions or projects which would include the appropriate files. Then build the specific solution based on which subcomponents you need, and then only those files will be built and copied to the drop location. Sure, they would still have been retrieved in the build agent's workspace, but they would not have been used in the actual build or placed in the drop location. If that's not good enough, and you need to actually Get different groups of files per build, then you should rearrange your files so that the necessary files are in the appropriate subfolders.

TFS 2010 Working Folders Setup in a Build

I have a folder structure setup for my code like so:
MyCodeFolder
-SolutionFileOne.sln
-ProjectFolder1
-ProjectFolder2
-ProjectFolder3
-SolutionFileTwo.sln
-ProjectFolderA
-ProjectFolderB
-ProjectFolderC
-ProjectFolderCommon
Solution one contains projects 1,2,3 and Common and Solution two contains project A, B ,C and Common.
When I come to create my TFS Builds I am getting a problem. If I just add MyCodeFolder in the working folder set up then both builds will succeed but then check-ins against project 2 will kick off a build of solution two and vice versa.
If I map only the folders the solution needs the build fails, which I am guessing is down to the fact I haven't included a mapping to the folder where the solution file is (the MyCodeFolder).
Is there a way I can solve this issue without altering my file structure?
The continuous integration trigger in TFS builds will queue a new build any time an item within that build's workspace is altered. Workspace mappings can only contain folders - you cannot include \ exclude (aka "cloak") individual files within folders.
What you can do is setup your build workspace to use the entire /MyCodeFolder folder. Then, in the build for SolutionFileOne.sln you can cloak ProjectFolderA, ProjectFolderB, and ProjectFolderC. In the build for SolutionFileTwo.sln you can cloak ProjectFolder1, ProjectFolder2, and ProjectFolder3.
This is only a partial solution. Both builds will still get kicked off when someone changes either solution file, or when anything in the ProjectFolderCommon folder is changed. Since you can't cloak the solution files themselves there's no way to avoid both builds getting kicked off on a solution file check-in without changing the structure of your files.

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.

Team Foundation Build Property for Build Folder

Using TFS 2010 I need to build a solution that depends on a couple of other solutions held in different team projects. I'm editing my build definition and I create a list of "Projects to Build'. When it comes to build the parent solution I get an error because it's unable to reference assemblies created by the other solutions. So I go back to edit build definition and add /p:ReferencePath="c:\builds\3\referencedproject\binaries\" to the "MSBuild Arguments" Build process parameters.
Problem is, I don't want to hard code the c:\build\3. I guess there may be a $() property I can use in its place - can anyone please advise?
The other problem I have is that the 'Main' project and the two other projects that it references live at the same level in the source code. As far as I can tell, I have to set the source control folder to be the level above this - which happens to be the root. This means that TFS Build does a get of all the projects on the root - which includes dozens of projects that are not required for my build. It's not a critical issue since it makes no attempt to compile these non-related projects but it does increase the time for the build cycle to complete. Is this only way to avoid this to "group" the projects that are required for my build into a different TFS source folder?
For the references issue there are a few options. The most common one taking an explicit dependency on a specific version by checking in the binary to TFS.
For example, if you have Team Project A that has a dependency on Team Project B, I would assume they are setup as separate projects because they evolve differently, probably have different teams working on them, and have different release cycles. The common approach to managing this dependency is to checkin B.dll into Team Project A (usually in a lib folder specifically for this purpose), then use a file reference from within Project A's solution/projects to the dll in the lib folder.
This approach lets the Project A team explicitly choose which version of B.dll they wish to depend on, and make an explicit decision to adopt newer versions of B.dll on their own timetable.
For the other question of how to have a build definition download only select source code paths, you can specify multiple lines in the Workspace mapping screen when setting up a build definition. For example you could have the following:
$\ProjectA -> $(SourceDir)\ProjectA
$\ProjectB -> $(SourceDir)\ProjectB
This would download Project A + B but not C.
I'll start with problem 2 as this should be easiest to solve.
You have 2 options both involve changing the workspace mapping of your Build Definition.
You don't have to map at the folder "above", you can map individual folders so if your source looks like this.
$/TP/SolutionA
$/TP/Folder1/SolutionB
$/TP/Folder1/SolutionC
$/TP/Folder2/SolutionD
and you only want to include SolutionA and SolutionC in your build, you could set the workspace up as follows.
This will get just the code you need and preserve the relative paths between them.
Another option is to use cloaking, you map the "Root" folder and then cloak any folders you want the build to ignore.
Both of these methods will restrict the amount of source being downloaded when the build runs, and also prevent "continuous" builds from starting when checkins occur in the folders that haven't been mapped / Cloaked.
Problem number 1.
As Dylan suggests, probably the best thing to do is to use Binary References between solutions. Especially solutions in seperate team projects.
Check out my answer to this question for a full description.

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