| Mike 的个人资料FreeToDev日志列表 | 帮助 |
|
11月7日 Versioning Code in TFS - RevisedThis is a revised and combined post covering the two previous posts, Versioning Code in TFS Part 1 & Part 2. If you haven’t read those two posts, then this revised post is all you need to read. If you have read the two previous posts, then although similar, I recommend you read this revised post as it contains important corrections, updates and clarifications. Note that this post mostly relates to TFS 2008, though the concepts implied are not tied to a specific version of TFS. ____________________________________________________________________________________ The ProblemI’ve lost count of the number of blog posts, forum questions and internal emails that I have seen regarding problems with versioning assemblies in TFS. I believe the root cause of the problem is that many users have tried to migrate their existing versioning logic and code to work with TFS, blinded by the wealth of functionality that TFS has brought to the development process. The Truth
Some BasicsWhat is Versioning?Versioning refers to the process whereby code is compiled and ‘stamped’ with a version number that can distinguish it from previous or future builds of that code. What is a version number?There are two version numbers in .Net, the AssemblyVersion and the AssemblyFileVersion. Both follow the same format:
My first piece of advice is that you don’t keep the two in sync. The AssemblyVersion should rather be of the format:
The reason for this is that strong name signatures include the AssemblyVersion, which means that if you release an updated assembly, the code that references it will need to be updated too (unless you go the publisher policy route, but let’s try keeping things simple). The AssemblyFileVersion is the attribute that should be updated with every build you perform, and therein lays the problem. How? I would estimate that in 99% of builds, the format of the build number will be
The Static parts are easy and they will most likely equate to those used in the AssemblyVersion. The calculated part is really up to you. It could be a date format e.g. mmdd or possibly the number of days since a given milestone date etc. The iterative part is where the trouble lies. All versioning tasks need to provide the same essential logic. They need to calculate your build number and provide a unique incremental value for every build. To ensure that the incremental value is unique, most versioning solutions check out a file, alter it and check the file back in. Lots of people including myself first used the AssemblyInfo task (which has now been included in the MSBuild Extension Pack), and encountered numerous painful ‘cannot determine the workspace’ errors, or you were likely to be caught by check-in policies or duplicate attributes. All issues can be resolved, but too many people have had a hard time using this task for versioning. It’s a great task, but not for versioning. If you managed to get around the AssemblyInfo task issues, or your own problems with creating a task that checked out a file, incremented the value and then checked it in again, well done... and welcome to continuous merging issues! TFS 2005 / 2008 don’t support multiple pending merge entries for a single file, so you have to perform continuous merging. This isn’t a big issue with versioning tasks, however the problem with continuously checking out and in the versioning file(s) is that you get loads of noise on the pending merges table and if you do merge multiple version files, you will likely have to manually resolve the final version. My second piece of advice is don’t check your versioning files in and out during the build process. As discussed above, it creates noise and merge hassles. As long as you’re versioning logic can be related to the TFS Build Number, I see no benefit in having this source control operation take place. The SolutionTFS provides a build number for every build it initiates. The format is
e.g.
To accomplish versioning, use the <revision> part of the build number. TFS will provide an incremented revision for every build, whether the previous build succeeded or not. All you need to do is provide a task that takes the build number as input, then emits your version number as output. The logic within the task is up to you. Because your build is based on the build number, you can easily locate the label associated with the build. In summary
Implementing the SolutionIf you don’t want to write your own task to implement versioning, the MSBuild Extension Pack provides various tasks to assist you with versioning. AssemblyInfo Task [MSBuild.ExtensionPack.Framework.AssemblyInfo] The original AssemblyInfo task has been added to the MSBuild Extension Pack and received various small tweaks. As mentioned, I’m not a fan of using this for versioning, but if you must, then below is an abbreviated sample: <Project DefaultTargets="DesktopBuild" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5"> <!-- ADD AND CONFIGURE THIS PROPERTY GROUP --> <!-- SET THIS TO NON-EXISTENT FILE TO FORCE REBUILD. --> <!-- OVERRIDE AFTERGET--> <!-- SET THE ASSEMBLYINFOFILES ITEMS DYNAMICALLY --> <Exec WorkingDirectory="$(SolutionRoot)" Command="$(TF) checkout /recursive "@(AssemblyInfoFiles)""/> <!-- OVERRIDE AFTERCOMPILE-->
TFSVersion Task [MSBuild.ExtensionPack.VisualStudio.TfsVersion] The TFSVersion task provides the more lightweight versioning that I have described and is what I use on all projects. Please Note: The output of GetVersion should not be used to change the $(BuildNumber). <Project DefaultTargets="DesktopBuild" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5"> <!-- DEFINE WHICH FILES TO VERSION --> <!-- OVERRIDE BUILDNUMBEROVERRIDETARGET --> <!-- OVERRIDE AFTERGET --> SQLVersion Task [MSBuild.ExtensionPack.SqlServer.SqlVersion] The SqlVersion task provides the ability to manage multiple build versions in a simple database table. Please Note: The output of GetVersion should not be used to change the $(BuildNumber). <Project DefaultTargets="DesktopBuild" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5"> <!-- DEFINE WHICH FILES TO VERSION --> <!-- OVERRIDE BUILDNUMBEROVERRIDETARGET --> <!-- Get the latest build number and increment as necessary --> <!-- OVERRIDE AFTERGET --> Version 3.5.5.0 of the MSBuild Extension Pack will provide an additional file based versioning task, but the above three, especially the TFSVersion task should meet most needs. I’ve disabled comments on this blog as the spam filters on live spaces are not sufficient. If you have any feedback, please use the feedback URL found in the MSBuild Extension Pack help. Mike 引用通告此日志的引用通告 URL 是: http://freetodev.spaces.live.com/blog/cns!EC3C8F2028D842D5!1253.trak 引用此项的网络日志
|
|
|