在進入下個階段之前(也就是開始執行Unit Test),有個部分一直沒有碰到,那就是當建制失敗的時候會發生什麼事情。
整個CI的概念就是儘早發現建制有問題好去做一些處理,但是如果出錯了都發現不到,不就等於沒有意義了?
這篇我們將會看看這方面的處理。
sample 程式在 github devops-psake sample/chapter9
同步發表於我的部落格:http://blog.alantsai.net/2016/12/devopsSeries-howToPropergateBuildError.html (部落格的格式會漂亮一些)
我們首先來看看,當我們故意修改程式碼,讓他build不下去,會出現什麼內容。
這會有什麼問題?
最大的問題會在,當我們要結合一些Build Server的時候,因為他呼叫的是psake,而psake告訴他成功(雖然MSBuild告訴他失敗),所以build server就認為成功。
換句話說,就算失敗了我們也永遠不會知道。
等於是整個建制scrip更本沒辦法使用了。
這個問題,其實很簡單,有點像是程式裡面,如果出現了Exception,把它Tray catch不做任何事情是一樣的概念,當MSBuild出錯的時候,我們的psake就像是掩耳盜鈴一樣,管他是不是跑成功了, 他永遠回傳成功。
所以,我們要面對現實,當建制失敗了,這個資訊要傳出去。
但是另外一個問題來了,我們怎麼知道MSBuild建制失敗了?
任何一個console程式,其實都有一個Exit Code的概念,就是當他執行完,他會回傳一個值,如果 = 0,表示沒有問題,不是0表示有問題。(話說,我寫console都沒有照這個原則)
既然知道有exit code之後,我們可以讓psake檢查,如果是0,就表示沒問題,是0以外表示有問題,就拋出exception。
可以想像當我們要呼叫的程式越來越多,每一個都要加上這個判斷真的不方便,所以psake提供了一個exec的方法,專門幫忙做上面的判斷。
所以,我們調整 task Compile變成:
task Compile -depends Clean, Init -description "編譯程式碼" `
-requiredVariables solutionFile, buildConfiguration, buildTarget, buildTempDirectory `
{
Write-Host "開始建制檔案:$solutionFile"
$buildParam = "Configuration=$buildConfiguration" +
";Platform=$buildTarget" +
";OutDir=$buildTempDirectory"
$buildParam = $buildParam + ";GenerateProjectSpecificOutputFolder=true"
exec {msbuild $solutionFile "/p:$buildParam"}
}
未來執行外部程式一定要記得呼叫exec包住
最後,就算是這樣,我們build server還是不認為失敗,原因很簡單,同樣概念,builder server呼叫的是 build.ps1,可是報錯的是default.ps1,如果錯誤訊息沒有往上傳,build server還是認為成功。
因此,我們要在build.ps1,把這個錯誤訊息往上傳:
...
Write-Host "建制的Exit Code:$LastExitCode"
# 把錯誤碼往上傳
exit $LastExitCode
$LastExitCode是powershell裡面記錄最後一個執行完回傳的結果,所以我們可以用這個值來呈現到我們build結果
在這篇我們瞭解到psake怎麼和其他console程式做結合,並且瞭解透過exit code的方式來知道是否執行成功。
因此,下次在寫console程式的時候,別忘記最後都回傳一個exit code,未來如果自己程式要和這種build結合才有辦法達到
下篇,我們正式進入另外一個部分,程式不是build起來就好了,還要確認所有檢查要通過,而這個檢查就是單元測試。