2015-05-13

[讀書筆記] [Continuous Delivery] Build and Deployment Scripting

Build and Deployment Scripting

Introduction
簡單的專案可以用簡單的方法進行建置與部署

只要專案規模稍微複雜點 建置與部署就會出現以下問題 :

  • 步驟會越來越繁複
  • 所需時間也會越長
  • 人工容易出錯


強烈建議使用Script來達成建置與部署的自動化

An Overview of Build Tools

  • Make & SCons
  • Ant
  • NAnt and MSBuild
  • Maven
  • Rake
  • Buildr
  • Psake


各個建置工具的不同點在於
任務導向
    e.g. Ant, NAnt and MSBuild
    根據一系列的任務來描述建置相依性
    不保存狀態(完全不適合C++)
    但對C# 沒有問題
    for example :
          要完成Init 或 Setup test data 的task之後 進行 compile source and test
          儘管很多task都必須依賴Init , 但執行過一次之後就不會再執行
 
產品導向
    e.g. Make
    跟據一系列的檔案來描述建置相依性
    增量式建置(C/C++)
    for example :
           確保compile source 跟 compile test之後的產出出來之後
           利用時間戳記來確是否進行Run Test
         


(1) Make & SCons
      http://zh.wikipedia.org/wiki/Make

      優點 :
                  (i) 能在單次建置中追蹤相依關係 只建置受本次修改影響的元件
                  (ii) 使用簡單
      缺點 :
                  (i) 相依複雜度增加時會難以除錯
                  (ii) 現代語言的IDE已經幫忙處理這塊
                  (iii) 依存在Shell上 (UNIX)

     “This is one of those days when I am not happy with software. It sometimes surprises me how many of those days involve Make.”
—Mark Dominus, “Suffering from ‘make install’”

      現在許多C/C++ Project的Developer都推薦使用SCons
       Why ?
                 1. Python 寫的
                 2. 支援Windows和並行建置

(2) Ant
      參考文件
      http://zh.wikipedia.org/wiki/Apache_Ant

      【認識 Gradle】(1)講古的時間 Apache Ant     
   
     優點 :
                (i) Jave寫的, 強大跨平台的能力
                (ii) Script用XML寫的
               
     缺點 :
                 (i)  XML不簡潔
                 (ii) 領域模型非常貧乏, 要耗費大量時間來編譯,產生jar,執行測試以及編寫樣板檔
                 (iii) 宣告式語言
                 (iv) 無法回答 執行了多少測試? 需要多久?
                 (v) Ant檔非常冗長 也難以重構

     若要使用Ant 推薦Julian Simpson寫的文章:
     “Refactoring Ant Build Files,” in The ThoughtWorks Anthology.      

(3) NAnt and MSBuild
     https://msdn.microsoft.com/zh-tw/library/0k6kkbsd.aspx

     Microsoft當初在導入.NET Framework時 很多Java的Developer將他們喜愛的工具移植到.NET上
   
     Ant  -> NAnt
     NAnt 變體 -> MSBuild

     MSBuild
     優點 :
                 (i) 與Visual Studio 緊密結合, 管理相依性較容易                
     缺點 :
                 (ii) 與Ant相同

(4) Maven
     http://zh.wikipedia.org/wiki/Apache_Maven
     【認識 Gradle】(2)講古的時間 Apache Maven

     Convention over configuration

     Maven被創造出來的動機如下 :
     (i) JAVA專案的標準化 -> 消除Ant大量樣板的問題
     (ii) JAVA專案函式庫管理的問題

     缺點 :
                (i) 缺乏彈性 : Project必須按照Maven規定的結構與生命週期
                (ii) XML
                (iii) 在預設與設置中, 總是自動更新自己 => 可能會導致不可預期的失敗

(5) Rake
      
     產品導向
     要安裝Ruby執行環境
     要用RubyGem建置

(6) Buildr
     
      Buildr 建立在Rake之上, 能做到Rake能做到的事
      作者推薦 如果想找Ant 或 Maven的替代品 強烈推薦 Buildr
      如果喜歡Groovy 就用 Gradle
    
(7) Psake
      
      支援Windows
      用PowerShell寫的內部DSL

Principles and Practices of Build and Deployment Scripting
以下將會提到幾點原則與實踐:


  1. Create a script for each stage in your deployment pipeline
  2. Use an appropriate technology to deploy your application
  3. Use the same scripts to deploy to every environment
  4. Use OS's packaging tools
  5. Ensure the Deployment Process is Idempotent
  6. Evolve your deployment system incrementally
(1) Create a script for each stage in your deployment pipeline
當Project開始時 或許可將script都寫在同一個檔案中
但是 一旦script變得太長 就要將它分成獨立的腳本

要確保所有的script都放在version control repository

(2) Use an appropriate technology to deploy your application
當我們在做自動化部署時 要使用合適的工具 而非general-purpose scripting language

Q : 何謂合適的工具?

When and Who?
在Project一開始就要進行時, Developers, testers, and operations staff都要一起來做部署
要一起決定部署的工具

CASE : One Telecoms Company

(3) Use the same scripts to deploy to every environment

使用相同的預設script部署到所有的環境
環境設置資訊必須分開管理

(4) Use OS's packaging tools
Problems : "將一堆檔案分別部署到檔案系統的不同位置" 效率又低且維護麻煩

要考慮到 upgrades, rollbacks, and uninstalls

Solution : 強烈建議使用 OS's Packaging Technology
For example :

  • Debian and Ubuntu : Debian Package System
  • RedHat and SuSE : RedHat Package System
  • Windows : Microsoft Installer System


也可以考慮使用platform-specific packaging system :
For example :

  • Ruby Gems
  • Python Eggs
  • Perl's CPAN


但如果可以 仍是推薦使用OS's Packaging Technology

(5) Ensure the Deployment Process is Idempotent
Idempotent : 無論做幾次 結果都要一樣

無論target environment現在處於什麼情況 當部署完畢之後target environment 上的狀態都要一樣

How to do?
1. 以已知狀態良好的環境當作起點
2. 驗證環境所需假設

每次部署時都應該根據version control 的某個單一修正版本產生的Binary從頭開始
當部署某元件時 就應該將相關的原件都重新部署一次 (Rebuild)

3個例外

  • (i) Clustered System (Chapter 10)
  • (ii) 應用程式是由多元件(不同version control repositories) => 要通過測試相關的所有元件組合 才可以只部署變更的元件
  • (iii) 使用可以讓效果Idempotent的Tool

(6) Evolve your deployment system incrementally
從簡單的小事開始做起
循序漸進

Deployment Scripting

核心原則 : 完全自動化

不要再遠端登入到環境上執行部署動作!!!

三種scripted deployments的方式 :
(1) 寫一支script 執行所有工作 (For  一台機器)
(2) 遠端部署 (For 多台機器)
(3) Script your own deployments (如果上述方法都不適用)

(1) 寫一支script 執行所有工作 (For  一台機器)
     因為只有一台機器 所以可以用一個script在local端執行所有工作

(2) 遠端部署 (For 多台機器)
      A set of deployment scripts
     (2.1) 寫script並登錄到遠端每台機器上執行
     (2.2) 在Local端寫script 利用agent在遠端每台機器上執行
     (2.3) 利用合適的OS's packaging technology
              第三種作法是最powerful
               why ?
               2.3.1 Idempotent
               2.3.2 管理部署及基礎建設可在同一套Tool上 不同團隊較容易溝通

    如果2.3找不到或無法使用這套方法
    找找看是否有包含Agent model的CI Server

(3) Script your own deployments (如果上述方法都不適用)

Deploying and Testing Layers

原則 :
總是把根基紮在已知狀態良好的基礎上


只有環境都設置完成 才能開始部屬軟體

Testing Your Environment’s Configuration

任何層次部屬出錯 都有可能造成應用程式無法正常執行
所以每個層次都需要進行測試

如果Fail 就讓環境設置流程快速失敗

For example :

  • Confirm that we can retrieve a record from our database.
  • Confirm that we can contact the website.
  • Assert that our message broker has the correct set of messages registeredin it.
  • Send several “pings” through our firewall to prove that it allows our traffic and provides a round-robin load distribution between our servers.


Tips and Tricks

  • Always Use Relative Paths
  • Eliminate Manual Steps
  • Build In Traceability from Binaries to Version Control
  • Don’t Check Binaries into Version Control as Part of Your Build
  • Test Targets Should Not Fail the Build
  • Constrain Your Application with Integrated Smoke Tests
  • .NET Tips and Tricks



(1) Always Use Relative Paths
建置中最常見的錯誤就是預設使用絕對路徑 (相依性)

所有位置都必須是相對路徑
能確保每個建置都是完整獨立的

如果不得不使用絕對路徑 請確保
1. 這是特例
2. 必須與建置系統相互獨立

盡量減少安裝於非標準位置的路徑

(2) Eliminate Manual Steps
"A bad system will beat a good person every time" 
by W. Edwards Deming

只要是手動 一定容易出錯

何時要考慮自動化呢?
當你不得不做第2次時

(3) Build In Traceability from Binaries to Version Control

確定某個Binary是由版本控管哪個版本產生
版本化的metadata

(4) Don’t Check Binaries into Version Control as Part of Your Build
不要把Binary當作建置的一部分check in進Version Control

因為我們總是能從重新建置一份

將Binary或是Report存到File System就好

經驗法則 :
不要將建置, 測試和部署期間產生的任何產出check in 進 Version Control
而是要將他們當作Metadata

(5) Test Targets Should Not Fail the Build
本書覺得不好的作法是 任何一個Fail都導致建置失敗

原因是 :
若是某個Unit Test Fail就導致Build Fail , 我們不曉得之後是否有更多測試沒過
要等下次建置才會測到未測到的部分, 一來一往之間更浪費時間

Solution :
1. 紀錄當下的錯誤 並註記1個 Flag
2. 經過完整的測試之後 根據Flag決定是否讓Build Fail

(6) Constrain Your Application with Integrated Smoke Tests

在部署之前另部署script檢查一下環境是否正確

(7) .NET Tips and Tricks
Problem 1
.NET .sln and .csproj 會記錄實際建置專案時所引用的reference, 但很有可能某個file已經不被引用了 但仍存在 file system中
Solution
在全部的sln中打開顯示隱藏檔案的屬性 , 刪除沒用到的File

Summary
script 可以輔助我們進行建置,測試,部署和發佈應用程式
請找出最痛苦的步驟, 開始嘗試自動化, 逐步完善自動化建置與部署的能力
Build and Deployment Scripting必須貫穿整個開發流程

0 意見: