版控的下一步 – Build Automation System

版本控制系統(Version Control)是近代軟體工程必要的一部份,只要是專注於軟體開發的公司或是部門,都必定擁有這一環,   當建置好版本控制系統後,接著要思考的是下一步,通常這指的就是建置系統(Build System),也稱為自動建置系統(Build Automation  System)

 

 

 

 

/黃忠成

 

關於版控

 

   版本控制系統(Version Control)是近代軟體工程必要的一部份,只要是專注於軟體開發的公司或是部門,都必定擁有這一環,如果沒有,那……祝你好運。

   當建置好版本控制系統後,接著要思考的是下一步,通常這指的就是建置系統(Build System),也稱為自動建置系統(Build Automation System),這個系統可以在Commit發生時自動建置版控上的程式碼,然後通知團隊成員建置是成功還是失敗,這可以有效地確認目前版控上的程式碼是可以正常建置的,不能保證可以建置的程式碼在版控中只是流水帳而已。

那麼為什麼版控上的程式碼會無法建置呢? 對於如果你處於一個長期使用版控的環境下,那麼對這種情況必然不陌生,舉個例來說,A Commit了一段程式碼,自然他一定是在本機能正常建置的情況下才Commit,但B Pull下來後卻是無法建置,原因在於A 所Commit的文件並不完整,有些外部的Reference或是文件沒有Commit到版控裡去。

   那有哪些情況呢?舉個例來說,專案使用了3rd Party元件,例如Telerik,在本機上是有的,但在別人電腦上沒有,如果沒有連這些3rd Party元件一起Commit進去,自然B就建置不起來。

   同樣的,這也常發生在使用額外的SDK,例如DirectX等,這些可以統稱為建置環境,重建或是複製這個建置環境,通常需要一個完全了解這個Project的人才能一一克服。

   建置系統(Build System)就是為了解決這種A可以Build但B不行的情況而誕生的,建置系統通常會在Commit發生時自行建置,這使用的不是A或B的環境,而是一個全新,乾淨的環境,這迫使我們一定得將所有建置相關的動作全部放在版控系統上面,只要建置失敗,所有相關的人都會收到通知,確保版控系統上的程式碼是可以建置成功的(當然,能不能正常運作是另外一件事)。

 

有這麼難嗎?

 

   這要看專案和選擇的Build System而定,如果開發的是一個純Web、沒有用到一些冷門的套件,那麼建構建置系統還真的不難,多數情況下現行的Package Manager就可以解決環境的問題,但如果專案使用了一些付費,不可能存在於公開的Package Manager System中的套件,那麼如何在乾淨的環境下重建建置環境就會是個不小的問題。

   如果選擇的是使用VM來做Build System的基礎,那麼問題就更小了,因為我們可以完全控制VM上的環境,少了什麼就裝什麼就好了。

   目前我使用的的Build System主要是Jenkins 跟Visual Studio Team Services(Online),Jenkins因為需要一個VM,所以問題小很多,只要在該VM上手動佈置所有環境即可,較大問題的是VSTS,因為是雲端環境,每次建置都是一個全新的開始,不可能手動去佈置環境,這是壞事也是好事,好事就是可以確保版控上的東西就是完整的,只要Pull就能建置(當然,如果連編譯器都沒有就掛了。),接下來我們就先談談VSTS的建置吧。

 

第一步

 

  首先我假設你已經有一個VSTS的Services存在了,如果沒有,請至https://www.visualstudio.com/products/visual-studio-team-services-vs弄一個,另外,本文以VSTS的Git作為版控,基本上這沒有太大的問題,因為VSTS也能整合GitHub來完成同樣的動作,差別沒有很大。

  我們由VSTS的起始頁面開始,當建立好一個新的VSTS之後,應該會看到圖001的畫面,於此輸入專案名稱及選擇版控系統。

圖001

完成後到002的畫面。

圖002

 

接著建立一個新的WPF Project。

圖003

連結版本控制系統。

圖004

Commit。

圖005

這裡需填入VSTS的Git Repo URL。

圖006

以本文為例,就是如下圖。

圖007

其實對應的就是於VSTS上建立的Project中的CODE頁籤內容。

圖008

按下Publish後,Visual Studio會詢問VSTS的帳號資訊,填入正確就可以完成Commit&Push,一切無誤的話就能於VSTS上看到Code。

圖009

接著就開始整合建置系統,按下setup now,就會進入建構建置系統。

圖010

VSTS內建許多建置範本,以本例來說自然是選擇Visual Studio這個,此範本是透過MSBuild來建置,按下Next之後就會到圖011的畫面,這裡可以選擇使用哪個Repository及Branch來建置

圖011

其中可以看到Continuous integration的選項,勾選這個選項可以讓這個Build在每次的Commit之後觸發,通常這裡會勾起來。接著到下一頁。

圖012

這裡可以設定使用哪個.sln來建置,如果方案中包含多個專案,那麼這裡要小心處理,我們後面會談到這部分,以這個專案來說,這裡使用預設就可以了,按下Save給他一個名字吧。

圖013

之後你隨時可以按下Queue Build按鈕來啟動這個建置動作。

圖014

圖015

對於較複雜的專案來說,圖015畫面裡的資訊其實很重要,不過這個專案實在很簡單,預設就可以跑了,按下OK按鈕後,會看到有趣的圖016畫面,其實就是個命令列。

圖016

沒問題的話就會看到017的畫面。

圖017

回到Code頁籤,感覺是不是很不錯?

圖018

以後只要Commit之後,這個建置動作就會自動執行了,如果想在建置失敗後收到Mail,那可以透過Control Panel來設定Alert。

圖019

接著我們進入主題,在這個Project上加入3rd Party元件,本例是Telerik WPF。

圖020

Commit之後到VSTS網站,可以看到Build已經被排程。

圖021

但很不幸的掛了。

圖022

檢視錯誤訊息,可以看到因為是Telerik元件才失敗,因為VSTS沒有內建這個元件。

圖023

此時有兩個選擇,第一個是架構自己的Nuget Server,把Telerik的元件打包成Nuget Package(別忘記,這東西是要錢的,所以自然要放在有密碼保護的Nuget Private Server),VSTS可以透過Nuget來還原所需要的套件。第二個選擇比較簡單,就是把用到的Telerik DLL檔一併簽入,例如以下畫面。

圖024

記得小心調整References相關項目的路徑。沒問題的話建置就會成功。

圖25

很鴕鳥,但也很有效,當然,較完整的解法應該是建置自己的Nuget Server,不過.NET 環境實在是簡單到我不想花時間去建自己的Nuget Server,這留到後面來談吧。

(PS: Git是以目錄為基礎的,所以就算不明確加入專案中,也可以在目錄下建置refs然後Commit至Git來達到同樣效果。)

 

本文後記

 

  Build System的基礎就是如何創造同樣的環境來建置,不管是地端還是雲端都是一樣的,VSTS提供了很多 Task範本,透過這些範本可以讓開發者自訂建置的過程,目的就只有一個,創造一個與地端同樣的建置環境,而要在不改動專案內容來配合Build System的前提下,如Nuget、Cocoapods、npm等普遍的套件管理系統就是關鍵角色。

圖026