Mike 的个人资料FreeToDev日志列表 工具 帮助

日志


11月7日

Versioning Code in TFS - Revised

This 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 Problem

I’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

  • TFS provides the basic fundamentals of iterative versioning out the box.

Some Basics

What 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:

  • <major version>.<minor version>.<build number>.<revision>

My first piece of advice is that you don’t keep the two in sync. The AssemblyVersion should rather be of the format:

  • <major version>.<minor version>.0.0

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

  • <Static major version>.<Static minor version>.< Calculated build number>.<Iterative revision>

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 Solution

TFS provides a build number for every build it initiates. The format is

  • <build name>_<year><month><day>.<revision>

e.g.

  • MSSDCDaily_20080402.1

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
  • Don’t increment the AssemblyVersion
  • Don’t perform source control operations for versioning
  • Do increment the AssemblyFileVersion
  • Do base your build number iteration on the TFS Build Number
  • Do base your build number calculation on the TFS Build Number

Implementing the Solution

If 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">
    <Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\TeamBuild\Microsoft.TeamFoundation.Build.targets" />
    <!-- ADD THIS LINE -->
    <Import Project="$(MSBuildExtensionsPath)\ExtensionPack\MSBuild.ExtensionPack.VersionNumber.targets"/>

    <!-- ADD AND CONFIGURE THIS PROPERTY GROUP -->
    <PropertyGroup>
        <!-- ASSEMBLY VERSION PROPERTIES.-->
        <AssemblyMajorVersion>1</AssemblyMajorVersion>
        <AssemblyFileMajorVersion>0</AssemblyFileMajorVersion>
        <!-- TF.EXE -->
        <TF>&quot;$(TeamBuildRefPath)\..\tf.exe&quot;</TF>
        <!-- ASSEMBLYINFO FILE SPEC -->
        <AssemblyInfoSpec>AssemblyInfo.cs</AssemblyInfoSpec>
    </PropertyGroup>

    <!-- SET THIS TO NON-EXISTENT FILE TO FORCE REBUILD. -->
    <ItemGroup>
        <IntermediateAssembly Include="$(SolutionRoot)\foobar.dll"/>
    </ItemGroup>

    <!-- OVERRIDE AFTERGET-->
    <Target Name="AfterGet" Condition="'$(IsDesktopBuild)'!='true'">

        <!-- SET THE ASSEMBLYINFOFILES ITEMS DYNAMICALLY -->
        <CreateItem Include="$(SolutionRoot)\**\$(AssemblyInfoSpec)">
            <Output ItemName="AssemblyInfoFiles" TaskParameter="Include" />
        </CreateItem>

        <Exec WorkingDirectory="$(SolutionRoot)" Command="$(TF) checkout /recursive &quot;@(AssemblyInfoFiles)&quot;"/>
    </Target>

    <!-- OVERRIDE AFTERCOMPILE-->
    <Target Name="AfterCompile" Condition="'$(IsDesktopBuild)'!='true'">
        <Exec WorkingDirectory="$(SolutionRoot)" Command="$(TF) checkin /comment:&quot;Auto-Build: Version Update&quot; /noprompt /override:&quot;Auto-Build: Version Update&quot; /recursive &quot;@(AssemblyInfoFiles)&quot;" />
    </Target>


    <!-- IN CASE OF BUILD FAILURE, THE AFTERCOMPILE TARGET IS NOT EXECUTED. UNDO THE CHANGES -->
    <Target Name="BeforeOnBuildBreak" Condition="'$(IsDesktopBuild)'!='true'">
        <Exec WorkingDirectory="$(SolutionRoot)" Command="$(TF) undo /noprompt /recursive &quot;@(AssemblyInfoFiles)&quot;" />
    </Target>
</Project>

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">
    <Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\TeamBuild\Microsoft.TeamFoundation.Build.targets" />
    <!-- ADD THIS LINE -->
    <Import Project="$(MSBuildExtensionsPath)\ExtensionPack\MSBuild.ExtensionPack.tasks"/>

    <!-- DEFINE WHICH FILES TO VERSION -->
    <ItemGroup>
        <FilesToVersion Include="$(SolutionRoot)\Source\Common\VersionInfo.cs" />
    </ItemGroup>

    <!-- OVERRIDE BUILDNUMBEROVERRIDETARGET -->
    <Target Name="BuildNumberOverrideTarget" Condition="'$(IsDesktopBuild)'!='true'">
        <MSBuild.ExtensionPack.VisualStudio.TfsVersion TaskAction="GetVersion" UseUtcDate="true" BuildName="$(BuildDefinition)" TfsBuildNumber="$(BuildNumber)" VersionFormat="Elapsed" StartDate="1 Jan 2009" VersionTemplateFormat="0.0.1000.0" Major="3" Minor="1">
            <Output TaskParameter="Version" PropertyName="CodeBuildNumber" />
        </MSBuild.ExtensionPack.VisualStudio.TfsVersion>
    </Target>

    <!-- OVERRIDE AFTERGET -->
    <Target Name="AfterGet" Condition="'$(IsDesktopBuild)'!='true' ">
        <MSBuild.ExtensionPack.VisualStudio.TfsVersion TaskAction="SetVersion" Files="%(FilesToVersion.Identity)" Version="$(CodeBuildNumber)"/>
    </Target>
</Project>

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">
    <Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\TeamBuild\Microsoft.TeamFoundation.Build.targets" />
    <!-- ADD THIS LINE -->
    <Import Project="$(MSBuildExtensionsPath)\ExtensionPack\MSBuild.ExtensionPack.tasks"/>

    <!-- DEFINE WHICH FILES TO VERSION -->
    <ItemGroup>
        <FilesToVersion Include="$(SolutionRoot)\Source\Common\VersionInfo.cs" />
    </ItemGroup>

    <!-- OVERRIDE BUILDNUMBEROVERRIDETARGET -->
    <Target Name="BuildNumberOverrideTarget">
        <PropertyGroup>
            <FieldToIncrement Condition=" '$(IncrementalBuild)'=='true' ">4</FieldToIncrement>
            <FieldToIncrement Condition=" '$(IncrementalBuild)'!='true' ">3</FieldToIncrement>
        </PropertyGroup>

        <!-- Get the latest build number and increment as necessary -->
        <MSBuild.ExtensionPack.SqlServer.SqlVersion Taskaction="GetVersion" BuildName="V9 Production Build" FieldToIncrement="$(FieldToIncrement)" DatabaseName="Mike">
            <Output TaskParameter="Major" PropertyName="BuildMajor" />
            <Output TaskParameter="Minor" PropertyName="BuildMinor" />
            <Output TaskParameter="Build" PropertyName="BuildBuild" />
            <Output TaskParameter="Revision" PropertyName="BuildRevision" />
        </MSBuild.ExtensionPack.SqlServer.SqlVersion>
        <PropertyGroup>
            <CodeBuildNumber>$(BuildMajor).$(BuildMinor).$(BuildBuild).$(BuildRevision)</CodeBuildNumber>
        </PropertyGroup>
    </Target>

    <!-- OVERRIDE AFTERGET -->
    <Target Name="AfterGet" Condition="'$(IsDesktopBuild)'!='true' ">
        <MSBuild.ExtensionPack.VisualStudio.TfsVersion TaskAction="SetVersion" Files="%(FilesToVersion.Identity)" Version="$(CodeBuildNumber)"/>
    </Target>
</Project>

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

5月6日

Planning for TFS 2010

Brian Harry has posted a few more details concerning system requirements and more here.

I’ve updated my previous diagrammatic overview to include this new information.

Download

ScreenShot015

11月21日

Team Foundation Server Build 2008 Reference DeskSheet – V2.0

A few minor updates. A handy reference to aid your work with building software in TFS 2008

ScreenShot023

11月17日

Team Foundation Server Build 2008 Reference DeskSheet

UPDATE: V2 is available now.

A handy reference to aid your work with building software in TFS 2008

image

Download

11月8日

TFS Power Tools October 2008

These have just been released… Available here

9月30日

Planning for Team Foundation Server 2010 (Rosario)

Brian Harry posted an interesting blog which outlines some of the steps that can and should be taken in planning for Rosario. Note that this information is based on assumption and subject to change. Below is a summarised view that may be handy for your Rosario budget meeting… [Download pdf]

ScreenShot010

7月24日

Versioning Code in TFS - Part 2

7 Nov 2009: Update

In Versioning Code in TFS - Part 1 I covered most of my thoughts on the matter. I've since helped a colleague out with implementing code versioning using GetBuildNumber and SetBuildNumber in the FTDTFSBuild task. I was disappointed that the experience wasn't as smooth as it could have been and following a few discussions, a few changes have been made to the FTDTFSBuild Task to improve the functionality and user experience. These have all shipped in the latest beta release of the FreeToDev MSBuild Tasks Suite.

Summary of Changes

Name changes to alleviate confusion:
  • FTDTFSBuild ---> FTDTFSVersion
  • GetBuildNumber ---> GetVersion
  • SetBuildNumber ---> SetVersion
  • BuildType ---> BuildName
  • BuildNumber & CalculatedBuildNumber ---> Version
  • Encoding ---> TextEncoding to be consistent with other tasks
  • Format ---> VersionFormat
  • VersionFormat Date option ---> DateTime
Enhancements
  • ZeroPadding has been split into PaddingCount and PaddingDigit
  • Padding is now supported for VersionFormat=”DateTime”, not just VersionFormat=”Elapsed”
  • TextEncoding is now optional. Defaults to UTF8
  • If a file is made write-able, it is now set back to read-only after versioning
Updated Sample

    <!-- 1. Import the Tasks-->
    <Import Project="C:\Program Files\FreeToDev\MSBuild Tasks Suite 3.5\FreeToDev.MSBuild.tasks"/>
    <ItemGroup>
        <!-- 2. Create an Item Collection of files to version -->
        <FilesToVersion Include="C:\POC\AssemblyInfo.cs"/>
    </ItemGroup>
    <!-- Team Build Code omitted for brevity -->
    <Target Name="BuildNumberOverrideTarget" Condition="'$(IsDesktopBuild)'!='true'">
        <!-- 3a. Get the version using the current Team Build properties. This example uses the Elapsed VersionFormat. Note, if you are using TFS2005, then use $(BuiltType) rather than $(BuildDefinition) for the BuildName property-->
        <FTDTFSVersion TaskAction="GetVersion" BuildName="$(BuildDefinition)" TFSBuildNumber="$(BuildNumber)" VersionFormat="Elapsed" StartDate="1 Jan 2000" PaddingCount="4" PaddingDigit="1" Major="3" Minor="5">
            <Output TaskParameter="Version" PropertyName="NewVersion"/>
        </FTDTFSVersion>
        <Message Text="Elapsed Version is $(NewVersion)"/>
        <!-- 3b. This example uses the DateTime VersionFormat. Note, if you are using TFS2005, then use $(BuiltType) rather than $(BuildDefinition) for the BuildName property-->
        <FTDTFSVersion TaskAction="GetVersion" BuildName="$(BuildDefinition)" TFSBuildNumber="$(BuildNumber)" VersionFormat="DateTime" DateFormat="MMdd" PaddingCount="5" PaddingDigit="1" Major="3" Minor="5">
            <Output TaskParameter="Version" PropertyName="NewVersion"/>
        </FTDTFSVersion>
        <Message Text="Date Version is $(NewVersion)"/>
    </Target>
    <Target Name="AfterGet" Condition="'$(IsDesktopBuild)'!='true'">
        <!-- 4. Set the version in the file collection -->
        <FTDTFSVersion TaskAction="SetVersion" Files="%(FilesToVersion.Identity)" Version="$(NewVersion)"/>
    </Target>


6月2日

Versioning Code in TFS - Part 1

7 Nov 2009: Update

24 July 2008 UPDATE: Part 2 is available.

I’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’ve made various responses to them and in many said I would put together some thoughts to clarify my thinking on the matter... I’ve finally got round to doing it...

The Problem

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 is that TFS provides the basic fundamentals of iterative versioning out the box.

 

Versioning Assemblies

Let’s start with some basic fundamentals. What’s a version number? There are two version numbers in .net, the AssemblyVersion and the AssemblyFileVersion. Both follow the same format:

<major version>.<minor version>.<build number>.<revision>

My first piece of general advice is that you don’t keep the two in sync. The assembly version should rather be of the format:

<major version>.<minor version>.0.0

The main reason for this is that strong name signatures include the assembly version, which means that if you release an updated assembly, the code that references it will need to be updated too (unless you go the policy route, but let’s keep things simple).

The AssemblyFileVersion is the attribute that should be updated with every build you perform, and therein lays the question. How?

I would estimate that in 99% of builds, the format of the build number will be

<Fixed major version>.<Fixed minor version>.< Calculated build number>.<Iterative revision>

The Fixed 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, the number of days since a give milestone etc. The iterative part is where the trouble lies.

Let’s look at some tools for versioning. In the past, before TFS, you may have used the SDC Tasks for versioning, or your own bespoke solution. With the first release of TFS, a popular solution was, and still is, the AssemblyInfo Task. All these solutions 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.

This is the operation that causes the most problems. When I first used the AssemblyInfo task, I encountered numerous painful ‘cannot determine the workspace’ errors. I could easily resolve those issues today, but with little experience and understanding of TFS back then, I and many others felt the pain. If that error didn’t catch you, then you were likely to be caught by checkin policies or duplicate attributes. All issues can be resolved, but too many people have had a hard time with this task.

So, 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 contiguous merging issues! TFS 2005 / 2008 don’t support multiple pending merge entries for a single file, so you have to perform contiguous merging. This isn’t a big issue with versioning tasks, however the problem with continuously checking out and in the versioning files(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.

Many people have questioned why Microsoft didn’t release a basic versioning task with TFS, and in fact it appears that the next version of TFS may include such functionality. But why wait? The functionality is already there, it just needs to be used.

 

Don’t do it

My second piece of general advice is don’t check your versioning files in and out during the build process. As discussed above, it creates noise and hassle with merges. 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. Stop the obsession!

 

The Solution

TFS provides a build number for every build it initiates. The format is

<build name>_<year><month><day>.<revision>

e.g.

MSSDCDaily_20080402.1

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.

The lightweight TFS Versioning Tasks provide functionality to easily create builds with a calculated build number in a date or elapsed format.

Because your build is based on the build number, you can easily locate the label associated with the build.

 

In summary

  • Don’t increment the AssemblyVersion
  • Do increment the AssemblyFileVersion
  • Don’t perform source control operations for versioning
  • Do base your build number iteration on the TFS Build Number
  • Do base your build number calculation on the TFS Build Number

I hope that clarifies things...FTD


5月26日

Integrate Microsoft C# Source Analysis with TFS

UPDATE - 15 October 2008 : Please see MSBuild Extension Pack for the StyleCop task.

UPDATE - 20 July 2008: This task is now available again. This task works with Source Analysis 4.2. A version for StyleCop 4.3 will be made available in the FreeToDev MSBuild Tasks Suite soon...

The FTDSourceAnalysis MSBuild task (download here) provides a mechanism for scanning C# files for Source Analysis violations based on a collection of files, rather than the MSBuild integration offered by the tasks provided with the  Source Analysis install (which scans @(Compile) items).

To use this task, place the FTDSourceAnalysis.dll file in C:\Program Files\MSBuild\Microsoft\SourceAnalysis\v4.2

Sample

<Project DefaultTargets="Default" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <UsingTask AssemblyFile="C:\Program Files\MSBuild\Microsoft\SourceAnalysis\v4.2\FTDSourceAnalysis.dll" TaskName="FTDSourceAnalysis"/>
    <Target Name="Default">
<!-- Create a collection of files to scan -->
        <CreateItem Include="C:\SomeFiles\**\*.cs">
            <Output TaskParameter="Include" ItemName="SourceAnalysisFiles"/>
        </CreateItem>
        <!-- Run the FTDSourceAnalysis MSBuild task -->
        <FTDSourceAnalysis SourceFiles="@(SourceAnalysisFiles)" ShowOutput="true" ForceFullAnalysis="true" CacheResults="false" logFile="C:\FTDSALog.txt" SettingsFile="C:\Settings.SourceAnalysis">
            <Output TaskParameter="Succeeded" PropertyName="AllPassed"/>
            <Output TaskParameter="ViolationCount" PropertyName="Violations"/>
            <Output TaskParameter="FailedFiles" ItemName="Failures"/>
        </FTDSourceAnalysis>
        <Message Text="Succeeded: $(AllPassed), Violations: $(Violations)"/>
<!--
    /// FailedFile format is:
    ///
    ///     <ItemGroup>
    ///     <FailedFile Include="filename">
    ///         <CheckId>SA Rule Number</CheckId>
    ///         <RuleDescription>Rule Description</RuleDescription>
    ///         <RuleName>Rule Name</RuleName>
    ///         <LineNumber>Line the violation appears on</LineNumber>
    ///         <Message>SA violation message</Message>
    ///     </FailedFile>
    ///  </ItemGroup>
-->

        <Message Text="%(Failures.Identity) - Failed on Line %(Failures.LineNumber). %(Failures.CheckId): %(Failures.Message)"/>
    </Target>
</Project>

Sample Output

Target Default:
    Performing Microsoft C# Source Analysis scan...
    Pass 1: FTDSourceAnalysis (2).cs...
    1 violations encountered.
    Succeeded: False, Violations: 1
    C:\SomeFiles\FTDSourceAnalysis (2).cs - Failed on Line 1. SA1638: The file attribute in the file header's copyright tag must contain the name of the file.

This custom collection based scanning provides an easy way to scan various files as part of your TFS builds and flag any violations to the team.

1月25日

Using the TFS Build Number Task with TFS 2008

UPDATE: 13 July 08 --- These tasks are now available in the FreeToDev MSBuild Tasks Suite

The sample code provided in the blog post covering this light weight task needs to be tweaked if using TFS 2008:

TFS 2005:

<GetBuildNumber BuildType="$(BuildType)" BuildNumber="$(BuildNumber)" Format="Elapsed" StartDate="1 Jan 2007" ZeroPadding="4" Major="2" Minor="1">
        <Output TaskParameter="AssemblyFileVersion" PropertyName="ElapsedBuildNo" />
</GetBuildNumber>
<GetBuildNumber BuildType="$(BuildType)" BuildNumber="$(BuildNumber)" Format="Date" DateFormat="MMdd" Major="2" Minor="1">
        <Output TaskParameter="AssemblyFileVersion" PropertyName="DateBuildNo" />
</GetBuildNumber>

TFS 2008:

<GetBuildNumber BuildType="$(BuildDefinition)" BuildNumber="$(BuildNumber)" Format="Elapsed" StartDate="1 Jan 2007" ZeroPadding="4" Major="2" Minor="1">
        <Output TaskParameter="AssemblyFileVersion" PropertyName="ElapsedBuildNo" />
</GetBuildNumber>
<GetBuildNumber BuildType="$(BuildDefinition)" BuildNumber="$(BuildNumber)" Format="Date" DateFormat="MMdd" Major="2" Minor="1">
        <Output TaskParameter="AssemblyFileVersion" PropertyName="DateBuildNo" />
</GetBuildNumber>

FreeToDev

9月26日

TFS Build Number Tasks

UPDATE: 13 July 08 --- These tasks are now available in the FreeToDev MSBuild Tasks Suite

UPDATE (15 May08): See this post for TFS 2008 support

I've added two simple tasks to the FreeToDev.MSBuild.Tasks assembly, both relate to build numbers in TFS. I've previously modified and used the AssemblyInfo task to get assembly versions consistent across all assemblies produced by a team build. I have a few pet hates with regard to this task though.

  1. It’s very easy to get into ‘unable to determine the workspace’ hell
  2. You typically have to change the code to suite your build number format
  3. It updates the assemblyinfo files in source control
  4. It crashes if any files it processes do not contain versioning attributes.

The following tasks are intended to provide a lightweight and flexible solution to getting your assemblies versioned consistently in a team build.

 

  • GetBuildNumber – This can be used in two ways. It will base the build part on either the number of days that have elapsed since a given date or on a date format, eg.

<GetBuildNumber BuildType="$(BuildType)" BuildNumber="$(BuildNumber)" Format="Elapsed" StartDate="1 Jan 2007" ZeroPadding="4" Major="2" Minor="1">
        <Output TaskParameter="AssemblyFileVersion" PropertyName="ElapsedBuildNo" />
</GetBuildNumber>
<GetBuildNumber BuildType="$(BuildType)" BuildNumber="$(BuildNumber)" Format="Date" DateFormat="MMdd" Major="2" Minor="1">
        <Output TaskParameter="AssemblyFileVersion" PropertyName="DateBuildNo" />
</GetBuildNumber>

 

  • SetBuildNumber - this is used to set the build number in a given collection of files.

Team Build Sample

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="DesktopBuild" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v8.0\TeamBuild\Microsoft.TeamFoundation.Build.targets"/>
    <Import Project="FreeToDev.MSBuildTasks.tasks"/>
    <ItemGroup>
        <FilesToVersion Include="C:\POC\AssemblyInfo.cs"/>
    </ItemGroup>
    <!-- Team Build Code omitted for brevity -->
    <Target Name="BuildNumberOverrideTarget" Condition="'$(IsDesktopBuild)'!='true'">
        <ShowBuildStep TeamFoundationServerUrl="$(TeamFoundationServerUrl)" BuildURI="$(BuildUri)" BuildStep="TARGET OVERRIDE: BuildNumberOverrideTarget"/>
        <GetBuildNumber BuildType="$(BuildType)" BuildNumber="$(BuildNumber)" Format="Elapsed" StartDate="1 Jan 2007" ZeroPadding="4" Major="2" Minor="1">
            <Output TaskParameter="AssemblyFileVersion" PropertyName="ElapsedBuildNo"/>
        </GetBuildNumber>

        <OnError ExecuteTargets="OnError"/>
    </Target>
    <Target Name="AfterGet" Condition="'$(IsDesktopBuild)'!='true'">
        <ShowBuildStep TeamFoundationServerUrl="$(TeamFoundationServerUrl)" BuildURI="$(BuildUri)" BuildStep="TARGET OVERRIDE: AfterGet"/>
        <SetBuildNumber Files="%(FilesToVersion.Identity)" BuildNumber="$(ElapsedBuildNo)" Encoding="UTF8"/>
        <!-- add any addition processing required -->
        <OnError ExecuteTargets="OnError"/>
    </Target>
    <!-- Team Build Code omitted for brevity -->
</Project>

Download the latest version with samples here....FTD

8月17日

Getting TFS 2008 functionality in TFS 2005

The latest beta of TFS 2008 has a go-live licence and Brian Harry has blogged about the Final TFS 2008 Feature List. TFS 2008 was always marketed as a minor release, targeted at reducing the adoption blockers which have kept companies from buying the product. Anyone who is considering a move to TFS now, should go with TFS 2008. Even if your development is VS2005 based, VS2005 is compatible with TFS 2008.

What about all those users out there who have adopted TFS 2005 though? Is it worth upgrading? I think for the majority of TFS 2005 users, the answer will be no. There is already a CTP of Rosario out, and that is the release where in major updates to TFS are being made. I wouldn't be surprised if Rosario ships (in beta with a Go-Live licence) within 12 months of TFS 2008 being launched in February 2008. Skipping TFS 2008 and waiting for Rosario doesn't mean you can't get TFS 2008 features now though. Given the Final TFS 2008 Feature List, I've listed current alternatives you can use now; more may appear in the near future.

(I'm still gathering some information, so some features are incomplete, but check back soon for an update. If you know of any better or missing alternatives, please let me know.)

Administration, Operations & Setup

  • Share Point 2007 support --- Guidance
  • Support for MOSS 2007 --- TBC
  • Enable use of SharePoint on any server and any port --- Guidance
  • Enable support for Reporting Services on any server and any port (new) (RTM) --- None / Not Recommended
  • Support for SQL Named Instances – This will allow customers to share a SQL server between multiple TFS instances, or with other applications.  This has been a commonly requested feature by enterprises. --- None
  • “Longhorn” server support – TFS will support the next version of the server (and corresponding new version of IIS) that is currently under development. --- TBC
  • Sync Large Groups – This is a set of work to improve the performance and robustness of TFS’s handling large groups of users (~30,000 or more) granted permission to a TFS instance.  Today this can result in a support call to recover from it. --- Not sure, see where the support call gets you.
  • Non-default ports – We’ve gotten a bunch of feedback from enterprise customers about TFS’s limited support for alternate web sites and ports running afoul of data center policies.  We are going to be improving TFS’s configurability in this respect in Orcas. --- Not Recommended. Guidance
  • Simplify installation – In Orcas, we will be doing a variety of things to attempt to make installing TFS easier and quicker than it is now.  Improvements include eliminating the separate data-tier installation, simplifying the requirements around required domain accounts by supporting the built in machine accounts (like Network Service) where we can, etc. --- Not really applicable, but if you are installing, make sure you check the online documentation rather than the CHM. And like many things, practice makes perfect.
  • Official testing and support for more configurations - This includes clustering, mirroring, log shipping, Virtual machine deployment, and more. --- If it's official support you are after, then there is no alternative. That said, I've done several virtual deployments that work without issue and a standby virtual rig is a great temporary DR solution.
  • Support for client certificates --- TBC
  • Upgrade from TFS 2005 --- Not Applicable
  • Support for SQL 2008 (aka Katmai) (new) (RTM) --- TBC, though I doubt TFS 2005 support will be added.
  • TFSDeleteProject now permanently deletes (destroys) version control content (new) (RTM) --- None. But some would be better off without this! Really, buy a bigger disk.
  • New role for many operations activities (new) (RTM) - You don't have to be server administrator to run many of the admin utilities any longer. --- None
  • Enhancements to tfsadminutil (new) (RTM) - New capability to configure accounts, connections, etc on both TFS and the TFS proxy. --- TBC

Build

  • Support multi-threaded builds with the new MSBuild. --- None
  • Continuous Integration – There are many components to this, including build queuing and queue management, drop management (so that users can set policies for when builds should be automatically deleted), and build triggers that allows configuration of exactly how when CI builds should be triggered, for example – every checkin, rolling build (completion of one build starts the next), etc. --- A CI solution is available from Microsoft. Contact your technical account manager and they will be able to arrange it for you. It's nowhere near as powerful as TFS 2008, but it does provide some CI functionality.
  • Improved ability to specify what source, versions of source, and other build properties. --- None
  • Improved extensibility of the build targets – such as ability to easily execute targets before and after each solution/project is built. --- None
  • .NET Object model for programming against the build server. --- None
  • Improved ability to manage multiple build machines. --- None
  • Stop and delete builds from within VS. --- Use the command line tool, write your own tool or use TFSBuildManager
  • Simplified ability to specify what tests get run as part of a build. --- None
  • The ability to store build definitions anywhere in the version control hierarchy. --- None
  • Scheduled builds - You can schedule builds to happen at specified times. --- Windows Task Scheduler
  • Improved build agent communication - We replaced .NET binary remoting with WCF web services, simplifying some configuration and security aspects. --- None
  • Ability to run GUI tests as part of a build - Automated builds used to run tests in such a way as to prevent access to a GUI desktop. --- None
  • New checkin policy for broken CI builds - Preventing checkin while the CI build is broken. --- Guidance
  • Support for HTTPS communication to the TFS server (new) --- None
  • Continuous Integration build checkin policy (new) --- TBC
  • Support for incremental gets and builds (new) --- TBC

Data Warehouse

  • Add support for checkin policy overrides to the warehouse - an oversight from V1. --- TBC

Migration

  • Migration toolkit – A toolkit for building conversion and mirroring solutions between TFS and other systems.  In addition, we will release one or more new tools to integrate with popular alternative systems.  --- TBC

Version Control

  • Merge improvements (new) - Improved the logic that detects merge conflicts to generate fewer false positives and handle more scenarios. --- None
  • Annotate – This is based on the TFS Annotate Power Tool but includes numerous improvements. --- TFS PowerTools
  • Folder Diff – Also based on the TFS Tree Diff Power Tool with numerous improvements. --- TFS PowerTools
  • Destroy – The ability to permanently delete version control files/folders from TFS.  It can also be used to destroy the file contents while preserving the change set history. --- None. But some would be better off without this!
  • Get Latest On Checkout – There have been many requests for this feature (which was a change in behavior from SourceSafe).  There is now an option that allows you to specify that you want TFS to download the latest version of files when you check them out. --- Add in
  • Workspace improvements – Workspaces will now support mapping a folder or file under a cloaked folder and wildcard mappings so that you can map all files in a folder without mapping sub folders.  Based on experience with large projects, this will simplify workspace definitions for many people. --- None
  • Performance improvements – A variety of Version Control performance enhancements that will improve virtually all aspects of version control performance.  The gains for smaller servers/projects (< 10,000 files) will be modest.  The gains for larger projects (particularly where the file count approaches 100,000’s) will be substantial. --- Buy a faster server.
  • Scale improvements – Fixed out of memory problems on the server when operating on more than a few hundred thousand files at a time. --- None
  • Offline improvements - We've significantly improved the experience going offline and integrated the tfpt online capability into the IDE for going back online. --- None
  • Extranet support for the TFS Proxy - allowing you to access a local TFS proxy with a different set of credentials than the TFS server. --- None
  • Command line help - You can now type "tf command /help" and get a console dump of the usage of that command.  This is much more convenient than always being launched into the richer GUI hypertext help when you just want to remember what the options for a command are.  You can still launch the GUI help by running "tf msdn".  You can get a console dump of available commands by just typing "tf help". --- None
  • Source Control Explorer refresh improvements - This includes less redrawing and reloading but even more important it enables updates based on changes made in other instances of TeamExploror or the command line.  That's right, if you checkout a file from the command line, any instances of TeamExplorer you have running on the same machine will automatically refresh. --- None
  • Async loading of the Source Control Explorer (new) --- None
  • The SCE local path can now be selected and copied (new) --- None

Work Item Tracking

  • Performance & Scale improvements – A variety of improvements that will make both the work item server and client faster and able to handle larger servers. --- None
  • Query builder usability improvements - Drop down filtering based on current project, better MRU lists, column drag & drop, shift-click mouse based multi-column sorting, etc. --- None
  • Attachments improvements - Save button, drag & drop for adding an attachment, multi-select for attaching files. --- None
  • Tooltips on field names contain the field name used for querying --- None
  • Server side support for deleting work items & work item types - We didn't have time to do client UI support for it but we plan to release a Power Tool that will take advantage of the new server side feature. --- None
  • Support for security on the iteration hierarchy (new) --- None

Web Access

  • Adding Web Access UI to TFS - As you've seen many places, we acquired devBiz and their TeamPlain Web Access product.  We are releasing it as a Power Tool in the next few months and plan to release it as an official product in the Orcas timeframe.  We have not figured out how the release date will line up with the Orcas date but it will be in the same general timeframe. --- Power Tool

Bug fixes

  • In addition to all of the feature work, we’ve spent months testing the product and fixing any bugs we’ve found.  We expect Orcas will have even better stability and robustness than TFS 2005. --- There are various hot fixes available, and if you have a support contract, then chances are you will get a patch if required.
8月6日

Team Development with Team Foundation Server - Guide

Over the last few weeks I've had the opportunity to work with a few people on the Microsoft Patterns and Practices team in writing a guide for TFS. The final version of this guide has now been published and is available here. It's an ideal read for anyone considering TFS or using it today... and buried in the Contributor's list is the identity of FreeToDev... I hope you find the guide useful...FTD.

3月6日

TFS Team Build DropLocation

I'm running multiple build servers and want drops to go to the relevant build server rather than a central drop folder. The TFSBuild.proj file has a property called DropLocation that specifies where to drop build output. I decided to add a property to the value of DropLocation to make the build drop locally:

    <DropLocation>\\$(COMPUTERNAME)\drops\CI---ProductXYZ</DropLocation>

Easy enough, but running a build resulted in:

TF42042: Failed to connect to drop location \\$(COMPUTERNAME)\drops please ensure that is is a valid share.

It’s not the $, using %24 gives the ‘same’ message. It looks like the build process is using EvaluatedProperties.Value rather than FinalValue.

Luckily there is a way to get around this small bug. I overrode BeforeEndToEndIteration and set DropLocation in there:

<Target Name="BeforeEndToEndIteration" Condition="'$(IsDesktopBuild)'!='true'">
<ShowBuildStep TeamFoundationServerUrl="$(TeamFoundationServerUrl)" BuildURI="$(BuildUri)" BuildStep="TARGET OVERRIDE: BeforeEndToEndIteration"/>
<CreateProperty Value="\\$(COMPUTERNAME)\drops\CI---ProductXYZ">
<Output TaskParameter="Value" PropertyName="DropLocation" />
</CreateProperty>
</Target>

If you are wondering what ShowBuildStep is, take a look at this post...FTD

3月1日

It's time to start looking at Orcas...

The March CTP is here and I'm looking forward to working with the new bits. Also, check out the great Code Metrics that are included in VS. The Orcas Forums are a great place to request, provide and review feedback...FTD

1月7日

Quick Book Review: Professional Team Foundation Server

I just read Professional Team Foundation Server and thought I'd compile a quick review.

If you consider yourself an experienced TFS user, then avoid this book. It's fairly lightweight and tries to cover just about everything in TFS in around 400 pages. If you are a beginner, then go ahead, the book provides an easy read and you can use online resources to further your knowledge in specific areas of the product. One criticism I do have of the book is Chapter 8 'Managing Schemas Using Team Edition for Database Professionals'. What is this chapter doing in a book titled 'Professional Team Foundation Server'? Team Edition for Database Professionals is a great product, and covering it in 25 pages is an injustice. Sticking it in the wrong book is even worse.

My Rating:

  • For Beginners: 4 / 5
  • For Experienced Users: 2/ 5

10月11日

Note To Self: Team Foundation Server Knowledge Base Articles

I just know I'll be needing something from here some day soon. Check out this great post for Team Foundation Server Knowledge Base Articles