如何搭配 PowerShell 來進行自動化編譯 CI 和部署 CD - 不使用 WebDeployPackage 時
環境
Team Foundation server 2013 一台
Team Build Server 2013 一台
Release Management 2013 一台
UAT / Staging 各一台
Production 三台
使用的專案是 NopCommerce 3.30
設定的腳本 - 簡易說明
由於 NopCommerce 的過版程序比較多,而且有些環節出錯了程式就無法正確使用。 所以先將整個過版的程序列出,讓各位比較知道來龍去脈。
- 備份所有 source
- 解除 IIS WebApp
- 複製 NopWeb
- 複製 NopAdmin 到 NopWeb 底下的 Administation
- 將 NopAdmin 底下的 Bin 搬到 NopWeb 底下的 Bin
- 建立 IIS WebApp
- 執行 APPCMD 設定 HTTP Request Header ( 為了可以正確顯示 RWD )
- 設定 DefaultAppPool 要有 NopWeb 的存取權限
-
設定還原機制
- 還原所有 Source
- 解除 IIS Web APP
- 建立 IIS Web APP
可以看到雖然不是每次部署都要部到 9 個動作,但若是要從無到有地建置起來這 9 個步驟就是非常必要的且關鍵。就算是對這個系統非常熟悉的同仁,有再完整的手冊都難保過版的時候沒有少任何一個動作。通常都很容易忘記,因為完整地部署並不是每天會執行的。
所以自動化部署的腳本並不單單只是為了節省時間,更是為了要提高正確性降底人為的疏失。
相關的設定檔也要納入版本管控
之前我們介紹了如何用 RM 來設定 ASP.NET 的網站進行自動化部署,這個方式主要是使用 Web Deploy Package 。但若是遇到 Web Site 或是 無法打包成 Package 的話可能就必須要依靠自訂流程了。
使用 Release Management 設定 ASP.NET Web Application 進行自動化佈署 Continuous Deliver
有用過 NopCommerce 的朋友就知道,當系統第一次執行時會判斷是否有資料庫、建立資料和產生好設定檔之類的動作。所以,這個部分設定檔並不是在 Web.config 之中而是在其他檔案。這個檔案若是要做版本管控的話,就可能沒有辦法直接在原本的路徑上進行管理,因為會造成協同開發時設定檔之間的衝突,二來這個檔案也沒有 Web.config 那樣子有 web.release.config 的轉換機制存在。
因此我將所有要部署用的檔案單獨放在 Publish 的目錄之中,並且依照原本的架構存放。
因為是要透過 Release Management 部署,所以連線字串的部分已經先行更換成「變數格式」
另外因為 NopCommerce 有使用到 自訂輸出路徑來搬動 Plugins 的 dll 元件,所以這些檔案也必須要統一納入版本管控
別忘記要將這些的 plugins 的元件納入專案,這樣子在 Team Build 的時候才會一併搬到 PublishWebsites 之中。 ( 不然就要自已再寫 script )
了解 Team Build 的目錄結構
所有的 source 都會統一存放在 src 的目錄之下,而編譯過的檔案都會放在 Binaries 之中。最後才會再搬到 bin 之下,若是 ASP.NET 的話就會再放到 _PublishedWebsites 之中。
而剛剛的 Publish 要放在 _PublishedWebsites 的 Nop.web 底下,所以我們需要在編譯過後再透過 PowerShell 的方式搬過去
我這裡是將 PowerShell 的檔案放在 Publish 的上一層
$path = $args[0] + "\_PublishedWebsites\Nop.Web"
「Copy-Item .\Publish\Web\ $path -Force -Recurse」
為了可以覆蓋檔案所以加上了 –Force 和 –Recurse 兩個參數,記得 .\Publish\Web\ 後面就不要再加上 * 了 不然目錄會 copy 不過去。
當然這些指令都是在 ISE 中先確認過的
Team Build 設定 PowerShell
Release Management 的 Team Build 腳本如何使用 PowerShell 呢?
請先依照這份連結將「建置流程範本」升級到 12 的版本後才可以在 Team Build 中設定 power shell
先指定 ps1 的檔案 ( 一定要進版控,Team Build 才找得到 )
上面的參數請用「$(TF_BUILD_DROPLOCATION)」
Team Build 的變數可以參考這份連結
Team Foundation Build environment variables
http://msdn.microsoft.com/en-us/library/hh850448.aspx
因為透過 Team Build 編譯完成後會統一放到共享資料夾,而且會給予一個建置編號。所以在 PowerShell 中的路徑就不可以寫死
若設定都正確的話,建置就會成功了
看到 settings 檔也有 copy 過來就代表 powershell 都有正確執行
在 Release Management 設定 PowerShell 變成 單一元件
大部分我會用現成的元件來設定我的腳本,因為這樣子做最有效率,但複製資料夾時若來源資料夾不存在的話就會導致整個部署失敗。而部署我又不想要人工的方式把目錄設上去,所以加了一段 Powershell 而這個動作又會常常使用。索性就將 PowerShell 的項目直接包裝成 Action 可以直接托拉到腳本之中
在 Release Management 請在「詳細目錄—>工具」的地方可以新增我們的元牛
命令是「PowerShell」
引用是「-command .\CheckCreateFolder.ps1 '__Path__'」
檔案內容可以參考 [Memo]第一次就上手 PowerShell
接下來就是將新剛好的工具加入到「動作 Action」之中,這樣子才會出現在 左邊的工具列
選擇好工具後就會自動帶出相關的參數
確定沒問題後在發行範本中就會出現了
在 Release Management 設定 PowerShell – SetDefaultAppPoolPermissionAction
SetDefaultAppPoolPermissionAction 可以參考這個語法
若是 Command line 則是如下
iCacls.exe "C:\inetpub\wwwroot\NopCommerce" /grant "IIS APPPOOL\DefaultAppPool":(OI)(CI)M
在 Release Management 設定 PowerShell – SetHTTPRequestHeaderAction
依
SetHTTPRequestHeaderAction 可以參考這個
[Memo]如何用 PowerShell 修改 IIS 站台的設定 v3–HTTP Request Header 並處理 XML 結果
附上在 RM 上的設定項目
開始設定 Nopcommerce 的部署元件
和上一篇的說明一樣,當我們在 Copy 的動作想要更換特定的檔案內容 ( ex .. 設定檔 ) 就必須要將 Copy 的動作另外封裝成 元件才行。
「_PublishedWebsites\Nop.Web」
首先指定 NopCommerce 的網站來源位置,當然這裡有搭配 Team Build 。所以系統自然會知道 編譯完的檔案會放在指定的目錄上。
選擇 XCopy 部署器,若是要用自已的 PowerShell 的話,可以在 工具那邊增加
前面我們設定了 Settings.txt ,這邊我們要置換 Settings.txt 裡面的 ConnectionString 變數。
設定好之後,也別忘了 Nop.Admin 也要做一樣的設定
最出列出所有的程序提供給大家,當然,若是這個過程想要打包成一個 Action ,這也是沒有問題可以透過 工具—>元件的方式封裝起來後參數化就可以重複使用了
開始自動化的部署
立馬開始驗證一下我們的自動化部署的腳本
直接簽入一個新的版本後,系統就自動觸發 Team Build
GOOD!全部都是綠燈打勾!
發行總管中也有正常出現,網站也可以正常運作
UAT 也正常運作
結論
現在講求任何事情就是要快的時代,客戶要求我們要上線快,主管要求我們要寫的快。身為一個專業的工程師就必須要尋求一種心法來快速練成神功 ( 不是自宮的那種 ) ,更重要的是絕對不要等到專案數量很多了才來考量到自動化,等到要上前殺敵了才來看怎麼使用大炮,這樣子就絕對來不及而且你也不會有那個心思來弄這些東西。
畢竟,專案在趕的時候,誰給你管品質?管上線自動化啊 ,但這個問題不去面對以後只會更痛而已。
另外,像是有在導入流程改善的團隊,絕對不要只有考慮到「文件」的流程改善,而是要思考如何利用自動化讓開發到上線整體的時程可以縮短又兼顧到 SOP 才是真正的關鍵
參考資料
http://www.dotnetcurry.com/showarticle.aspx?ID=964
http://technet.microsoft.com/en-us/library/ee156818.aspx