February 2, 2007 CI Factory, Continuous Integration

Closing In

I am closer than I have ever been. :)

I have been focused on getting our build infrastructure working with Visual Studio Team Systems, Team Foundation Server.  This means creating a VSTS Source Control Package for CI Factory, which includes NAnt tasks and CCNet plugins.  Blah Blah Blah, you have heard this before?  True.  I think I am just about done.  When I publish, it would be nice if it were actually useful to some other shops.  So I will try to do a quickly summary of the features here and you can let me know if I have missed something that you would like to see.

 

I have added 9 tasks and 24 functions.  This is directly against the Team Foundation (TF) API not the TF.exe tool.  I did try to maintain, without restricting improvement, congruency with tf.exe.  So for the moment you should be able to get help from the tf.exe help doc.  There are of course some new things here.  There are filesets, which are generally localitems elements, which should be intuitive to NAnt user.  There is one task that is an experiment, tfsblock.  Notice the function call just before the tfsblock, it passes the string ‘tfs’, the id of the tfsserverconnection.  In the tfsblock the function calls do not require this information as it is specified in the block declaration.  So from one perspective there are only 12 functions, half only operate in a tfsblock.  BTW I plan to add a fileset option to the tfsget task, like the tfsadd already has.

<tfsserverconnection

  password=“”

  username=“”

  serverurl=“”

  domain=“”

  id=tfs/>

 

<versionspec

  type=Changeset, Date, Label, Workspace, Latest, or Null

  versionspec=“”

  id=ver/>

 

<tfsadd

  localitem=“”

  recursive=“”

  workspacename=“”>

  <localitems>

    <include name=“”/>

  </localitems>

  <tfsserverconnection refid=tfs/>

</tfsadd>

 

<echo message=${tfs-vc::get-latest-changeset-id(‘tfs‘)}/>

 

<tfsblock

  clean=true or false

  workspacename=“”>

  <tfsserverconnection refid=tfs/>

  <do>

    <!–

    do some stuff in here without having to specify

    workspace and or connection info

    –>

    <echo message=${tfs-vc::get-latest-changeset-id()}/>

    <echo message=${tfs-vc::get-latest-changeset-id-frompath(serverItem)}/>

    <echo message=${tfs-vc::label-exists(label, scope)}/>

    <echo message=${tfs-vc::workspace-exists(workspaceName)}/>

    <echo message=${tfs-vc::get-workspace-name(localItem)}/>

    <echo message=${tfs-vc::is-server-path-mapped(serverItem)}/>

    <echo message=${tfs-vc::is-local-path-mapped(localItem)}/>

    <echo message=${tfs-vc::get-localitem-for-serveritem(serverItem)}/>

    <echo message=${tfs-vc::get-serveritem-for-localitem(localItem)}/>

    <echo message=${tfs-vc::has-pending-changes()}/>

    <echo message=${tfs-vc::has-pending-changes(localItem)}/>

    <echo message=${tfs-vc::has-confilcts(pathfilter, recursive)}/>

  </do>

</tfsblock>

 

<tfscheckin

  comment=“”

  localitem=“”

  recursive=“”

  workspacename=“”

  >

  <localitems>

    <include name=“”/>

  </localitems>

  <tfsserverconnection refid=tfs/>

</tfscheckin>

 

<tfscheckout

  localitem=“”

  recursive=“”

  workspacename=“”

  >

  <localitems>

    <include name=“”/>

  </localitems>

  <tfsserverconnection refid=tfs/>

</tfscheckout>

 

<tfsdeleteworkspace

  workspacename=“”

  >

  <tfsserverconnection refid=tfs/>

</tfsdeleteworkspace>

 

<tfsget

  all=“”

  localitem=“”

  overwrite=“”

  recursive=“”

  resultfilesetrefid=“”

  serveritem=“”

  workspacename=“”

  >

  <tfsserverconnection refid=tfs/>

  <versionspec refid=ver/>

</tfsget>

 

<tfshistory

  itemspec=“”

  recursive=“”

  reportfile=“”

  >

  <tfsserverconnection refid=tfs/>

  <fromversionspec refid=ver/>

  <toversionspec refid=ver/>

</tfshistory>

 

<tfslabel

  child=“”

  comment=“”

  delete=“”

  itemspec=“”

  labelname=“”

  recursive=“”

  scope=“”

  >

  <tfsserverconnection refid=tfs/>

  <versionspec refid=ver/>

</tfslabel>

 

<tfsmapworkspace

  comment=“”

  workspacename=“”

  >

  <tfsserverconnection refid=tfs/>

</tfsmapworkspace>

 

I have added two plugins to CCNet and altered a third.  The two that I added, vstsbychangesetTrigger and vstsbychangesetSourceControl, subscribe to the checkin event, TFS will call a WCF soap service hosted in the CCNet process on the port specified.  This means that triggering a build is much more responsive and safe (as in concurrency).  As well each build will work with just one person’s changes.  The third plugin is Martin Woodward’s with a few modifications.  The main one being that it remembers the latest changeset from when the build starts, during the get modification phase, and will use this in the get and label operations.  Again this is to prevent concurrency issues.

<vstsbychangesetTrigger

  port=4567

  project=$/test.project/Current/Build

  server=http://vsts.chcsii.com:8080

  statefilepath=C:\Projects\test.project\Current\Build\server\vsts.state.xml

  username=false

  password=false

  domain=false

  />

 

<vstsbychangesetSourceControl 

  applyLabel=false

  force=false

  cleancopy=false

  autoGetSource=true

  port=4567

  project=$/test.project/Current/Build

  server=http://vsts.chcsii.com:8080

  statefilepath=C:\Projects\test.project\Current\Build\server\vsts.state.xml

  workingDirectory=C:\Projects\test.project\Current\Build

  workspace=BuildTest

  deleteWorkspace=false

  username=false

  password=false

  domain=false

  />

 

<vsts 

  applyLabel=true

  force=false

  cleancopy=false

  autoGetSource=false

  project=$/test.project/Current

  server=http://vsts.chcsii.com:8080

  workingDirectory=C:\Projects\test.project\Current\Build

  workspace=BuildTest

  deleteWorkspace=false

  username=false

  password=false

  domain=false

  />

The project that I am doing this for would like to start with very few changes from the Source Safe environment that they now work in.  This means that we won’t go directly to vstsbychangesetSourceControl, one changeset per build.  We will start with Martin’s vsts plugin and a modification delay.  It is unclear if we will start with an interval trigger or move directly to vstsbychangesetTrigger.  Both are compatible with Martin’s vsts plugin and a modification delay. 

The two new plugins use a listener behind the scenes, the subscription to TFS checkin event.  In the example above they share the same listener.  The current configuration schema is clunky.  Only the listener needs port and statefilepath.  It shares the need for project, server, username, password, and domain with vstsbychangesetSourceControl.  vstsbychangesetTrigger does not work with TFS directly so it does not need any of this info, save to pass to the listener.

There are a few new attributes force, cleancopy, and deleteWorkspace that bear some explanation.  Force will replace all files, it is like the all and overwrite switches for the tf.exe get command.  Cleancopy will delete the workingDirectory.  deleteWorkspace will delete the TF workspace and recreate it.  These three options are used during the get source phase of the build if the autoGetSource option is true.

If you are just dyeing to get you hands on this you can find the source for the NAnt tasks and functions and the first two CCNet plugins in CI Factory’s source control repo and Martin’s is on CodePlex.  I have attached my modifications to Martin’s stuff.

15,194 Total Views

1 to “Closing In”

  1. Jennifer Overholt says...

    Hello… I have some files that have to be checked out through a batch file, stuff happens to them, then checked in. This was find in SourceSafe… However, I’m now using TFS, and below you will find my code. The problem is, when it does the check out through the command line, it pops open this “Source Control Settings” and has 2 checkboxes. 1 asking me for Enable multiple check-out. The other to Enable get latest on check-out. I do not want either to occur NOR do I want the popup asking me this to even show…

    CAN YOU HELP A GIRL? PLEASE! LOL… I’m dying!

    Thanks so much,
    Jennifer Overholt
    (code I have written so far below – nuttin fancy)

    SET TFDIR=”C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE”

    cd C:\DEV\

    %TFDIR%\TF.exe configure /server:vcst-tfs
    %TFDIR%\tf checkout -I “$/Engineering Applications/Typelib/Managed/VPCodecDriver.dll” -R -K:Checkout

    pause

Leave a comment

*

here