TFS 2010 project structure and getting the best out of it - version-control

we recently decided to move to TFS 2010. we would like also to improve our source control structure and projects structure.
here is the structure the team agreed on:
|OurCompanyName (or common root name)
|
+--Windows
+----Applications
+------App1
+------App2
+----Services
+------WindowsService1
+------WindowsService2
|
+--Web
+----Applications
+------WebApp1
+------WebApp2
+----Services
+------WebService1
+------WebService2
|
+--Common
+----ThirdParty
+----Libs
+------DataAccessLib
+------BusinessLogicLib
|
+--Tests
+----TestProject1
+----TestProject1
The common folder holds 3rd party and our in-house libraries which is used all-over(App1,App2,WebApp1...etc)
We need to acheive the following :
Release versions must depend on latest production release of Libs.
if tests failed, depended projects shouldn't build and team should be notified.
simple branching: development, production,versioned releases and how we can structure them accordingly.
I have already read the following guide Visual Studio TFS Branching Guide 2010 but it only addresses the branching bit of it.

You aren't really asking a question from what I can tell. But I can give some feedback/discussion on your goals.
Release versions must depend on latest production release of Libs.
A release version should depend on whatever it used while it was being developed. Not whatever the current version is. You may want to go into more depth on what this requirement is and why you think you need it.
if tests failed, depended projects shouldn't build and team should be notified.
TFS doesn't support chaining builds out of the box, you can modify the build template to add support, but it's not a particularly clean solution (imo).
You can self subscribe to failing builds utilising the built in tfs alerts subscriptions, however it is up to each developer to do so. (Unless you subscribe a mailing group or create a custom event mailer).
Again why are you automatically updating dependencies in other projects? surely you'd be better off using a pull for updates than a push and use a technology like NuGet to handle your references.
simple branching: development, production,versioned releases and how we can structure them accordingly.
That sounds like simply branching each time you do a release, which is very simple.
If you however knew which changeset you releases you wouldn't have to branch and could branch only if you needed it (eg to fix a production bug). It takes a lot more work as you either need to manually label your code on release (at which point you gain nothing over branching) or have an automated release process which does it for you.
Other notes
You dont' want to use multiple Team Project Collections - this adds in a nightmare when it comes to managing build servers.
You may want to update your diagram to show what is a Team Project, Branch, and what is just a standard folder.

Having used TFS for a while, I would like to give a caution:
You look at things from the developer's side, as we did when we started thinking about how to best deploy the projects. However, you should also take under account project management requirements.
Having different TFS projects, means different reporting data to the manager.
Thus if App1 and WebApp1 are to the person that runs your projects part of the same overall project, then if you have them in different TFS projects, questions of the form: 'How many hours did my team spend on this project' will be difficult to answer.
I would seriously look into this issue before deciding on the project structure.
Now regarding your questions:
Release versions must depend on latest production release of Libs
As Betty (above) mentions this is not good practive. What will happen if development took place with production release of Lib v1.0 and sometime during stabilization Lib changed to v2.0 ?
if tests failed, depended projects shouldn't build and team should be notified.
I believe this is a matter of your build script, not of your layout
-simple branching
We try to implement a simple MAIN-line based approach,where we have one or more development branches (depends really on your specific requirements).
Once in a while, when dev code is considered 'stable' i.e. passed basic unit tests, it is merged onto the MAIN line. Developers carry on, on their development branches whereas code on the MAIN line goes more extensive testing. Bugs found are reported and fixed initially on the DEV branches and merged back onto the main line. Once code on the MAIN line is good enough, stabilization starts on a RELEASE branch. After that point, bugfixes take place on the RELEASE branch and merged back into the MAIN line. Note that 'stable', 'good enough' are values that mean different things to organizations.

Related

Buildfile with trunk/branch or separate

The issue that I am trying to figure out is whether it is best to keep the buildfile together with the source code, i.e. trunk and branches, or in some separate location (obviously still under SCM).
The question: (to keep in mind while reading the rest of the text) Buildfile that ensures branch re-buildability at any time (at expense of maintenance), or one that ensures latest bugfixes/improvements (to build process) are quickly used by multiple branches and different projects (at expense of backward compatibility with older branches)
It doesn't matter what we are building, or what technologies are used, but just for the sake of completeness: making a mobile application, building/packaging with ANT, using SVN for SCM.
Buildfile = instructions for your builder/compiler/packager to compile and package an application from source.
Buildfile with code
This is what we have right now. Ant's build.xml is stored alongside the main code in SVN. A number of other supporting "packaging" files (Apple's provisioning profiles and certs) are stored there as well.
Pros:
Single checkout from DEV perspective. When developers checkout the trunk or one of its branches, the buildfile is right there. They don't need to search for it elsewhere. A simple ant build after checkout is all they need.
When changes to the build/packaging process are done on trunk that require some reorganization in code (different file locations, support for compiler constants, etc), I need not worry about breaking existing branches, since each branch gets its own revision.
Cons:
When changes to the build/packaging process are done on trunk that improve the process and fix bugs, I now need to worry about merging those changes to all active branches, which means having to keep track of all dev/feature branches in addition to release branches.
No reusability. A technologically identical project, that only requires a few switches/property changes to the buildfile should be able to use identical buildfile. But because they are spread across multiple project locations (in addition to multiple branches, as from the point above), it becomes a nightmare to do a generic improvement that affects all those locations. Mainly due to the fact that no matter what, these files end up with little "patch-works" here and there, and eventually with conflicting merges and ever-so-slightly different processes that cannot be resolved without putting one of the projects on hold and modifying that process to "catch up" with the other.
Buildfile separate from code
To address the cons of the previous scenario in regards to re-using a single file and avoid a plethora of small fixes all over the place, I was thinking of keeping the build file separate. Shareable between the trunk, branches and other similar projects.
Pros:
Single file to modify, improve and bugfix, reusable by multiple other projects.
Cons:
No "single checkout" for DEVs (but it can be solved with svn externals or other linking solution
Breaking old/existing builds. Since there is only one version of the file now, introducing an improvement that requires code restructuring would make it incompatible with older branches. When that older branch needs to be rebuild (urgent fix to already released software), the build file will no longer work. Yes, it's solvable by getting a previous revision of the file, however:
It is not directly obvious which previous revision had worked with this branch
The older revision may be missing some other critical bugfixes to the build process.
Toss up question
So for me it is a toss up between making my life easier and only maintaining one file for bugfixes and improvements, and thus ensuring that projects use identical processes, latest bugfixes to the build process, etc. Or making developer's life easier by providing a single point of checkout, and ensuring branch "stability/re-buildability" because the buildfile that's checked in with the branch is guaranteed to work with that branch.
Is there a proper way for this? What is the proper way for this? Am I approaching this wrong?
I would suggest tagging your code with a version number every time you build. IF you ever want to roll back to a revision , you can always create a new branch from the tag of that revision and use the build.xml from that revision
You can also publish all your artefacts into a revision named directory. If you want to rollback you can just use the artefacts from this directory instead of going through the build process again .
Your build file should always be part of your code . That way a developer can check out his/her code into an IDE and start building from there for his local testing.
If you have env related configurations that are different per environment you should separate it out into a deployment configuration that is used when the code is deployed.
If you want to reuse your build files across projects , you can create a master build file with macros that is fetched prior to starting a build. The only thing you need to do is override the macros in your local project if you want to override the default behaviour

Keeping track of changes in Dev Branch

I recently started taking an interest in using a branching model similar to Vincent Driessens Git branching model. We have multiple developers working on the same project so using different branches for different features is a big plus for us. The model states that after a feature is developed, it is merged back into the Development branch, and on a certain time a release branch will be created from it.
Now my problem is that I don't know who added what to the dev branch since the last release, but I do want to present a list of changes that will be implemented for the next one. So the question is, how do I know what features have been added to the dev branch?
We're using TFS for version control. As far as I know I have the following options:
Better labeling and commenting of versions (currently there is no labeling and little commenting)
Linking TFS tasks to versions (not sure how to create a nice list of that yet though)
Maybe I should just follow my own options above but I was curious about how you guys deal with this.
First I would suggest you take a look at the TFS Branching and Merging Guide as it will likely answer most of your questions.
how do I know what features have been added to the dev branch?
I think the "develop" branch in Driessen's model is most closely equated to the "main" branch in the TFS guidance. I would suggest that you shouldn't merge changes into main unless they are already planned to go into the next release. Then when you are ready to release you simply branch from the latest version of main.
Keeping track of what features are intended for the next release is something that would be handled by the work item tracking system.
Separately, you may find the Track Work Item feature of Team Explorer to be helpful.

Branching and Merging Strategies

I have been tasked with coming up with a strategy for branching, merging and releasing over the next 6 months.
The complication comes from the fact the we will be running multiple projects all with different code changes and different release dates but approximately the same development start dates.
At present we are using VSS for code management, but are aware that it will probably cause some issues and will be migrating to TFS before new development starts.
What strategies should I be employing and what things should I be considering before setting a plan down?
Sorry if this is vague, feel free to ask questions and I will update with more information if required.
This is the single best source control pattern that I have come across. It emphasizes the importance of leaving the trunk free of any junk (no junk in the trunk). Development should be done in development branches, and regular merges (after the code has been tested) should be made back into the trunk (Pic 1), but the model also allows for source to be patched while still under development (Pic 2). I definitely recommend reading the post in its entirety, to completely understand.
Pic 1
Pic 2
Edit: The pictures are definitely confusing without words. I could explain, but I would basically be copying the original author. Having said that, I probably should have selected a better picture to describe the merge process, so hopefully this helps. I'd still recommend reading the post, however:
The simplest and most usual way I've seen branching work is off two premises. Trunk and Release. I think this is known as the "Unstable trunk, stable branch" philosophy.
Trunk is your main source. This contains the "latest and the greatest" code and is forward looking. It generally isn't always stable.
Release is a one-to-many association with trunk. There is one trunk but many releases that derive from the trunk. Releases generally start with a branch of the trunk once a particular functionality milestone has been hit so the "only" things left to go in for a particular deployment should just be bug fixes. You then branch the trunk, give it a label (e.g. 1.6 Release is our current latest Release), build and send the release to QA. We also push the version number (usually the minor number) of the trunk up at this point to ensure we don't have two releases with the same number.
Then you begin the testing cycle on your release branch. When sufficient testing has been perfomed you apply bug fixes to the release branch, merge these back to the trunk (to ensure bug fixes are carried forward!) and then re-release a build of the branch. This cycle with QA continues until you are both happy and the release is finally given to the customer(s). Any bug reports from the customer(s) that are accurate (i.e. they are a bug!) start another QA cycle with the branch in question.
As you create future releases it is a good idea to also try to move older customers onto newer branches to reduce the potential number of branches you might have to back-patch a bug fix into.
Using this technique you can deploy solutions using your technology to a variety of customers that require different levels of service (starting with least first), you can isolate your existing deployments from "dangerous" new code in the trunk and the worst merge scenario is one branch.
My first recommendation would be to read Eric Sink's Source Control HOWTO - specifically the branches and branch merge chapters.
We have 3 containers - DEV, MAIN, and RELEASE for our work. MAIN contains all our "ready-to-release" code and we tend to think of it as "basically stable." DEV/Iteration (or DEV/Feature, or DEV/RiskyFeatureThatMightBreakSomeoneElse) are branches from MAIN and are merged up when the Iteration/Feature is ready to promote up past the DEV environment. We also have TFS builds set up from the DEV/Iteration branch and the MAIN branch.
Our RELEASE container contains numbered releases (similar to the "tags" container used in many Subversion repositories). We simply take a branch from MAIN each time - I like to say we're "cutting" a RELEASE branch to signify this shouldn't have a lot of activity going on once the merge is finished.
As for VSS->TFS - Microsoft supports an upgrade path which should keep your version history, but if you don't need it the history, I would just get the latest version from VSS, check it into TFS and archive the VSS repository.
One final tip - get your team members familiar with source control. They must understand branching and merging or you will be stuck doing a lot of cleanup work :).
Good luck!
The subversion book describes some common branching patterns. Maybe you can also apply these to TFS.

Best practices, building trunk against trunk?

We have many projects that use a common base of shared components (dlls).
Currently the development build for each project links against dlls built from the trunk of the components. (ie trunk builds use the dlls from other trunk builds)
When we do a release build, we have a script that goes through the project files and replaces the trunk references to specific numbered versions of the components (that are built from a tagged branch)
I think this weakens the testing that we do during development because the project that I am actually working on is using diferent dlls to what the release build will be using. I would like to always develop against the numbered versions of the components and only ever update them when there is a specific need.
However others in the team argue that unless we develop against trunk (and update to the newer versions of the components with each release) we will have the problem that (a) our products will hardly ever update to the newer version of the components then (b) when we do need to update it will be a huge task because the component source/interfaces will have changed so much.
What practices do you follow, and why?
Edit: Sorry all, I have just realised I have confused things by mentioning that there are several main products sharing components - although they share the components they don't run on the same PCs. My concern relates to the fact the because the components are likely to change with each release of a product (even though there was no specific requirement to update the component) that testing would miss some subtle change that was done in a component and not related to the specific work being done on the product.
Hmm, I may be in a minority here, but this comes down to release management.
Developing against the trunk of a set of shared components means, by definition, that the components are a "moving target" -- a developer using those shared components won't necessarily know if a newly found defect or failure is due to the project code or the shared components, which leads to a loss of productivity, IMNSHO.
The "shared components" have a release cycle all their own. Give your other developers a break and fix the version of the shared components that the projects are going to use and use tags, labels or branches to identify the shared component release. On the next iteration for the projects, bump up to the latest "stable" or "production" build of the shared components.
There's another "smell" here, if you'll pardon the expression. Having "shared components" whose "source/interfaces will have changed so much" between project releases sounds like the components aren't so solid or shouldn't necessarily be shared.
See also the answer to this question Shared components throughout all projects, is there a better alternative than svn:externals?
You should have strong interfaces that rarely change, so changing versions shouldn't be that hard.
Separating the versions and working against specific versions will increase overhead when you need to change, but it should also encourage less interface changes overall, which will help in the long term.
We develop against multiple branches and trunk simultaneously and we have chosen to build and test each branch with the code we'll be pushing out to production. I don't think it is safe any other way.
Basically, if a developer is working on trunk, all they have to do is worry about building from trunk and committing code to trunk.
Any developer working on a branch needs to build and test off that branch (there are multiple projects all branched/tagged the same build/release). When they commit changes to that branch, they must also merge those individual changes into trunk.
We expect all developers to be familiar with SCM (SVN) and to be capable of maintaining multiple branches of code. As a team we handle major framework shifts or huge code changes to minimize troublesome merging.
Two things here. First, I think you're right; you want to build against the most current development versions, not against the old versions. If you haven't already, you will see a situation in which the build-for-release blows up and you have to do an all-nighter cleaning up the diffs.
I'm personally a fan of the "commit to trunk, release from branch" model anyway. All commits go to the trunk, overnight builds or CI builds are against the trunk, and people create branches freely. When you have a trunk that meets acceptance criteria, tag a release candidate, BUT KEEP MAKING UPDATES TO THE TRUNK. If you hae a long release cycle, then you might have changes for release n+1 being added to the trunk, but ideally you should just shorten your release cycle instead. If there are changes to the trunk that shouldn't be in the released version, AND you have a problem that requires changes, create a branch against the tagged version --- and make sure you merge any changes back to the trunk once you have an actual release.
We are using the scons building system, and have our own file in the root directory which specifies what version of each library we're going to use when building the application.
That reduces the need to change version names in several locations like you mentioned.
Whether (b) is a valid argument depends on how often your shared components change and by how much. If they change often in your workplace, it might be a valid that you are "forced" to develop off the newest version. Whether that in itself is a problem is a valid question.
However, from your side of things, I don't see how you can push code into production without it being tested against the shared components being used in production. Do you do a second test cycle against the release build? Do you just pray that nothing breaks? Frankly, (b) can be reversed in these cases to support your point of view: If the trunk is different enough from the most recent tagged branch, then that effort has to be made to ensure your app works properly with it.
If your shared components are tagged often enough, then your colleagues are probably right, and it's easier to manage the incremental changes from the most recent tag to the trunk than it is to manage the change from arbitrary version X (determined at the last build) to arbitrary version Y (determined when you choose to upgrade).

Using separate TFS projects for source control and work item tracking, is this a good thing?

I have a client who is using one TFS project just for source control only and now wants to manage work items in a totally different TFS project, using a different process template, and intends to link changesets to work items across TFS projects.
I know that this is possible in TFS, but don't know what the limitations or issues that come with this configuration. e.g Build Summaries, Reporting, etc.
I would prefer branching the code into a new TFS project and managing code and work items together in one project, but need to know how the above method stacks up.
It'll work - I've occasionally had to associate checkins with work items from other projects. I haven't noticed any issues with reports or the like, that said this seems like an overly complex arrangement with little benefit.
Seems like a strange set-up to me. While it will work, TFS is designed for the check-ins and work items to be in the same team project so you won't really get the full benefit of the TFS features. Does the client know that they can modify the process template of the existing team project or do what you say and branch or even just move the source into a new team project.
We used this model to allow us to have separate projects but against the same source branch. It worked for a while but once we started being more adventurous with branches the model broke down. So as others have noted, there's no reason why technically you can't do this, it's not standard.