Third Shelf

Source Code Promotion Model

Posted in team foundation server by Sydney du Plooy on September 24, 2008

At work we make use of a source code promotion model. What this means is that we promote source code through the various stages of product development.

All new development is done at the tip level. Once development is completed; and I’ll leave the definition up to you; the source code is promoted to the pre-stage level. It is at this level where our internal testers can begin testing the latest release of the product.

Only when the internal testers are satisfied, is the pre-stage source code promoted to the stage level. This is the level where our business users have access to the latest product release. They will in turn begin their testing. Once the business users are satisfied with the release, the stage source code will be promoted to the live or production level.

All this is accomplished by means of source code labels in Team Foundation Server Version Control and in a moment I’ll show you how to setup an MSBuild target that will take care of performing this type of promotion for you.

Note that although the source code is promoted, the labels in the version control system are in fact being shifted downwards, as shown in the picture. Also note that for every source code promotion there is a corresponding build process that kicks-off.

The first thing that we need is a set of label names that we will use to identify the various promotion levels. For this post I’m going to use the following label names: pre-stage, stage and live. You might wonder where the label is for tip – there isn’t one. We make use of the special version spec called T, which marks the latest version of the source code in Team Foundation Server Version Control by default and is always present.

I suggest creating a property group for these labels in case they need to change at some later stage.

<propertygroup>
<prestagelabel>pre-stage</prestagelabel>
  <stagelabel>stage</stagelabel>
	<livelabel>live</livelabel>
</propertygroup>

There are rules that we need to have in place before any source code promotion can happen. Here is a summarized list of rules:

  • A valid FromLabel parameter must be specified;
  • A valid ToLabel parameter must be specified;
  • The pre-stage label can only be moved to tip;
  • The stage label can only be moved to pre-stage;
  • The live label can only be moved to stage.

Here they are represented in the build file:

<error Condition="'$(FromLabel)'==''"
	Text="The FromLabel property has not been specified."
/>

<error Condition="'$(ToLabel)'==''"
	Text="The ToLabel property has not been specified."
/>

<!-- check that the label name we are going to move is valid -->
<error Condition="'$(FromLabel)'!='$(PreStageLabel)' and '$(FromLabel)'!='$(StageLabel)' and '$(FromLabel)'!='$(LiveLabel)'"
	Text="Valid FromLabel values are $(PreStageLabel), $(StageLabel) or $(LiveLabel)"
/>

<!-- check sanity : pre-stage label can only move to tip -->
<error Condition="'$(FromLabel)'=='$(PreStageLabel)' and '$(ToLabel)'!='T'"
	Text="$(PreStageLabel) can only be moved to tip (T)."
/>

<!-- check sanity : stage label can only move to pre-stage -->
<error Condition="'$(FromLabel)'=='$(StageLabel)' and '$(ToLabel)'!='$(PreStageLabel)'"
	Text="$(StageLabel) can only be moved to $(PreStageLabel)."
/>

<!-- check sanity : live label can only move to stage -->
<error Condition="'$(FromLabel)'=='$(LiveLabel)' and '$(ToLabel)'!='$(StageLabel)'"
	Text="$(LiveLabel) can only be moved to $(StageLabel)."
/>

At this point we can be fairly sure that we are going to move labels to where they are supposed to be. On with the promotion. The actual process of moving the labels is fairly straight forward.

There are three different cases to consider when moving labels:

Special case #1 – Moving the live label:

I have not yet spoken about the labels that are attached to previously live versions. It might be necessary to track the source code version that was previously live, just in case the product needs to be rolled back for some or other reason. I term this label the previous-live label. If you need to keep track of all the previous live source code, then I suggest creating a custom build task that simply returns a current date/timestamp and mangle this with the previous-live label. If you only need to keep track of the previous version, you can simply just add it to the property group with all the other label names.

If we are moving the live label which is indicated by the FromLabel property, we first need to label the version at the current live label with the previous-live label. This is done with the following command:

    <!-- Create a previous live label -->
    <exec Condition="'$(FromLabel)'=='$(LiveLabel)' and '$(ToLabel)'=='$(StageLabel)' and '$(LiveLabelExists)'=='true'"
        WorkingDirectory="$(SolutionRoot)"
        Command="&quot;$(TfCmd)&quot; label /server:$(TeamFoundationServerName) &quot;$(PreviousLiveLabel)@$(ProjectSourceRootPath)&quot; $(ProjectSourceRootPath) /version:L$(LiveLabel)@$(ProjectSourceRootPath) /recursive"
    />

Property values in the command line:

  • $(TfCmd) points to the location, including tf.exe.
  • $(TeamFoundationServerName) is machine name where Team Foundation Server is installed on.
  • $(ProjectSourceRootPath) is the source control folder of the project, for example $/MyProject.

Note the L in /version:L – which means that we are referring to the source code version labeled with the label that follows L.

Our next step is to move the live label to the stage label, which is done with the following command:

    <!-- Move Live to Stage -->
    <exec Condition="'$(FromLabel)'=='$(LiveLabel)' and '$(ToLabel)'=='$(StageLabel)'"
        WorkingDirectory="$(SolutionRoot)"
        Command="&quot;$(TfCmd)&quot; label /server:$(TeamFoundationServerName) &quot;$(PreviousLiveLabel)@$(ProjectSourceRootPath)&quot; $(ProjectSourceRootPath) /version:L$(LiveLabel)@$(ProjectSourceRootPath) /recursive"
    />

Special case #2 – Moving the pre-stage label to tip:

When moving the pre-stage label to the tip, there is a small change that has to be made to the command line. Referring to the tip version in the versionspec is simply a T and is not prefixed with L – which indicates a label.

Below is the command line that has to be executed when moving from pre-stage to tip:

    <exec Condition="'$(ToLabel)'=='T'"
        WorkingDirectory="$(SolutionRoot)"
        Command="&quot;$(TfCmd)&quot; label /server:$(TeamFoundationServerName) $(FromLabel)@$(ProjectSourceRootPath) $(ProjectSourceRootPath) /version:$(ToLabel) /child:replace /recursive"
    />

General case:

In all the other cases we simply move the source code labels based on the criteria given. The command line for this general case is shown below:

    <exec Condition="'$(FromLabel)'!='$(LiveLabel)' and '$(ToLabel)'!='T'"
        WorkingDirectory="$(SolutionRoot)"
        Command="&quot;$(TfCmd)&quot; label /server:$(TeamFoundationServerName) $(FromLabel)@$(ProjectSourceRootPath) $(ProjectSourceRootPath) /version:L$(ToLabel)@$(ProjectSourceRootPath) /child:replace /recursive"
    />

Note: The above command lines, with the exception of Special case #1, will overwrite previous applied labels. It will also perform a recursive labeling of all the items in the source path with the new label.

And that is all that there is to it!

Tagged with: ,

7 Responses

Subscribe to comments with RSS.

  1. Jan said, on April 23, 2009 at 18:15

    error Condition=”‘$(FromLabel)’==’$(StageLabel)’ and ‘$(ToLabel)’!=’$(PreStageLabel)’”
    Text=”$(StageLabel) can only be moved to $(PreStageLabel).”

    is the condition I was referring to in my previous post…

  2. Sydney du Plooy said, on April 23, 2009 at 20:17

    Thank you for pointing out the mistake. You are quite right and I have corrected the comment to now show /p:FromLabel=live /p:ToLabel=stage.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 144 other followers