views:

660

answers:

2

We are using TFSDeployer to listen to build quality changes and deploy to our staging environment when it transitions to "Staging".

I'd like to have it go ahead and update all of the other builds that have a currently build quality of "Staging" to be "Rejected".

This appears to be something that needs to happen inside the PowerShell script which looks like:

$droplocation = $TfsDeployerBuildData.DropLocation
ECHO $droplocation

$websourcepath = $droplocation + "\Release\_PublishedWebsites\CS.Public.WebApplication\"
$webdestinationpath = "\\vmwebstg\WebRoot\CreditSolutions\"

new-item -force -path $webdestinationpath -itemtype "directory"
get-childitem $webdestinationpath | remove-item -force -recurse
get-childitem $websourcepath | copy-item -force -recurse -destination $webdestinationpath

$configFile = $webdestinationpath + "web.development.config"
remove-item $configFile -force

$configFile = $webdestinationpath + "web.staging.config"
$configFileDest = $webdestinationpath + "web.config"
move-item $configFile $configFileDest -force

So, how can I do this?

+1  A: 

This is not the full answer as I don't have much knowledge of TFSDeployer or indeed PowerScript. However the .NET API for Team Build is able to do this. You want to get hold of the IBuildDetail for the build. The easiest way to get this is if you have the BuildUri (which it sounds like you might) in which case a call to IBuildServer.GetBuild should get you the build you are interested in.

IBuildServer also has the QueryBuilds methods which you would be able to call to find the builds that are of interest to you, you would then set the Quality property on the IBuildDetails that you wanted to change, remembering to call the Save() method on each one.

Hope that gives you a start - sorry it isn't a more complete answer.

Martin Woodward
+1  A: 

First add the Get-tfs function to your script:

function get-tfs (
    [string] $serverName = $(Throw 'serverName is required')
)
{
    # load the required dll
    [void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation.Client")

    $propertiesToAdd = (
        ('VCS', 'Microsoft.TeamFoundation.VersionControl.Client', 'Microsoft.TeamFoundation.VersionControl.Client.VersionControlServer'),
        ('WIT', 'Microsoft.TeamFoundation.WorkItemTracking.Client', 'Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItemStore'),
        ('BS', 'Microsoft.TeamFoundation.Build.Common', 'Microsoft.TeamFoundation.Build.Proxy.BuildStore'),
        ('CSS', 'Microsoft.TeamFoundation', 'Microsoft.TeamFoundation.Server.ICommonStructureService'),
        ('GSS', 'Microsoft.TeamFoundation', 'Microsoft.TeamFoundation.Server.IGroupSecurityService')
    )

    # fetch the TFS instance, but add some useful properties to make life easier
    # Make sure to "promote" it to a psobject now to make later modification easier
    [psobject] $tfs = [Microsoft.TeamFoundation.Client.TeamFoundationServerFactory]::GetServer($serverName)
    foreach ($entry in $propertiesToAdd) {
        $scriptBlock = '
            [System.Reflection.Assembly]::LoadWithPartialName("{0}") > $null
            $this.GetService([{1}])
        ' -f $entry[1],$entry[2]
        $tfs | add-member scriptproperty $entry[0] $ExecutionContext.InvokeCommand.NewScriptBlock($scriptBlock)
    }
    return $tfs
}

Next, instantiate the TFS object

$tfs = get-tfs http://YourTfsServer:8080

Then find the builds with a build quality of "Staging"

$builds = $tfs.BS.GetListOfBuilds("Test Project", "TestBuild") | 
where {$_.BuildQuality -eq "Staging"}

Finally, update the quality of these builds

 foreach ($build in $builds) { $tfs.BS.UpdateBuildQuality($build.BuildUri, "Rejected") }

(I haven't run this script yet, but you should be able to get it going without troubles)

More info on my blog: Using the Team Foundation Object Model with PowerShell

One last advice, if you update the Build quality from within the script that is running from TfsDeployer, you could end up with 2 script running at the same time if you have a mapping for the Staging --> Rejected transition!

thijs
Should there be some type of qualifier in the where clause that excludes the current build? In other words, is the Staging quality set on the current build before or after TfsDeployer gets a hold of it?
Chris Lively
It worked. I added another where clause which excluded the particular build number I was working with. Thanks!
Chris Lively
The build quality is already set (firmly) when TFSDeployer picks up the change. (Presumably from "Unexamened" to "Staging" when you're deploying.
thijs