Queue 2013 TFS团队构建并指定GIT密钥

时间:2015-04-06 22:17:35

标签: xml git powershell tfs team-build

我想使用Powershell调用Team Build。我想覆盖默认的MSBuild参数并指定GIT更改密钥。我无法相信这是多么困难。

指定MSBuild参数很难,因为它是XML中的Json。

以下适用于我的本地笔记本电脑,但不适用于我的TeamCity Build Server。

$buildserver = $tfs.GetService([Microsoft.TeamFoundation.Build.Client.IBuildServer])
$definition = $buildserver.GetBuildDefinition($teamProject, $buildDefinition)

# Deserialize ProcessParameters from the definition
$ProcessParameters = [Microsoft.TeamFoundation.Build.Workflow.WorkflowHelpers]::DeserializeProcessParameters($definition.ProcessParameters)

$AdvancedBuildSettings = $ProcessParameters['AdvancedBuildSettings'].json | ConvertFrom-Json
$AdvancedBuildSettings.MSBuildArguments = "/p:one=parm1 /p:two='parm2'"
$ProcessParameters['AdvancedBuildSettings'].json = $AdvancedBuildSettings | ConvertTo-Json

$request = $definition.CreateBuildRequest()
$request.ProcessParameters = [Microsoft.TeamFoundation.Build.Workflow.WorkflowHelpers]::SerializeProcessParameters($ProcessParameters)
$QueuedBuild = $buildserver.QueueBuild($request)

但是我无法弄清楚我需要安装什么才能安装Microsoft.TeamFoundation.Build.Workflow.dll所以我在使用Deserialize Serialize帮助程序调用时只是自己动手做了。

但是,访问CheckoutOverrides设置更糟糕。我能得到它的唯一方法是在定义中删除一个值,因为它不在XML中。一旦我将其删除,XML就基于类型的数组而言非常讨厌。这是一个样本:

<Dictionary x:TypeArguments="x:String, x:Object" xmlns="clr-namespace:System.Collections.Generic;assembly=mscorlib" xmlns:mtbc="clr-namespace:Microsoft.TeamFoundation.Build.Common;assembly=Microsoft.TeamFoundation.Build.Common" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <x:Array x:Key="ProjectsToBuild" Type="x:String">
        <x:String>\TeamCityToTeamBuild\PullTeamCityBuild.proj</x:String>
    </x:Array>
    <x:Boolean x:Key="CleanRepository">False</x:Boolean>
    <mtbc:BuildParameter x:Key="AdvancedBuildSettings">
        {
        "MSBuildArguments":  " /p:TeamCityProjectId=\u0027%teamcity.project.id%\u0027 /p:TeamCityBuildNumber=%build.number% /p:TeamCityBuildOutput=\u0027\\\\scs40vptmcapp04.medassets.com\\D$\\work\\1f7b2c812110928e\u0027",
        "MSBuildPlatform":  "Auto",
        "PreActionScriptPath":  "",
        "PreActionScriptArguments":  "",
        "PostActionScriptPath":  "",
        "PostActionScriptArguments":  "",
        "RunCodeAnalysis":  "AsConfigured"
        }
    </mtbc:BuildParameter>
    <mtbc:BuildParameter x:Key="AgentSettings">{"MaxExecutionTime":"00:00:00","MaxWaitTime":"04:00:00","Name":"*","Tags":[],"TagComparison":"MatchAtLeast"}</mtbc:BuildParameter>
    <x:String x:Key="CheckoutOverride">SetIt</x:String>
</Dictionary>

因为这是一个String,所以它是String Element下的一个键。将XPath与doc上的命名空间一起使用,此代码如下所示:

$ProcessParametersDoc = [xml]$definition.ProcessParameters
$ns = New-Object System.Xml.XmlNamespaceManager($ProcessParametersDoc.NameTable) 
$ns.AddNamespace('x',"http://schemas.microsoft.com/winfx/2006/xaml") 
$CheckoutOverridesNode = $ProcessParametersDoc.SelectSingleNode("//x:String[@x:Key='CheckoutOverride']",$ns)
$CheckoutOverridesNode.InnerText = $VersionControlNumber

如果它不存在则灵活地创建String数组将成为另一个层次的荒谬。

以下代码可以工作(仍然需要添加代码来处理CheckoutOverride缺少的String节点),但它就像用钳子拉动母鸡的牙齿一样。

$tfs = [Microsoft.TeamFoundation.Client.TeamFoundationServerFactory]::GetServer($serverName)

$buildserver = $tfs.GetService([Microsoft.TeamFoundation.Build.Client.IBuildServer])
$definition = $buildserver.GetBuildDefinition($teamProject, $buildDefinition)

$ProcessParametersDoc = [xml]$definition.ProcessParameters

$AdvancedBuildSettingsNode = $ProcessParametersDoc.Dictionary.BuildParameter | ?{$_.Key -eq 'AdvancedBuildSettings'}

$AdvancedBuildSettings = $AdvancedBuildSettingsNode.InnerXml | ConvertFrom-Json

$MsBuildArgs  = " /p:Arg1='Arg1Value'"
$MsBuildArgs += " /p:Arg2='Arg2Value'"
$AdvancedBuildSettings.MSBuildArguments = $MsBuildArgs

$AdvancedBuildSettingsNode.InnerXml = $AdvancedBuildSettings | ConvertTo-Json

$CheckoutOverridesNode = $ProcessParametersDoc.Dictionary.BuildParameter | ?{$_.Key -eq 'CheckoutOverrides'}

$ns = New-Object System.Xml.XmlNamespaceManager($ProcessParametersDoc.NameTable) 
$ns.AddNamespace('x',"http://schemas.microsoft.com/winfx/2006/xaml") 
$CheckoutOverridesNode = $ProcessParametersDoc.SelectSingleNode("//x:String[@x:Key='CheckoutOverride']",$ns)
$CheckoutOverridesNode.InnerText = $VersionControlNumber

$request = $definition.CreateBuildRequest()
$request.ProcessParameters = $ProcessParametersDoc.OuterXml

$QueuedBuild = $buildserver.QueueBuild($request)

我删除了一些代码来处理缺少XML节点的情况,使其更具可读性。即便如此,这是稳定的吗?有没有更好的办法?我只是担心,即使我稳定了代码,它也可能会破坏下一版本的TFS。

0 个答案:

没有答案