好的,使用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