-
If you are using TFS 2008 for work item tracking be sure to get most out of the tool by relating work items. Depending on the process template you are using the work item types may be different. In general terms consider linking your requirement/scenario/use cases with tasks.
If you are using the MSF for Agile template this would translate to linking scenario work item with one or more tasks required to implement than scenario.
While there is no actual work item parent/child relationship in TFS 2008 you can still construct meaningful work progress reports from a peer scenario and task work item relationship. I’ll go into more detail on how to get this project status info in a later post.
Here I want to focus on how to link work items in bulk. TFS 2008 does not have a way to bulk link work items; not through Team Explorer, not through Excel and not through Project. Darn, darn, darn.
This means if you have imported scores of work items, say via Excel, you would have to open each scenario work item in Team Explorer and manually link the associated tasks with that scenario (instructions to do this manually are here).
For most folks all this manual work would be a reasonable barrier to entry and they would just abandon linking work items and the associated project reporting benefits.
Bulk linking of work items may be better in TFS 2010. Until then I offer you the code below for a command line utility that will link a work item with one or more other work items.
Example syntax looks like this:
linkWorkItems.exe http://tfsrtm08:8080 sandbox 659 "660,661,662,663”
This would link work item 659 to work items 660, 661, 662 and 663.
One great reference I used was this link below to Shai Raiten’s blog.
Reference Link
http://blogs.microsoft.co.il/blogs/shair/archive/2008/10/06/more-about-creating-work-item-using-tfs-api.aspx
Code
using System;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
namespace linkWorkItems
{
class Program
{
static int Main(string[] args)
{
//show syntax if no arguments are passed in or user asks for help
if (args.Length < 4 ||
args[0].ToLower() == "/h" ||
args[0].ToLower() == "-h" ||
args[0].ToLower() == "/?" ||
args[0].ToLower() == "-?"
)
{
showSyntax();
return 1;
}
string serverName = args[0].ToString();
string projectName = args[1].ToString();
string parentWorkItemID = args[2].ToString();
string [] childWorkItemIDs = args[3].Split(',');
//connect to TFS
TeamFoundationServer tfs = null;
WorkItemStore store = null ;
Project project = null ;
try
{
tfs = new TeamFoundationServer(serverName);
store = (WorkItemStore)tfs.GetService(typeof(WorkItemStore));
project = store.Projects[projectName];
}
catch (Exception e)
{
Console.WriteLine("Error:" + e.Message);
return 2;
}
//get parent work item
WorkItem parentWorkItem = null;
try
{
parentWorkItem = project.Store.GetWorkItem(int.Parse(parentWorkItemID));
}
catch (Exception e)
{
Console.WriteLine("Error:" + e.Message );
return 3;
}
//iterate through child work items that we want to link to parent work item
foreach (string childWorkItemID in childWorkItemIDs)
{
//create related work item link
RelatedLink rl = new RelatedLink(int.Parse(childWorkItemID));
Console.WriteLine("Linking work item ID " + childWorkItemID + " to " + parentWorkItemID) ;
try
{
parentWorkItem.Links.Add(rl);
}
catch (Exception e)
{
Console.WriteLine("Warning:" + e.Message);
}
}
//save new links to parent work item
try
{
parentWorkItem.Save();
}
catch (Exception e)
{
Console.WriteLine("Error:" + e.Message) ;
return 4;
}
//complete
return 0;
}
private static void showSyntax()
{
string thisFileName = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
Console.WriteLine("Utility to link one or more work items to another work item.");
Console.WriteLine();
Console.WriteLine("Usage: " + thisFileName + " [Team Server] [Project] [parent work item ID] [\"child ID1,ID2,ID3\"]");
Console.WriteLine();
Console.WriteLine("Example: " + thisFileName + " http://MYTFS:8080 sandbox 559 \"560,561,562\" ");
}
}
}
If you have other ways bulk link work items let me know in the comments. Be sure to leave a comment and link to other tools that solve this same problem too.
-
I was lucky enough to have some I’d been a part of captured in a case study. The engagement was focused on Application Lifecycle Management improvements focused on people, process and tools (TFS).
The study is available at http://www.microsoft.com/casestudies/Case_Study_Detail.aspx?CaseStudyID=4000004473
When I work with a customer I’m most successful when I embed myself in their org. This helps me understand the nuances of the problem but also craft a solution that is appropriate to the organization. With a deep understanding of the organization an engineering solution can be developed that persist people and organizational changes.
-
It’s great to see the latest version of Team Foundation Server branching guide just passed 30,000 downloads. Even if you are using another source control system I think you will find plenty of the information in the guide is version control system agnostic and hopefully useful to you.
We are planning to update the guide to align the with the release Team System 2010. The revised guide will have the same content plus focus on some of the new features around branching and merging.
One area I’ve been wanting to expand on is how to secure the basic, standard and advanced branch plans presented in the guide. I’m not sure if this will make it into the revised doc so I thought I would post it here just in case.
Regardless of which branch pattern you are using from the branching guide you should have some form of dev/main/release. Below some tips you can use to secure these branches that balance security and developer productivity and also cover vendor access scenarios too. Feel free to adjust as needed depending on your needs.
Unless otherwise specified TFS Application groups should have the access type listed below. Note, FOO (how unoriginal of me) represents your TFS project.
| TFS Application Group | Access Type |
| [FOO]\Readers [SERVER]\Team Foundation valid users | Read |
| [FOO]\Build Services [FOO]\Contributors [FOO]\Core_Contributors [FOO]\Release_[xxx]_Contributors [FOO]\Vendor_[xxx]_Contributors | Read, PendChange, Checkin, Label, Lock |
| [FOO]\SCM Admin [FOO]\Project Administrators [SERVER]\Service Accounts [SERVER]\Team Foundation Administrators | Read, PendChange, Checkin, Label, Lock, ReviseOther,UnlockOther, UndoOther, LabelOther, AdminProjectRights,CheckinOther |
In Source Control Explorer start at the root TFS project level (e.g. $/FOO). Check in policy and check-in notes are stored as version control annotations at the TFS project level (I just found this out too so don’t feel bad). If users are granted access to the sources further down the source tree but not, at least read access, to the project level, then they will get errors when trying to check in. Note, users granted access to check in deeper in the source tree but not the root level, will ultimately be able to check in. However, the experience is bad due to error popup and check in policies will not be evaluated.
| TFS Application Group | Inherit Permissions |
| [SERVER]\Team Foundation Valid Users | No |
Apply to $/FOO/Dev . Use the access types for each TFS application group listed in the section above. Since we do not want the [SERVER]\team foundation server valid users group to have access anywhere in the source tree we remove inheritance at this level.
Since “dev” is really a container for child development branches we only grant access at this level to the build in server groups listed below.
| TFS Application Group | Inherit Permissions |
| [SERVER]\Service Accounts [SERVER]\Team Foundation Administrators
| No |
Applies to $/FOO/Dev/dev_xx. Permissions are set at the dev_xx level (i.e. development branches and inherits to all levels below.
| TFS Application Group | Inherit Permissions |
| [SERVER]\Service Accounts [SERVER]\Team Foundation Administrators [FOO]\Build Services [FOO]\Project Administrators [FOO]\Contributors [FOO]\Readers | Yes |
Applies to $/FOO/main – access to main is set at this level and is inherited through main. In general, only members of the Project Admin groups will be checking fixes into main.
| TFS Application Group | Inherit Permissions |
| [SERVER]\Service Accounts [SERVER]\Team Foundation Administrators [FOO]\Project Administrators | Yes |
Applies to $/FOO/release and $/FOO/release/[release name] (e.g. product 1.0). Similar to the development branch container we want to make sure the [SERVER]\Team Foundation Valid Users do not get read access at this level or below from the parent so we do not inherit permissions.
| TFS Application Group | Inherit Permissions |
| [SERVER]\Service Accounts [SERVER]\Team Foundation Administrators | No |
Applies to all release branches under $/FOO/Release/[release]/dev_sp, SP0, SP1, etc. Only members of the [FOO]\Release_[xxx]_Contributors should have access to check into the release branches. In practice, membership to Release_[xxx]_Contributors should be controlled via membership in a local group on the TFS AT (i.e. Release_[xxx]_Contributors is a local group on the TFS AT and is the sole member of the [FOO]\Release_[xxx]_Contributors TFS application group. This will assure that this is no downtime waiting for new membership to be applied via active directory.
| TFS Application Group | Inherit Permissions |
| [SERVER]\Service Accounts [SERVER]\Team Foundation Administrators [FOO]\Release_[xxx]_Contributors | Yes |
Members of the [FOO]\Vendor_[xxx]_Contributors group (where xxx is a “friendly” name for their project) should have access to only the directories that they need to do their work. This group is added to the specific directories as needed using the same access type as contributors.
The change here is that vendor permissions are not usually set at the development branch level. You have the flexibility to set these permissions in a very targeted, directory by directly way if needed.
You may want to restrict access to higher value intellectual property or core libraries. In this case you can isolate the folders where this content is in your development branch and add [FOO]\Core_Contributors and deny [FOO]\Contributors and deny [FOO]\Project Administrators. If additional security is needed for sources you may want to consider putting the sources in an offline TFS and only check in a library.
Conclusion
The presented security plan strikes a balance between security and developer productivity. It allows for all development branch activity to be controlled and the branch level. You also have the ability to restrict access to vendors or allow access to more secure sources to core contributors.
When locking down for release you control access through release specific local groups reducing any latency caused by going through a separate or waiting for active directory to reflect the security group change.
-
I recently had to create an area tree, in a TFS project, with large number (500+) of nodes. I was not looking forward to doing this manually. I had the area tree that I needed to create in a comma delimited (CSV) file so I looked around online to see if someone had a utility I could use to import the areas paths in a csv file and add these as new TFS areas in a project.
The TFS community online is so great. But this time I could not find anything really close to what I was looking for. I list some good blog posts at the end of this post that got me started using ICommonStructureService.
With these leads I created the below command line utility that will consume a file with your areas and add them as areas in your particular TFS project.
You should be able to cut and paste the code below being sure to reference the following assemblies as well.
Microsoft.TeamFoundation.dll
Microsoft.TeamFoundation.Client.dll
Microsoft.TeamFoundation.Common.dll
Microsoft.TeamFoundation.Server.dll
Microsoft.TeamFoundation.WorkItemTracking.Client.dll
Input CSV format example
Parent,Area1,SubArea1
Parent,Area1,SubArea2
Parent,Area2,SubArea1
Sample syntax
TFSAreaTool.exe [TFS Server] [TFS Project] [input csv file]
example: TFSAreaTool.exe http://TFSRTM08:8080 sandbox "Feature Areas.csv"
Code
using System;
using System.IO;
using System.Text.RegularExpressions;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.Server;
namespace TFSAreaTool
{
class Program
{
static int Main(string[] args)
{
//check and set required parameters
if (args.Length < 3)
{
showSyntax();
return 1;
}
string tfsServer = args[0].Trim();
string tfsProject = args[1].Trim();
string inputFile = args[2].Trim();
string line;
//connect to TFS
TeamFoundationServer tfs = null;
try
{
Console.WriteLine("Connecting to " + tfsServer);
tfs = TeamFoundationServerFactory.GetServer(tfsServer);
}
catch (Exception e)
{
Console.WriteLine("Error: " + e.Message);
return 2;
}
//use ICommonStructureService to access area nodes
ICommonStructureService m_css = null;
try
{
Console.WriteLine("Connecting to structure service");
m_css = (ICommonStructureService)tfs.GetService(typeof(ICommonStructureService));
}
catch (Exception e)
{
Console.WriteLine("Error: " + e.Message);
return 3;
}
//iterate through input file with list of areas
StreamReader sr = null ;
try
{
Console.WriteLine("Reading input file " + inputFile);
sr = new StreamReader(inputFile);
}
catch (Exception e)
{
Console.WriteLine("Error: " + e.Message);
return 4;
}
while (!sr.EndOfStream)
{
line = sr.ReadLine();
string[] areas = Regex.Split(line, ",");
//start with top level area path as parent
string parentPath = tfsProject + "\\area" ;
//iterate through areas listed in input file
foreach (string area in areas)
{
createArea(area, parentPath, m_css);
//parent path for next iteration is the node that we just created
parentPath = parentPath + "\\" + area;
}
parentPath = null;
}
sr.Close();
m_css = null;
tfs = null;
return 0;
}
static void createArea(string areaNode, string parentPath, ICommonStructureService m_css)
{
String node = null;
try
{
Console.WriteLine("Create Area: " + parentPath + "\\" + areaNode) ;
node = m_css.CreateNode(areaNode, m_css.GetNodeFromPath(parentPath).Uri);
}
catch
{
//any duplicate area paths will catch here. May be good to post a warning
}
}
static void showSyntax()
{
Console.WriteLine("TFSAreaTool creates TFS Area tree based on CSV formatted input file.");
Console.WriteLine();
Console.WriteLine("Input file example:");
Console.WriteLine("Parent,area1.0,area1.1,area1.11");
Console.WriteLine("Parent,area1.0,area1.1,area1.12");
Console.WriteLine("Parent,area2.0,area2.1,area2.11");
Console.WriteLine();
Console.WriteLine("Syntax: -[TFS Server] [project] [areas list file]");
Console.WriteLine();
Console.WriteLine("Example: tfsareatool.exe http://myTFSServer:8080 SANDBOX areas.csv");
}
}
}
Caveats
The catch block in the createArea method catches attempts to create areas that have already been created or fail to be created. Some additional handling here would be helpful.
Also note, if an area is created already this catch block with activate and your existing area will persist. This means you can run this script multiple times if needed to add on to your area tree without losing any existing area information.
Links to related blog posts
http://blog.benday.com/archive/2007/07/24/23153.aspx
http://blogs.microsoft.co.il/blogs/shair/archive/2009/01/30/tfs-api-part-10-add-area-iteration-programmatically.aspx
http://blogs.msdn.com/bharry/archive/2006/08/28/728333.aspx
Conclusion
I hope you find this saved you a bit of time when doing a bulk import of TFS project areas. Enjoy!
-
My colleague, Ian Ceicys (http://blogs.msdn.com/iceicys/) just pointed me to a great book on Windows Server Hyper-V. I’ve been a been late ramping up on this server role so I’m excited to get caught up. I’m reading this now Windows Server 2008 Hyper-V: Insiders Guide to Microsoft's Hypervisor: John Kelbley, Mike Sterling, Allen Stewart: Books.
My first thought is how useful Hyper-V running on a build machine could be to enable isolated testing on the build machine. I’ve always been bothered by how little utilization most build machines have. With Hyper-V running on a build machine it would be interesting to spin up virtual machines to test the product of the build. On a test failure we could save off the VM for debugging later. All this without tainting the build machine.
Something to think about. I’ll be installing Windows Server Hyper-V in the next few weeks to explore this more.
-
When switching between TFS servers (i.e. different servers not TFS projects) there can be data that is cached between projects on the 2 servers leading to some confusion in the Team Explorer UI that makes is appear you have not really changes servers.
This information applies to both TFS 2005/2008. I’m not sure how this behavior will change in the 2010 release and beyond.
To preempt any problems related to caching you may want to follow steps below when changing between TFS servers.
Changing between TFS Servers
| In Team Explorer disconnect from the existing TFS server. In Team Explorer ->Right click server->select disconnect |  |
| Close Team Explorer/Visual Studio | |
| Remove the Team Foundation local cache | 1. cd "%userprofile%\local settings\application data\Microsoft\team foundation\2.0" 2. rd /s /q cache |
| Restart Team Explorer/Visual Studio | |
| Connect to new TFS server |  |
This can be especially important if you are switching between a production and test Team Foundation Servers that have similar data.
There is no worse feeling that realizing that destructive change you thought you made in the test environment was made in production.
-
If you are attending the Microsoft technical readiness (TechReady) conference this week in Seattle please drop by one of my sessions below. I’ll be speaking with Mario Rodriguez, from the Visual Studio team, about source code branch requirements, strategies and execution in TFS.
DEVCT311-R1 VSTS Rangers TFS Branching howto
Thursday, February 5, 12:45 - 14:00, (WSCTC) 206
Friday, February 6, 13:00 - 14:15, (WSCTC) 206
Primary Track: Development Tools & Technologies
Session Type: Chalk Talk
Speaker(s): James Pickell, Mario Rodriguez
Abstract: Learn how to use TFS branching structures from basic to advanced in this educational and hands on session
Objectives: 1. identify branching requirements. 2. describe the most frequently used TFS branching strategy. 3. execute common branching scenarios.
-
Determining how long it will take to migrate source and revision history is usually tricky for me to answer accurately.
Depending on the source and destination source control systems there may be some scripts or tools to help automate the task but my expertise is that these tools usually need some level of customization.
With this in mind I stumbled onto the announcement below that the Perl source has been moved from Perforce to Git. The tools required to make this happen took over a year of part time work to develop! I do not have much more context than that. My guess is that the history and size of the code base was not the time consuming part. It was probably the development of the “layering” algorithm to get each revision from Perforce into the Git repository accurately.
In true open source style, Sam Vilain converted Perl's history from
Perforce to Git. He did the work both in his spare time and in time
donated by his employer, Catalyst IT. He spent more than a year building
custom tools to transform 21 years of Perl history into the first
ever unified repository of every single change to Perl.
use Perl | Perl 5 now uses Git for version control
When I’m asked by an organization to move sources from one source control system to another I quickly confirm if source history needs to be moved as well. This may seem like a firm requirement in all cases but when balanced with the additional time required to move the history most organization see more value in brining over a current snap shot of sources and leaving the old repository online (but read only) for to review history and servicing. Depending on the product, dev culture and servicing requirements the old repository can be moved to offline storage after some time.
-
If you use any sort of source control system you will find this TFS Branching Guide available at http://www.codeplex.com/TFSBranchingGuideII useful. There is some Team Foundation Server specific content and labs but the main branching guide is source control agnostic and presents proven branch plans.
Following the guidance in the guide you should be spend more time writing features, finding bugs and shipping software instead of exploring new and unusual ways to branch your source code.
Enjoy and be sure to post any thoughts you have on the project in the discussion section at http://www.codeplex.com/TFSBranchingGuideII/Thread/List.aspx.
btw – I was one of the authors of this branching guide so I’m not exactly and impartial reviewer.
-
Here are some steps you may want to take to around planning downtime for your Team Foundation Server h/w.
Proxy – can be rebooted at any time. Users will pass through to the App Tier as long as the proxy is offline.
Build – Mark the build agents associated with this machine as “unavailable,” make sure no builds are in progress, then reboot. After reboot mark the build agents to active.
App/Data Tier – if either of these are offline users will get unexpected behavior. The error messages in TFS can be cryptic so its best to schedule downtime for these boxes. As you approach the downtime be sure to “drain” the build machines by setting all build agents to “unavailable.” Once in your scheduled downtime window you want to make sure you have not builds running. Reboot the AT and or DT during your scheduled downtime window.
I’d recommend the only required notification be the AT/DT downtime. 1 week, 2 day, 1 day from reboot is good policy. Alternatively, some teams will just budget a 2 hour window every Sat or Sun for maintenance and just advertise that the TFS h/w may be offline during this time. You do not have to use the time but it gets the org “trained” to know that the ops org uses that time for work.
You can run TFS h/w with multiple 9’s of uptime if needed. However, in practice, scheduling downtime make the operational tasks less expense since you have a fixed time each week you can do your work instead of treating downtime as a special event that required huge planning (and expense).
-
"Visual Studio 2010 == happiness" is from one of the VSTS 2010 talks today. I expected more buzz around Windows Azure but talking to folks in the lounge, at lunch and over coffee there is huge interest in some of the new features in VSTS 2010 especially in the improvements around testing and architecture.
It's tricky talking up features of your v-next product without cannibalizing sales of your current release. One way to generate interest about the next release while encouraging adoption of the current release could be to publish an "investment map" that shows between 2 releases what scenarios have been enabled or changed.
For a highly customizable product like Visual Studio a consumer they could use the investment map information to continue customization in an are that has been advertised as "no investment." Like wise they could abandon investment in areas that have been identified as high investment in a future release. I'm still baking this plan.
The PDC focus tomorrow shifts to Windows 7.
-
I jumpstarted my PDC experience this year by attending a pre-conference talk on Agile Perspective; Industry and Microsoft. I was surprised to see such strong turn out on a Sunday. There appeared to be about 200 people at the talk.
Many times I need to hear something several times before I have an "a-ha" moment. Today I really internalized that Agile software development gives you a big toolbox of development methodologies (i.e. XP, scum, TDD). However, the unit of agile adoption is really at the methodology level. To be "agile" you need to be using at least one of the agile methodologies... not really all of them. However, when you use one of the agile tools (e.g. scrum) adoption needs to be 100%. Adopting only parts of, say, scrum, just make a mess and will not get you any of the team work, adaptability and quick response to change that you may want.
-
I'm in Los Angeles this week to attend the Microsoft Professional Developers Conference (PDC). My personal PDC goal is to focus on how partners supplement our Microsoft ALM offerings. I'm especially interested in seeing complimentary and competitive offerings to Visual Studio Team System.
I'll be posting some PDC thoughts this week via twitter (http://twitter.com/jampick) and post blog updates each evening.
-
Below is a branch plan that I've used before that enables servicing a released product with hot fixes, a cumulative service pack (SP) and enables next version work in main and the development branches. This is also simplified version on the branch plan used for Windows development at Microsoft but could also be useful in your organization if you have similar servicing requirements.
Branch planning, like many aspects of application lifecycle management, does not have canned solutions that work for everyone. I'll step through the details of this branch plan and hopefully parts of this will apply to your project and a starting point for your own solution may emerge.
Goals
This branch plan enables concurrent hot fix, SP and v-next development. It also ensures that changes can be checked into on branch and merge into branches of future releases.
A by-product of this plan is that you should see fewer regressions from "lost" changes and reduced merge conflicts since changes are checked into one branch.
This post does not go into much detail on check in policies, quality gates or build frequency. For that information you may want to start with the branching guidance on codeplex.com or look for later posts here in those areas.
Definitions
These definitions are used in the graphics for this branch plan. The definitions I provide below are a bit more generic than the official MS servicing definitions. Hopefully these broader definitions will make this branch plan apply to more situations.
- Development branches - child branches of main where developers work on the current on future versions on your product.
- Hot Fix - these are specific fixes required to unblock a specific customer blocking issue.
- Main - this is the junction between the development and production branches. For most organizations this is the "golden" branch that should be very stable.
- Production/release branches - child branches of main where servicing (i.e. hot fix and SP) check-in's are made.
- RTM - release to market, this is the branch that has the sources for your final release.
- Service pack - a cumulative package of hot fixes and updates targeting a previously released version on you product.
- V-next - the next version of your product.
Release vehicles
The release vehicle is how code leaves your organization. For any branch plan to work you must define precisely the different ways that code leaves your org and gets to a customer. In this example we have 3 release vehicles.
- Major release (RTM)
- Hot fixes for a major release
- Service packs for the major release
Once the release vehicles are defined you build a branch plan around these that enables code to be checked in once and merge back to main.
Branch plan in action
From development to main there should be regular forward (FI - parent to child) and reverse (RI - child to parent) integrations. Once the code in main has reached some objective measure of release quality (e.g. bug count, test pass %, preview feedback, etc.) then it is time to create the production/release branch for this release.
The key to this branch plan is that the SP, Hot fix and RTM branches must be created in order to assure the parent child branch relationship is maintained.
In TFS the physical layout of the release branches would look like this.
$/project
$/project/development/dev_team1/source (branch from main/source)
$/project/development/dev_team2/source (branch from main/source)
$/project/development/dev_teamX/source (branch from main/source)
$/project/main/source
$/project/production/V1/SP/source (branch from main/source)
$/project/production/V1/HF/source (branch from release/V1/SP/source)
$/project/production/V1/RTM/source (branch from release/V1/HF/source)
If the spaces format correctly, you should see that the production branches SP, HF and RTM are children of each other. In the production branches the further from main the branch check in policy is usually more restrictive.
Once the production branch plan is created main and the development branches move on to "next version" work. In this example we will call this V2.
Any changes for the V1 release happen in the appropriate branches based on the specific criteria below.
- Ship stopping bug fix for v1 RTM - check in to production/V1/RTM (mark this branch read only after release)
- Hot fix for v1 release - check in to production/V1/HF
- SP 1 work - check in to production/V1/SP
- V2 work - check in to your development branch
Changes should be RI'd in from RTM->HF->SP->main only. This will ensure future releases are regression free as fixes will integrate into the next cumulative release (i.e. all hot fixes will be merged into the next service pack). Do not FI changes from main to SP after the initial release branches are created. An exception may be for merge specific change sets as needed for a HF or SP release.
This plan also supports n service pack releases and hot fixes for those service packs by branching from the SP branch.
$/project/main/source
$/project/production/V1/SP/source (branch from main/source)
$/project/production/V1.1/HF/source (branch from production/V1/SP/source) <-V1 SP1 hot fixes here
$/project/production/V1.1/RTM/source (branch from production/V1.1/HF/source) <-V1 SP1 release here
$/project/production/V1.2/HF/source (branch from production/V1/SP/source) <-V1 SP2 hot fixes here
$/project/production/V1.2/RTM/source (branch from production/V1.1/HF/source) <-V1 SP2 release here
Conclusion
This is a specific branch plan that enables concurrent hot fix, service pack and v-next releases. Each branch is associated with a release vehicle to give the developers checking in a clear map of where their changes should be checked in depending on what release they are working on.
This plan also allows for a single check in to have a clear merge path to main to reduce regressions and merge conflicts.
Also, having a strong association between your branches and the release vehicles will keep the whole organization aligned on very specific releases and expose work that is not focused on a particular release.
If you product has similar release vehicles and servicing requirements then this plan may be a good start point for you.
Reference
TFS branching guidance http://www.codeplex.com/BranchingGuidance
Microsoft servicing terminology http://support.microsoft.com/kb/824684
-
There are many posts and deep thoughts on source code branching but little advice on how deep you should go into putting your build dependencies under source control.
Since I've not seen any general guidance on managing build dependencies I'll offer the following based my experinece:
Check in build dependencies rather than installing them on the build and development machines.
Any dependency that your build process has that is not under source control will undermine the benefit you get from branching.
The range of build dependencies that I'm calling out for you to check in usually fall into the 3 categories.
- Source – developer owned code that is required to create your product components. May include compiled and non-compiled code.
examples: c, c#, wix, sql scripts - Tools/Applications – executables, build tools and scripts required to transform the source code in to the product that can be shipped to test (ideally the same as what is shipped to your customer)
examples: compilers, build scripts, packaging (MSI, CAP, ZIP) tools - Libraries – SDK’s and 3rd party libraries
examples: headers and libs from windows SDK, .net framework
Several changes fall out from this since I'm recommending that all you need is an OS and your source code branch to build you product.
For managed code developers this means checking in the .Net framework and using the HINTPATH attribute in your proj files to refer the the checked in assembly instead of assuming you have it available in the GAC.
This also means that you may also want to steer away from tools that do not have an xcopy style deployment. Look for tools that offer a "stand alone" build or silent modes.
Once your build dependencies are under source control they can be branched with your product code. This will create a standard build environment, identify all of your projects dependencies and simplify servicing.
Standardized build environment
Having all dependencies under source control will assure that each individual developer build and the official builds are building using the same build environment. This will reduce the number of defects introduced from mismatched environments (i.e. “it builds on my machine…”).
Known set of dependencies
A secondary benefit of being able to build from a clean OS install is a complete understanding of your product dependencies. If there is a security defect, licensing or IP question related to a component your product depends on you can sync to the source tree and reliably enumerate through every components available at build time and take appropriate action.
Simplified servicing
Installed applications on a build machine can’t be branched. This means that even if you branch your source code for release, defects could be introduced as newer versions of applications are installed on the build machine.
Fear the magic build machine!
When dependencies are not understood some teams will marry a single machine for each release branch they maintain. This is not a good strategy as this is the first step in creating a build system that is only reproducible on a particular machine (i.e. the "magic" machine).
The servicing window for products is increasing as many businesses are seeing 7-10 year servicing windows. Relying on a particular machine (physical or virtual) to reproduce your build over that timeframe introduces unneeded risk.
What if I can't check in everything?
For many products is may not be feasible to change applications that are installed on the build machine to alternate apps that can be checked in. In this case I recommend that you document and automate the build machine setup.
Test your build machine setup by following the steps in your setup documentation on a clean OS install. Then build your product from a known state (i.e. your last release) and run the associated test pass against it. Most errors associated with an improper build machine setup generate a build break instead of more subtle run time defects.
Once you have confirmed the setup document is accurate treat this just like source code and check it in and branch it with your product releases. Also, make sure all build and dev machines owners use this document for machine setup and update as needed.
An optional step is to fully automate the build machine setup by using the unattended install of applications that must be installed on the build machine.
Consider checking in the binaries of the applications you need into source control as well. This may not be feasible considering the size of the application. The main cost and inconvenience here would be having each developer in your org having to sync these large install files so consider removing these from the standard client work space.
Summary
In addition to your sources, all tools, libraries and applications that your product depends on to build should be checked into source control. Relying on machine state and installed applications undermines the benefit of source code branching. Once all of your build dependencies are under source control you will benefit by having standard build environment, known project dependencies and simplified servicing. Dependencies that can not be checked in should be documented and their install automated.