2017年7月30日 星期日

[從.Net工程師的角度來看DevOps 21]Build階段的總結和重構 - Build Server介紹

image圖片來源:https://pixabay.com/en/books-spine-colors-pastel-1099067/ 和 https://blog.xebialabs.com/2016/03/21/essential-devops-terms/

在上篇[iThome第8屆鐵人賽 20]靜態程式碼分析之程式碼風格 - Stylecop介紹完了如何整合stylecop之後,build階段也差不多到了一個階段。

在這個階段裡面,從最基本的編譯、到執行單元測試、到整合程式碼測試的涵蓋率最後整合Code Analysis和stylecop,整個build基本要做的都做了,因此我們要開始進入如何把這個建制整合到builder server來達到CI的效果

在這篇,將會談到:

  1. 在一次重構和調整script - 以符合上build server執行的時候比較沒有問題
  2. 對build server做個簡單的介紹

重構build scrip

在這個階段加入的一些build task會需要在做一點重構方便上build server呼叫,這個部分將對重構內容做說明。

會重構的有:

  • 允許傳入參數的方式決定是否執行Stylecop和Code Analysis
  • 修正script裡面相對路徑是指執行位置而不是相對於檔案本身
  • 整合psake module - 直接load 整合的psake
  • 整合nuget restore

允許傳入參數的方式決定是否執行Stylecop和Code Analysis

不是每一個專案都會需要執行Stylecop和Code Analysis,因此我們可以調整compile,讓有傳入參數的時候在執行,沒有則不執行。

做法很簡單,就是加2個Properties,代表是否要執行Stylecop和Analysis,如果是false就不執行。

修正script裡面相對路徑是指執行位置而不是相對於檔案本身

在script裡面在執行一些檔案的時候寫了一些相對路徑的語法,舉例來說在build.ps1.\default.ps1

    Invoke-psake -buildFile .\default.ps1 -taskList Test `

乍看之下,會認為說這個的相對路徑是相對於當前檔案build.ps1)- 但是其實不是,這個相對路徑是相對於 執行檔案的位置。換句話說指的是呼叫script的位置。

這個會造成很大問題,因為假設你執行的時候和build.ps1是同樣的位置,那麼沒有問題。但是如果假設執行的位置和當前檔案位置不同,那麼整個路徑是錯的。

因此需要調整變成相對於script。

整合psake module - 直接load 整合的psake

之前psake load進來的版本都是用從nuget package下載下來的版本。在這邊調整為直接load一個準備好的版本。

這麼做的原因只是明確表示,目前使用的psake module版本是幾號(目前是4.6) - 可以增加如果nuget package有提供就用那個版本方便未來直接改版,但是目前沒有加入這個機制。

相關修改可以直接參考commit:[重構]讓load psake local版本 - 目前是4.6

整合nuget restore

有很多套件都依賴nuget下載下來,到目前為止都會先透過nuget下載,所以nuget package都有存在因此build都沒有什麼問題。

可是我們不會上packages資料夾,所以假設從github下載repo,其實根本無法build,需要先自己做nuget restore。

因此要在我們的build script裡面加上nuget restore。

和psake module一樣,會把nuget直接整合進來,目前使用的版本是3.5。

restore的方式很簡單,直接呼叫nuget restore $solutionFile

正常來說應該在default.ps1整合一個task在Init前先做nuget restoer就好,但是由於我們在Properties有一些路勁是從nuget的packages裡面取得(例如$xunitExe),這個會造成一個 執行順序的問題,假設在進入Task前packages還不存在,Properties的對應路徑會不存在,這個有兩個解決方式:

  1. 在執行到task之前先restore - 因此restore要寫在build.ps1
  2. 在default.ps1裡面使用global 參數 - 因此可以讓在執行nuget restore之後把參數的值改掉

目前選擇的方式是第二種 - 不選擇第一種的原因是其實要手動先執行nuget restore不直覺

相關修改可以直接參考commit:加入 nuget restore - nuget版本3.5

Build Server的目的和使用

Build Server講白一點環境和我們開發的機器沒什麼兩樣,他的唯一目的就是用來編譯專案

那或許會說既然和我們兩樣,那幹嘛還要有build server,直接用我們的機器編譯就好了?原因很簡單,完全是為了節省時間。

以我目前這麼簡單的一個範例專案,光建制和跑測試(不包含stylecop和code Analysis)就要跑將近1分鐘的時間,可以想象如果多人開發,每一次commit我都要在確認目前上面的code是不是建制沒有問題,假設一天有總共20個commit, 我就要浪費<20分鐘的時間(因為build的時候一定影響電腦上執行其他的效能,更別說要pull然後build等其他沒有算進來的時間)

因此我們用Build server做這件事情,只要有commit就自動幫我們建制是否有成功(至少要build成功,test執行成功,甚至如果有需要也可以設定當測試涵蓋率低於某個數字直接報錯)

雖然build server的環境從本質上來說和我們開發的一樣,但是我們開發會自己手動執行做build,但是在build server怎麼自動觸發呢?因此有所謂的build server的軟體可以管理/觸發自動build。

整個搭配起來就是所謂的Continous Integration(CI 持續整合) - 所以build server有時候也稱為CI Server

build server工具

既然了解了什麼是build server之後,就來了解一下如果要建制一個環境需有什麼build的軟體。

基本上來說還蠻多build server的工具,這些工具一般是一個專案會議組設定檔案用來設定如何建制這個專案。一般來說這些工具也提供一些已經寫好的script,讓大家直接連接專案然後非常簡單設定就會自動建制。

直接使用build server提供的script有好有壞,好處是簡單設定,壞處是無法在local跑和build server一樣的動作(因為不知道他的script跑了什麼) - 也是因為這樣所以這個專案的目的就是提供一個通用script能夠在build server跑也能在local跑。

常見的.net build server 有:

其實還有很多,用自己習慣就好。

這也是使用自己build script的好處,因為不會被build server綁死。只要能夠跑powershell都跑得了build script。

免費的build server

雖然上面提到的build server工具有些有免費的可以自己架設在自己的Server,可是自己架設畢竟需要自己管理,並且也要一筆費用(像是機器費用,Server License等),因此如果只是open source專案根本用不起。

因為這些費用的問題,因此以前很難找到給.net免費的CI Server。

幸好目前有非常佛心的服務可以讓我們在open source專案或者提供定量的次數讓我們可以免費使用。

這其中分別有:

  1. Visual Studio Team Service - TFS的雲端版本 - 提供每月240分鐘的免費build時間
  2. Appveyor - 提供open source免費的CI build服務

結語

在這篇重新把build script又調整了一下,讓我們上build server的時候執行不會有問題。

快速介紹了build server,和有哪些可以自己架設的build server - 在下一篇將會介紹Appveyor - 如何使用Appveyor來達到我們Open source專案的CI。


沒有留言 :

張貼留言

您或許對這些文章有興趣: