How to share company wide settings across multiple team projects in TFS? - tfs

This is a problem we have been living with for a while already. Suppose that I have three files:
a FxCop ruleset, containing our basic Code Analysis rules
a Resharper .DotSettings file, with company defined naming conventions, for instance
a StyleCop.Settings file, with some of the default style cop settings disabled
How do I share these kinds of company wide settings files across multiple TFS Team Projects?
At the moment, we have these replicated in a Resources folder in each project, but this is quite a maintenance nightmare, since when we decide to update a few rules on any of these files, we have to update them in a lot of different places.
One approach I've seen is to create a team project specifically to store these files on TFS, for instance $/Core, and by some means share the files this way, either using workspace mappings or branching the project into the other projects.
I don't like this primarily because it requires manual intervention and hardcoded paths. Ideally, I'd like an approach that was not intrusive, i.e. a developer gets the project from source control and compiles without any problems. No need for separate mappings into specific forlders, setting environment variables, anything like that.
At the same time, I'd like to keep the history on these files, so it would be nice if they could still be source controlled. Since they are central to the company, it would be ideal to have limited permissions on them, and that each change was documented appropriately (changesets provide that).
Another approach that crossed my mind was to share these settings via company internal nuget packages. Say for instance that I do have this $/Core project, but instead of using workspace mapping or branching it inside the other projects, I publish a nuget package (or more than one even) containing the configuration files, and add these packages to each project that needs it. I can then use relative paths to the package folder when referencing them, and it would require no manual intervention on the developers part.
Although using nuget would probably work fine, this solution seems weird to me, since nuget packages are meant to be project specific, but this would be "whole team project" specific instead. Again, using this approach, I'd probably have to add the package to one of the projects inside one of the solutions inside each team project. This is actually quite similar to how test adapters are shared now. For instance, NUnit already support this approach. I feel I'd have to do something very similar to that if I went with an internal nuget package: each solution would have to load the package at least once.
Is there some other way to share these kinds of things across the whole company, while still maintaining them on source control? What if I loosened this constraint, and accepted that they don't need to be source controlled? Would it open up other options to share them?

If you go down the NuGet route, you could create Packages for your FXCOP and Resharper files, and then store them in a local feed.
For Stylecop you could use the existing NuGet Package for StyleCop.MSBuild and then repackage it with your own settings file.

Related

What is the recommended TFS structure.

We are trying to move from our current source control to a TFS as a source control. Right now we have all projects as project references. Our organization is small and we have a lot of common projects that are used by various development teams and all teams update these projects as needed. When we migrate to TFS we are looking to use DLL references for these projects but I am wondering if that would make branching impossible and I am also concerned about is there a benefit of having DLL references to the projects that all teams in the company need to make changes to.
Could you please suggest, given our scenario, if it would be good idea to have DLL references to our common projects or to have project references. Any links to suggested readings would also be helpful.
Depends on the size of these projects and how often you make changes there, dll references are generaly used for 3rd party libs, if you own common projects are not often changed and/or changed by small/dedicated group of ppl then it may be benificial to treat them the same way, otherwise its better to have project references.
Im not sure why dll references would present branching problems ? You branch them just like any other code or project, if they dont differ per branch you can save yourself time on updates and keep them outside branch in single location.

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.

How to handle 3rd party libraries in TFS 2010

At my work we are just starting to use TFS with our team of 4 developers, and are at the same time transitioning from single developer projects to team projects. We are mostly using the default settings in TFS
I was the first to push up a simple Silverlight MVVM project consisting of a solution with a Silverlight and a web project.
When my team-mate pulled down my code and tried to compile, he was faced with many missing references (.dlls), Expression blend SDK, Ria Services toolkit, Telerik controls, simple mvvm toolkit, silverlight toolkit, etc.
What do we need to do, to add projects to TFS that have everything needed to be compile it when the next developer pulls it down?
There isn't a really good way to do this all automatically. What you'd generally do this this:
in your branch create a bin folder next to your src folder.
in the bin folder create folders for each component you're relying on
in each folder place the setup or a link to the setup
in each folder place the binary files you're using in your solution
in each folder place a readme with any manual steps that must be completed
if wanted you can create a powershell script or batch file which installs all required components. It isn't too hard to detect whether or not an application is already installed using powershell and wmi
Now you'll have to fix a few things in your solution:
make sure your references don't point to the GAC, but that they point to the assemblies inside the bin folder of your branch
make sure all the paths are relative to the solution. Any c:... paths will not carry over from one system to another
I found that the easiest way to do this is to unload the project in Visual Studio and then edit it. You can then quickly add hintpath="..\..\..\bin\component attributes to each reference. There are a few blog on this subject which provide different solutions which all solve this same issue.
This setup allows you to at least get the latest version of any solution and build it without having to install any tools. If some of your components rely on visual studio add-ins, then the designers for these tools usually won't work, but at least you're able to build them.
An often used alternative is to create a Virtual Machine base image for your project and install all the required components onto it. Then copy the image to each developers workstation and sysprep it to ensure they all have a unique name and identifiers. When the project needs to update its dependencies, let one developer create a new clean machine and re-distribute that to all team members.
If you're using Windows Server Virtualization or VMWare, it's quite easy to create differencing disks and allow developers to access these images remotely.
Another approach would be to use NuGet and script NuGet using a powershell script for your solution. This will work for most cases, but products like Expression Blend still need to be installed separately.

Managing common components with Fossil CVS

I'm a Fossil (and CVS configuration) novice attempting to create and manage a set of distributed Fossil repositories for a Delphi project.
I have the following directory tree on my development machine:
Projects
Some Project
Delphi Components
LookupListView
Some Client
Some Project For Client
Some Other Project For Client
Source Code
Project Resources
Project Database
I am setting up Fossil version control in order to version and share Projects\Some Client\Some Other Project For Client\Source Code, which contains Delphi 2010 source for a database project.
This project makes use of Projects\Delphi Components\LookupListView which is a Delphi component. I need this code to be included in the versioning system for my project. I will, in theory, need to include it in other Fossil repositories in the future, as well.
If I create my Fossil repository at the Source Code or Some Other Project For Client level, I cannot add any code above that level to my repository. What is the proper way to deal with this? The two solutions that occur to me are
1) Creating a separate repository for LookupListView and make sure that everyone who uses a repository for a project that references it "knows" that they must also get the current version of this project as well. This seems to defeat the purpose of being able to obtain a complete, current version of the project with a single checkout. The problem is magnified because there are other common component dependencies in this project.
2) Establishing my Fossil repository in the Projects directory, so I can check in files from various subfolders. This seems to me to involve an awful lot of extra path-typing when doing adds, and also to impose my directory structure (Some Client\Some Other Project For Client\Source) on the other users of the repository -- in this case, the actual client.
Any suggestions appreciated.
I use Git, but my approach can be applied in your situation.
I have one repository for all my components folder. This gives me an ability to get all of them with only few console commands (in case when I reinstall my OS or go to another computer etc.).
Also I have one repository per each of my projects. If some project uses 3rd party controls I create "components" sub-folder and do symbolic links (junctions) of every components set.
This approach have some disadvantages (when you "go back" in commits history of some project, components can be modified too. And if many projects are using same components this could cause some troubles). But I had no issues yet :)

TFS 2008 and Common libraries folder structure

TFS 2008 and Common Libraries
I have created a Team Project called "Common Library" that will host code used in numerous different Team Projects throughout TFS. For sake of argument, lets say we have 2 distinct Librarys under the "Common Library" Team Projects, MailProject and LoggingProject. Other projects throughout TFS will be using the binary representation of these projects via branching and not the actual source code.
What is the best way to set up the folder structure for this Team Project? Do I add the project to the "Common Library" and simply "include" the bin/release folder as part of the project?
I have seen some examples of people creating a seperate "Deploy" folder. I assume this is synonamous with the bin/release folder?
We do not want the source code available in other solutions.
Currently, each project has the dll included in the project. Using a mailing module as an example, many projects need the ability to mail. The common module is very stable and mostly static.
However, what if there is a change in the mail module. It seems there would be a better way, than to check out each project and update the dll. Is it possible to allow TFS to grab the latest mail module any time a 'get latest' is called? Either explicitly or implicitly.
Unless you really require the source code for the libraries to be available in the other solutions my advice would be to include the binaries for the libraries in the projects that would use them not really having any explicit link between the two in TFS. Custom labelling of the library builds could be helpful to easily return and rebuild any chosen version of the shared libraries.
If the shared libraries require different versions for different projects then the obvious solution would to create a separate branch for every version of the libraries that need to be customised to a particular project.
TFS does not have a concept similar to SVN's 'externals' though - so if you include a branch from the shared libraries in a project and than branch that project it is very difficult to propagate changes correctly.
I suppose you could also use the Get task in the build and get the latest version of DDLs into the current project from another one, but verify if you can point of Workspace of another project (I have not tired it and MSDN is somewhat vague here). You might need to have a separate workspace for the shared project.
Yet another alternative would be to publish the DLLs for common components to a known location on every build of the shared libs and for individual builds to get whatever version is available from that common location (network share) even via the Copy task. This is simplistic and may cause problems with versioning of the common components but should work well enough in simple case.

Resources