iT邦幫忙

2017 iT 邦幫忙鐵人賽
DAY 3
0
DevOps

從.Net工程師的角度來看DevOps - 到底能夠幫助什麼 之 再戰江湖系列 第 3

[iThome第8屆鐵人賽 09]建制失敗的處理 - 為什麼失敗了但是build server還是認為成功

  • 分享至 

  • xImage
  •  

在進入下個階段之前(也就是開始執行Unit Test),有個部分一直沒有碰到,那就是當建制失敗的時候會發生什麼事情。

整個CI的概念就是儘早發現建制有問題好去做一些處理,但是如果出錯了都發現不到,不就等於沒有意義了?

這篇我們將會看看這方面的處理。

sample 程式在 github devops-psake sample/chapter9

同步發表於我的部落格:http://blog.alantsai.net/2016/12/devopsSeries-howToPropergateBuildError.html (部落格的格式會漂亮一些)

當Build有錯會怎麼樣?

我們首先來看看,當我們故意修改程式碼,讓他build不下去,會出現什麼內容。

從圖片可以看到,雖然MSBuild說失敗了,但是psake還是認為成功了

這會有什麼問題?
最大的問題會在,當我們要結合一些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"}
} 

psake 會報錯了

未來執行外部程式一定要記得呼叫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起來就好了,還要確認所有檢查要通過,而這個檢查就是單元測試。


上一篇
[iThome第8屆鐵人賽 08]建制結果問題 - 方法2 透過MSBuild的Target
下一篇
[iThome第8屆鐵人賽 10]執行測試 1 - XUnit .Net
系列文
從.Net工程師的角度來看DevOps - 到底能夠幫助什麼 之 再戰江湖30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言