How to override the TFS Build number and force TFS to include files changed during the build

I had an interesting problem today.  My current client uses a custom file to store build numbers in their application and that file gets used to show the number in a couple of places in the app.  TFS defaults its build numbers to _YYYYMMDD.# format, which was confusing when we were dropping the files to the build directory.  They used to have a manual process where they would physically change the revision number on this custom file before each build.  I automated that process with MSBuild/VSS a few months ago, so I had to tweak the custom task to work with VSS.  TeamBuild has a target called BuildNumberOverrideTarget, which does exactly what its name says, override the build number before all the build *stuff* happens.  So within that target, I can call my custom task that changes the file with the new version number (basically, looks at the old version number and increases it by 1).  Once you have your version number, you set the BuildNumber property, which is then used by TFS in the build process.

TeamBuild figures out the last checkin before the build started and uses that to label and get latest.  Since I am making a change to a source controlled file from within the build, my changes were not making it to the build.  For that, I had to set the changeset number that TFS should use as a reference.  I made a change to my custom task so that it returns the changeset ID for my checkin.  You then need to set the GetVersion property, which is also defined by Microsoft.TeamFoundation.Build.targets, which is the default target used by TFS.   So my target looks like this:

<Target Name = BuildNumberOverrideTarget >

    <AutoUpdateVersion Server=$(TeamFoundationServerUrl)>
      <Output TaskParameter=Major PropertyName=MajorNumber />
      <Output TaskParameter=Minor PropertyName=MinorNumber />
      <Output TaskParameter=Build PropertyName=BuildNumber />
      <Output TaskParameter=Revision PropertyName=RevisionNumber />
      <Output TaskParameter=ChangeSetId PropertyName=GetVersion />
    AutoUpdateVersion>

    <PropertyGroup>
      <BuildNumber>$(MajorNumber).$(MinorNumber).$(BuildNumber).$(RevisionNumber)BuildNumber>
    PropertyGroup>
  Target>

In order to interact with TFS source control from code, this is what you need to do:

  • Add references to Microsoft.TeamFoundation.Client, Microsoft.TeamFoundation.VersionControl.Client, Microsoft.TeamFoundation.VersionControl.Common
  • Connect to TFS
  • Create a Workspace on the build machine
  • Set a working folder for your workspace
  • Get latest to the working folder
  • call PendEdit(), which basically checks out the file. 
  • Call your function to update the file
  • Call CheckIn(), which returns the changeset ID

Here’s a code-snippet (simplified for demo purposes):

  1. //The _Server variable is provided from the build definition
  2. TeamFoundationServer tfs = TeamFoundationServerFactory.GetServer(_Server);
  3. VersionControlServer vcs = (VersionControlServer)tfs.GetService(typeof(VersionControlServer));
  4.  
  5. Workspace workspace = vcs.CreateWorkspace(“VersionWorkspace”, vcs.AuthenticatedUser);
  6. string localPath = Path.Combine(Path.GetTempPath(), “TFSVersionUpdate”);
  7. string localFilePath = Path.Combine(localPath, “VersionFile.cs”);
  8.                                                 
  9. WorkingFolder folder = new WorkingFolder(_FilePath, localPath);
  10. workspace.CreateMapping(folder);
  11. workspace.Get();
  12.  
  13. workspace.PendEdit(localFilePath, RecursionType.None);
  14.  
  15. //Call update function
  16.  
  17. _ChangeSetId = “C” + (workspace.CheckIn(workspace.GetPendingChanges(), “Automated build number update”)).ToString();
  18. workspace.Delete();
  19.  
  20. return true;

About esteban

Esteban is the Founder and Chief Technologist at Nebbia Technology, an ALM consulting and Azure-powered technology company. He is a software developer with a passion for ALM, TFS, Azure, and software development best practices. Esteban is a Microsoft Visual Studio ALM MVP and ALM Ranger, Pluralsight author, and the president of ONETUG (Orlando .NET User Group).

One thought on “Error when installing SQL 2008 on Windows Server 2008 R2 (64 bit)

  1. Mark Allen

    Another approach which works well is to have the XML tag reference a custom TFS group. In my case there is a master contributor group shared between projects so rather than list all the contributor users in the template AssignedTo list boxes I created a TFS group called ‘TeamAssignments’ and within security I referenced the team. Then in the templates I added the tag ListItem value=[project]\TeamAssignments. Now when anyone is added to the team they are displayed in the AssignedTo List box. This also means that another team can be created without changing the templates as the changes can be done in security.

    TFS Team Name: Blue (example set up in security)
    TFS Group Name: TeamAssignments
    Members: Team Blue


Leave a Reply

Your email address will not be published. Required fields are marked *

Are you human? *