好的,使用CruiseControl.NET的API我终于能够解决这个问题。活泉!
首先,我创建了一个C#控制台应用程序来获取失败的项目列表。检查每个失败项目的日志文件,并且如果由于错误8000000A导致项目失败,则会在该项目上强制构建。
//Due to a race condition in Visual Studio 2010, CCNet builds often fail with error 8000000A.
//See http://stackoverflow.com/questions/8648428/an-error-occurred-while-validating-hresult-8000000a
//
//The build failure can almost always be fixed by manually forcing another build on the failed project.
//
//This program, along with a companion CCNet project, will automate the process of forcing the builds on the failed projects.
// 1. For each CCNet project whose IntegrationStatus == Failure
// 2. Search the most recent log file for the string "8000000A"
// 3. If string found in log file, force a build on the project
using System;
using ThoughtWorks.CruiseControl.Remote;
namespace ForceBuildForError8000000A
{
class Program
{
static void Main(string[] args)
{
CruiseServerRemotingClient ccnetClient = new CruiseServerRemotingClient("tcp://localhost:21234/CruiseManager.rem");
ProjectStatus[] prjStatusList = ccnetClient.GetProjectStatus();
foreach (ProjectStatus prjStatus in prjStatusList)
{
if (prjStatus.BuildStatus == IntegrationStatus.Failure)
{
string latestBuildName = ccnetClient.GetLatestBuildName(prjStatus.Name);
string log = ccnetClient.GetLog(prjStatus.Name, latestBuildName);
if (log.Contains("ERROR: An error occurred while validating. HRESULT = '8000000A'"))
{
Console.WriteLine("Forcing build for " + prjStatus.Name);
ccnetClient.ForceBuild(prjStatus.Name);
}
}
}
}
}
}
接下来我在ccnet.config文件中创建了另一个项目。该项目使用多触发器来监视可能因8000000A错误而失败的所有其他项目。当任何触发器项目出现故障时,将运行C#程序强制构建因8000000A而失败的任何项目。
<cb:scope ProjectName="$(ForceBuildForError8000000A.Run_ProjectName)">
<project name="$(ProjectName)" >
<cb:ProjectHeaderMacro projectName="$(ProjectName)" />
<cb:AssemblyVersionLabellerMacro Major="1" Minor="0" Build="0" />
<triggers>
<multiTrigger>
<triggers>
<projectTrigger project="$(ProjectName1)" triggerStatus="Failure" />
<projectTrigger project="$(ProjectName2)" triggerStatus="Failure" />
<projectTrigger project="$(ProjectName3)" triggerStatus="Failure" />
<projectTrigger project="$(ProjectName4)" triggerStatus="Failure" />
<projectTrigger project="$(ProjectName5)" triggerStatus="Failure" />
<projectTrigger project="$(ProjectName6)" triggerStatus="Failure" />
</triggers>
</multiTrigger>
</triggers>
<tasks>
<exec>
<executable>$(ForceBuildForError8000000A.exe)</executable>
<baseDirectory>$(MyWorkingTrunk)</baseDirectory>
<buildTimeoutSeconds>120</buildTimeoutSeconds>
</exec>
</tasks>
</project>
</cb:scope>
注意我没有最终使用一个条件任务块,因为我最初认为是需要的,而是一个条件触发器。
有可能是一种使用NANT而不是C#来做到这一点的方法,但我永远不知道如何。
来源
2014-08-10 20:49:41
TJH