在進入下個階段之前(也就是開始執行Unit Test),有個部分一直沒有碰到,那就是當建制失敗的時候會發生什麼事情。
整個CI的概念就是盡早發現建制有問題好去做一些處理,但是如果出錯了都發現不到,不就等於沒有意義了?
這篇我們將會看看這方面的處理。
當Build有錯會怎麼樣?
我們首先來看看,當我們故意修改程式碼,讓他build不下去,會出現什麼內容。
這會有什麼問題?
最大的問題會在,當我們要結合一些Build Server的時候,因為他呼叫的是psake,而psake告訴他成功(雖然MSBuild告訴他失敗),所以build server就認為成功。
換句話說,就算失敗了我們也永遠不會知道。
等於是整個建制scrip更本沒辦法使用了。
問題原因分析
這個問題,其實很簡單,有點像是程式裡面,如果出現了Exception,把它Tray catch不做任何事情是一樣的概念,當MSBuild出錯的時候,我們的psake就像是掩耳盜鈴一樣,管他是不是跑成功了, 他永遠回傳成功。
所以,我們要面對現實,當建制失敗了,這個資訊要傳出去。
但是另外一個問題來了,我們怎麼知道MSBuild建制失敗了?
任何一個console程式,其實都有一個Exit Code的概念,就是當他執行完,他會回傳一個值,如果 = 0,表示沒有問題,不是0表示有問題。(話說,我寫console都沒有照這個原則)
解決方式 - exec
既然知道有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"} }
還有一道步奏
最後,就算是這樣,我們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起來就好了,還要確認所有檢查要通過,而這個檢查就是單元測試。
沒有留言 :
張貼留言