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
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:
<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):
- //The _Server variable is provided from the build definition
- TeamFoundationServer tfs = TeamFoundationServerFactory.GetServer(_Server);
- VersionControlServer vcs = (VersionControlServer)tfs.GetService(typeof(VersionControlServer));
- Workspace workspace = vcs.CreateWorkspace(“VersionWorkspace”, vcs.AuthenticatedUser);
- string localPath = Path.Combine(Path.GetTempPath(), “TFSVersionUpdate”);
- string localFilePath = Path.Combine(localPath, “VersionFile.cs”);
- WorkingFolder folder = new WorkingFolder(_FilePath, localPath);
- workspace.CreateMapping(folder);
- workspace.Get();
- workspace.PendEdit(localFilePath, RecursionType.None);
- //Call update function
- _ChangeSetId = “C” + (workspace.CheckIn(workspace.GetPendingChanges(), “Automated build number update”)).ToString();
- workspace.Delete();
- return true;