Can one VSTS project be mapped to different local workspaces? - visual-studio

I have a class library project to be shared by two different solutions in Visual Studio 2017. The solutions are mapped in two different workspaces. I cannot find a way to get the shared project under source control in both solutions. Any suggestions?

I'm assuming that you have two separate Team Projects, each with its own TFVC repository. Underneath one of those Team Projects (say, TPA), you have a common library that you'd like to share with a solution located in Team Project B (TPB).
You can't do what you're asking to do -- even if you could do it, you shouldn't. You don't want to fork the source code and maintain two copies of it. What you want to do is one of the following:
Map a single workspace containing all of the Team Projects and use relative
paths for references. This isn't great, ideally each Team Project is considered a totally separate entity.
Put everything in a single Team Project and maintain a single workspace for everything.
Turn the shared component into a NuGet package and use a Package Management feed. Each consumer of the shared component can then reference a common NuGet package.
I'd say #1 is already excluded as an option. Each Team Project should be an independent entity with nothing shared between it. Since you have things shared, you've chosen the wrong organizational structure. Stop using multiple team projects.
Option 2 is okay, but it's a little bit clunkier.
Option 3 is the preferred, modern way of managing cross-project dependencies. I'd strongly recommend looking into implementing this pattern. If you adopt this pattern, maintaining multiple team projects becomes acceptable again -- you have one Team Project that acts as a publisher of shared components, and another that acts as a consumer. That's sufficiently isolated to consider them independent of one another, and thus an acceptable candidate for multiple Team Projects.
It's worth noting that the modern thought among most experts in this area is that maintaining a single Team Project for all related applications is the correct approach. I've seen teams with hundreds of members and dozens of applications using a single properly organized Team Project with no problems.

While I agree with Daniel on the fact that this is probably a bad idea and that there are alternatives, it's perfectly possible; there's one restriction though: each workspace must have its own copy of the shared project on your hard drive, they can share the remote copy on the server. This si very similar to a distributed source control model and can work just fine.
To make this work, first create one workspace and map the folders locally:
Workspace 1
$/Common/ => c:\src\1stProject\Shared
$/ProjectA/Solution => c:\src\1stProject\SolutionA
Then create a second workspace:
Workspace 2
$/Common/ => c:\src\2ndProject\Shared
$/ProjectB/Solution => c:\src\2ndProject\SolutionB
This way both projects share the same server location and changes made to Shared will directly impact both SolutionA and SolutionB. Locally though, each solution will have its own local pending changes etc.
This solution will work as long as both Team Projects are in the same TFS Project Collection.
The only limitation is that these projects can't be placed in a subfolder of each other, so you can't do this:
Workspace 1
$/Common/ => c:\src\1stProject\SolutionA\Shared
$/ProjectA/Solution => c:\src\1stProject\SolutionA
Nor can both workspaces map to the same local folder:
Workspace 1
$/Common/ => c:\src\Shared
$/ProjectA/Solution => c:\src\1stProject\SolutionA
Workspace 2
$/Common/ => c:\src\Shared
$/ProjectB/Solution => c:\src\1stProject\SolutionB
Alternatives
Nuget
Instead of using shared sources directly, add a NuSpec to the Common project and build & publish the NuGet package to the VSTS package management feed of the VSTS account. Add a NuGet reference to SolutionA and to SolutionB. That way the binaries of Common are shared among SolutionA and SolutionB, but common is maintained independently. This way it's also easier to update SolutionA at a different cadence than SolutionB (this is also the biggest pitfall for this solution).
Git & Submodules/Subtrees
Convert the TFVC repositories to Git repositories. That way you can use Subtree or Submodules to reference Common directly from the SolutionA repository and the SolutionB repository.
MonoRepo/One Project To Rule Them All
Merge all your TFVC repositories into a single TFVC repository, that way both projects can easily live inside the same workspace. Technically this isn't needed to put both projects in the same workspace, but it is easier. It results in a very similar solution as described above:
Workspace Single
$/Project/Shared => c:\src\Shared
$/Project/SolutionA => c:\src\1stProject\SolutionA
$/Project/SolutionB => c:\src\2ndProject\SolutionB
Would result in the same as the following cross-project layout:
Workspace Single
$/CommonProject/ => c:\src\Shared
$/ProjectA/ => c:\src\1stProject\SolutionA
$/ProjectB/ => c:\src\2ndProject\SolutionB
Note
In any cross-project setup, the UI of both Visual Studio and VSTS will fight you. The VSTS team has been working on the ability to make individual Team Projects portable across accounts. In order to do that features like these will need to be dropped at some point. The UI in VSTS build, for example, will not show any other Team Projects in the Source picker. If you type the paths manually they will work (as long as you configure the build to have a Collection Level scope).
Advice
The Nuget solution is the most reliable solution for the type of problem you're trying to solve. The VSTS Package Management feature will allow you to easily share the Common project across multiple projects and even across other VSTS accounts is you want to in the future. It's the most reliable solution.
If you need to be able to edit the files in either solution, I highly recommend you look into Git Subtrees or Git Submodules. Git is the future in any case and these features will allow you to achieve what you need in a much easier to sustain way. They do come with a steep learning curve though.

Related

TFS structure for "base" and "derived" projects

I am looking for some ideas and suggestions on how to implement a class hierarchy type of structure of VS projects in TFS.
Specifically, I want to have a "base" project which will contain all the common functionality the rest of the projects will inherit. When the changes are needed in the "base" project it should be relatively easy to propagate these changes to the rest of the projects which are based on this "base" project.
The obvious approach is to branch other projects from this "base" project and merge up the tree from this root project when there are changes but I've never tried that before and would like to hear from someone who attempted something like this before or has extensive enough experience with TFS to be able to point to inherent issues or pitfalls of such idea...
The projects in source control is actually folders. So your question is somehow the same as how to structure your folders in TFS.
Your base project is the some concept of main in branch which is root folder that acts as a container folder for your main source tree, together with accompanying project artifacts such as design documentation, scripts, and test cases. The Main folder also usually contains your Visual Studio Solution (.sln) files.
In TFS you could convert a folder to a branch.Then you just need to branch your base project to other projects. After have a branching relationship, you will be able to merge changes between the 2 branches. Besides you could also use branches to accomplish the following goals:
Manage concurrent work by multiple teams on the same codebase
Isolate risks that are introduced by different sets of changes to the codebase
Take snapshots and then support subsequent isolated changes (for example, to create a release branch)
Although you can still branch and merge among folders, the best practice for your team is to branch and merge only among branches.
When you perform branch operations, branches have important advantages over folders. Branches support version control features that provide extra visibility into your branch structure and into where your changesets have merged. (For more information, see these wonderful links: Visual Studio TFS Branching Guide)
For inherent issues or pitfalls of such idea, one thing is you might have to resolve conflicts when you get, check in, merge, or unshelve. Another thing is permission. It's better to avoid everyone have permission to merge changes from the “derived” projects back to the "base" project.
Besides you can create multiple teams in the same Team Project and you can nest them to facilitate hierarchy. If you are interested, you could check this blog which shows how to configure that.

Can a solution have projects from two TFS collections

We are thinking of making a distinct collection for code that is shared between our software products. We would then have a collection for the software projects. This would be done for organizational purposes. Would it be possible for a solution to reference c# projects that are in two different collections?
A solution can have files from anywhere, since they need to be mapped to a loal disk for Visual Studio to open them, but when spreading the code over multiple collections Source Control integration will break. Team Explorer requires all code to come from the same collection, and it favors solutions where all code is from a single team project, in those cases the other features will work best.
Other features in VSTS and TFS will be harder to use when your work is spread across multiple projects and/or collections. Test Plans, Agile tools, Team capacity and a few other items are purely scoped to the Project level. working in multiple projects at the same time will make it much harder for a team to use the tools properly. Many TFS consultants implement a "One project to rule them all" strategy because of these reasons. Putting all code and all work in one teamproject.
The XAML and 2015 build engine can only access sources from a single Project Collection at a time. So while it's possible to setup a number of local workspaces that each map to different team projects and/or project collections, this is not available when using the standard build servers that ship with TFS. Other build tools, such as Team City can be linked to multiple Source Control providers at the same time.
Now that it's possible to have multiple Git Repositories under the same Team Project, that approach makes even more sense.
Other things that will be harder may include branching structures, it will be very hard to manage the different versions of your code when they're spread across collections, since Labels and Branches can't cross collections and are hard to maintain when working in multiple projects.
A better solution for you would probably be to have your shared code in a separate team project or project collection, but not include it directly in your other projects in the form of Visual Studio Projects. Instead, have your shared projects stored as NuGet packages, either on a private NuGet feed or on a VSTS account with Package Management enabled.
That way your other projects will build faster (which can be significant when setup correctly), will use the binary versions of your shared libraries and have less unwieldy solutions.
One disadvantage of putting all code in a single team project or project collection is that it's harder to maintain the security. Project Collections for a natural boundary inside TFS, one that's harder to accidentally misconfigure or to break out from.
As #jessehouwing said solutions can have files from multiple collections. Each collection has a local workspace from where you attach project/files to your solution.
Where I disagree is that this is actually a good idea. There is no problem having 10+ collections, each for specific purpose.
For example 1 for generic projects that nobody will update unless necessary. One to store scripts. Basically think of it as library bookshelf. All similar stuff to some degree should be kept close.
Another plus is a security since one team can have access to some collections but not other. It is an obvious plus.
As to time difference, does really 1-2 sec make difference to anybody. Add one more agent and you will save time because locally building makes no difference.
As to Labels specific purpose strategy helps to overcome those problems.

How to deal with Git Submodules in Visual Studio solutions with different layout?

We develop with Visual Studio 2010 (in C#) and migrated a while ago from SVN to GIT. Now we try to split up our repository (which is quite big - ~30.000 files) to many git repositories - one for each solution.
The solutions share some projects, mostly libraries we develop in-house and like to add to from all the solutions.
The new repositories have a flat layout. One subdirectory for each project (shared projects are submodules).
In the big old repo, the projects are in a tree structure.
The Problem occurs with external references in the submodules. In the new repos, the path to a referenced project may be "......libs\someproject", while in the new layout the correct path would be "..\someproject".
We already had some edit wars concerning this and are not keen on more.
Half-baked Solutions I could think of:
use "Reference Paths" in ...csproj.user and exclude this file from version control (has to be redone for each developer and after each reopsitory cleanup)
use branches for each situation and try to teach everyone where "real" commits should go and where "environment-change" commits should go (submodules are already not the simplest concept...)
embed binaries instead of the submodules (but what about developing changes to the submodules? what about different log4net versions?)
Does anyone know of a sane solution?
Since you are asking for a sane solution, I can only advise you to look into setting up your own NuGet service (look at http://www.MyGet.org for inspiration)
http://nuget.codeplex.com/
IF you go down the route of package management, consider OpenWrap. However, embedding the package management artefacts in source code is a bad idea. You can use such tools to update what is actually stored in submodules, but don't rely on them at build time. Expect the binaries to be there from the point of view of your build scripts.
So if I understand you correctly, the problem is with Visual Studio and not with Git? If that's the case, use the old tree structure that worked with Visual Studio. Make your submodules structure a tree structure too. So the top of the tree would be one super repo whose sub modules (the branches) would have submodules of their own, until you get down to the leaves of your tree. It would be a pain to setup at first, but it should just work.
Use one submodule to house all "common libraries". Just one level. But you should move the common libraries as services with well defined contracts. This way you can incrementally rollout new versions with no down time. This way you only have a submodule in each that holds the contracts. These could be interfaces or messages.
I have a similar problem using VS 2013.
I want to use git-svn instead of SVN directly. SVN has a gigantic set of directories. I could not create a single git-repository that would contain all of our trunk folder. Git-always exited with an error and the repository was corrupted. I worked around the problem by doing as follows:
Using git-svn, I cloned the subset of folders off SVN/trunk that I needed by creating one git-repository per folder.
Created a local parent git repository that contains all my git-svn-cloned folders.
Each git-repository was added as a sub-module to the parent git-repository.
The problem with Visual Studio is that it does not recognize the multiple projects outside the main project where I opened the solution. This solution is in a folder that contains the only files recognized by Visual Studio as being under git-source control.
I tried setting the git-preferences to use the upper level parent directory as the location of the git-repostitory without noticing any difference.

Should Git Repo's be at the Solution Level or Project Level in Visual Studio

If I have a C# solution with multiple projects in it, what would be better, to have the Git repo created in the solution folder, or in each individual project folder? Multiple developers will be working on the projects. What are your experiences with this?
I use several (sometimes overlapping) solutions to contain a collection of related independent applications and shared libraries. As others have mentioned, you really don't want to have a single Git repository containing the source for multiple, independent projects as it makes it much too difficult to track isolated changes.
So, if your solution is structured as mine is then you will definitely want individual Git repositories for each project. This has worked well for me for ten to twelve applications and doesn't create as much maintenance overhead as you might think.
If your solution is truly monolithic (and you're sure you want it that way forever and ever), then it probably makes sense to only have a single repository.
It depends. git repositories are most suited to containing a single configuration item with its own independent lifecycle. If your projects have their own release cycle and are shared between multiple solutions then it might make sense to have them in their own repositories. Usually, though, it is the solution that represents a configuration item with all the constituent projects forming part of the same build. In this case a single git repository at the solution level makes more sense.
git submodule is probably worth consideration here. Each project gets its own repo, the solution gets a repo, and the projects are submodules.
I assume that your solution represents some kind of a product while the projects are just a part of the product.
In this situation I would create the repository on the solution level. This way it is a lot easier to build the whole product at once, especially if the projects depend on each other.
Some though and 3 solutions on the subject can be read on that blog:
https://www.atlassian.com/blog/git/git-and-project-dependencies
package management tool, i.e. nuget in VS, so using reference to a package/compiled module
git submodule (only with command line in VS?)
other build and cross-stack dependency tools
Another solution is just to add a project from the other repo and let it out of the current repo, and latter use the Team Explorer to commit its changes.

Effective usage of Workspaces in Visual Studio?

I am wondering what is the best way to use workspaces in visual studio. We have 150+ webservices that are all part of the same team project $/MyTeamProject without being related at all. The reason for them all being part of the same team project as they are all maintained by the same group of people within our organization.
Each webservice has the following structure
$/MyTeamProject/WebService1
$/MyTeamProject/WebService1/Main
$/MyTeamProject/WebService1/Release/1.0
$/MyTeamProject/WebService1/Release/1.1
$/MyTeamProject/WebService2
$/MyTeamProject/WebService2/Main
... etc.
I am wondering what is the proper way to use workspaces with this setup as currently there is only mapping for the teamproject so all my webservices are part of the same workspace. Should I create mapping for the main branch and for each release branch as a separate workspace or should I map each webservice to its own workspace such as $/MyTeamProject/WebService1?
Any help would be appreciated.
I can't put each of the webservices as its own teamproject as the tfs is being shared between several groups with the same magnitude of projects and therefore we are limited by our own teamproject for all of the webservices.
You said that the webservices was not related at all. I then assume that they are released separately.
I can't see any reason to use multiple workspaces in your scenario.
I suggest that you remove the mapping from the top level project "MyTeamProject". Then you have flexibility to map the subfolders to whatever local folder you want.
If you have one workspace per webservice then you will get 150*#releases workspaces. This will get really hard to manage for build versions, labelling etc. Fewer workspaces will mean less builds to manage.
I would recommend having a workspace per release. Generally you would probably only be working on one release at a time and this will allow you to manage all code for a single release effectively. Also you can then map your workspaces on the client into a more logical structure as you allude to in the question.
For example
\Projects\MyTeamProject\Main\WebService1
\Projects\MyTeamProject\Main\WebService2 ...
\Projects\MyTeamProject\Release1.0\WebService1
\Projects\MyTeamProject\Release1.0\WebService2 ...
\Projects\MyTeamProject\Release1.1\WebService1
\Projects\MyTeamProject\Release1.1\WebService2 ...
etc

Resources