以下是Wiki對於CI的解釋
持續整合(英語:Continuous integration,縮寫CI)是一種軟體工程流程,是將所有軟體工程師對於軟體的工作副本持續整合到共用主線(mainline)的一種舉措。
該名稱最早由[1]葛來迪·布區(Grady Booch)在他的布區方法[2]中提出,不過他並沒有提到要每天整合數次。之後該舉措成為極限編程(extreme programming)的一部份時,其中建議每天應整合超過一次,甚至達到數十次。
[3]在測試驅動開發(TDD)的作法中,通常還會搭配自動單元測試。持續整合的提出主要是為解決軟體進行系統整合時面臨的各項問題,極限編程稱這些問題為整合地獄(integration hell)。
而自己對CI的見解是,透過軟體版本控管機制,持續將每個分支每次修改進行整合,並且透過自動化的測試、佈署、執行報告來控管軟體品質。
而這篇是要寫如何透過VSTS來達成此目標,跟整個設定的過程,先來整理要達成的目標項目。
希望
1.版控更新時,自動建置
2.自動執行單元測試
3.將建置好的檔案放到佈署資料夾(之後讓CD接手,做自動化佈署到正式機、測試機..等)
4.回報上述執行結果
版控更新時,自動建置
1.到VSTS網站頁面,選擇Build and Release > +New
[![](https://3.bp.blogspot.com/-XS-Ogl-wsag/WmmPVNrH_bI/AAAAAAAAIV8/cjl3VdVp6gsL11fiftfSCIcec9EsE_gGgCLcBGAs/s640/1.png)](https://3.bp.blogspot.com/-XS-Ogl-wsag/WmmPVNrH_bI/AAAAAAAAIV8/cjl3VdVp6gsL11fiftfSCIcec9EsE_gGgCLcBGAs/s1600/1.png)
**
**
2.選擇Empty process
[![](https://4.bp.blogspot.com/-qw_0GPoI3i4/WmmPmH3ClGI/AAAAAAAAIWA/pMV4k7v1uZQlucvGW5U0dy_Mu2MjwCVdQCLcBGAs/s400/1.png)](https://4.bp.blogspot.com/-qw_0GPoI3i4/WmmPmH3ClGI/AAAAAAAAIWA/pMV4k7v1uZQlucvGW5U0dy_Mu2MjwCVdQCLcBGAs/s1600/1.png)
Process Agent queue設定
[![](https://4.bp.blogspot.com/-nv9FB-OKBu8/WmmiC6TnyPI/AAAAAAAAIYs/unfIYRSe9wgUs1490wBHMKwp9_bOsAC_QCLcBGAs/s640/1.png)](https://4.bp.blogspot.com/-nv9FB-OKBu8/WmmiC6TnyPI/AAAAAAAAIYs/unfIYRSe9wgUs1490wBHMKwp9_bOsAC_QCLcBGAs/s1600/1.png)
3.加入Nuget restore Task,因為我們專案都有用Nuget,所以需要在建置之前先還原Nuget,設定如下
[![](https://1.bp.blogspot.com/-hFBqYKbzhfI/WmmUkjd318I/AAAAAAAAIWc/VnQOMKDfOWUFlsdbTwtgOzDsuEo1HyDWwCLcBGAs/s640/1.png)](https://1.bp.blogspot.com/-hFBqYKbzhfI/WmmUkjd318I/AAAAAAAAIWc/VnQOMKDfOWUFlsdbTwtgOzDsuEo1HyDWwCLcBGAs/s1600/1.png)
[![](https://1.bp.blogspot.com/-8bU6NhV_axk/WmmSF6nLdzI/AAAAAAAAIWQ/xR8dyhcgSP8e9s4c5pukjKhgmiqKKmyYwCLcBGAs/s640/1.png)](https://1.bp.blogspot.com/-8bU6NhV_axk/WmmSF6nLdzI/AAAAAAAAIWQ/xR8dyhcgSP8e9s4c5pukjKhgmiqKKmyYwCLcBGAs/s1600/1.png)
這邊Feed to use 我選擇Feeds in my Nuget.config,原因是公司專案有用自己開發的Nuget套件,而那些Nuget放的位置就需要自訂的Config讓建置機器知道,否則抓不到那些套件,待會建置就會錯誤,如果專案沒有用內部Nuget Server的套件,就選第一個即可。
通常如果我們有用私人的Nuget套件,一定會在VS設定套件來源,而這個設定檔就會放在底下這個位置
%appdata%\NuGet\NuGet.Config
把檔案放進版控中,就可以讓VSTS選的到了
4.加入Build Solution Task
[![](https://4.bp.blogspot.com/-P83wkuHiW_Q/WmmU9NttxhI/AAAAAAAAIWg/eKcneONO0H0amRUTTrN0KmMSpKnIHFaCgCLcBGAs/s400/1.png)](https://4.bp.blogspot.com/-P83wkuHiW_Q/WmmU9NttxhI/AAAAAAAAIWg/eKcneONO0H0amRUTTrN0KmMSpKnIHFaCgCLcBGAs/s1600/1.png)
[![](https://1.bp.blogspot.com/-VpXPU2_Rkb8/WmmVvzSQSBI/AAAAAAAAIWs/Mpu-mZu4gqEzXQBfEqurgLBwRxTc2fp_ACLcBGAs/s640/1.png)](https://1.bp.blogspot.com/-VpXPU2_Rkb8/WmmVvzSQSBI/AAAAAAAAIWs/Mpu-mZu4gqEzXQBfEqurgLBwRxTc2fp_ACLcBGAs/s1600/1.png)
**
***這邊MSBuild Arguments裡面的PublishProfile=CICD,意思是說我們要用的發行檔名稱,而名稱就做CICD,所以等等我們會回VisualStudio建立一個名叫CICD的發行檔
*Configuration,是說我要用Debug的組態檔來建置,如果你不知道組態檔是什麼,請看
5.建立CICD發行檔
[![](https://4.bp.blogspot.com/-fXHi2n6VZFM/WmmYCGCjFAI/AAAAAAAAIW4/5zbkFrA19Fon58CJBVLTEUJR3Chqz50iQCLcBGAs/s400/1.png)](https://4.bp.blogspot.com/-fXHi2n6VZFM/WmmYCGCjFAI/AAAAAAAAIW4/5zbkFrA19Fon58CJBVLTEUJR3Chqz50iQCLcBGAs/s1600/1.png)
[![](https://1.bp.blogspot.com/-l1gb4UnmpmM/WmmYYZTNDxI/AAAAAAAAIW8/0HjBNGwjRNMIErNyx8lrVf4Hy7TZ88x9ACLcBGAs/s400/1.png)](https://1.bp.blogspot.com/-l1gb4UnmpmM/WmmYYZTNDxI/AAAAAAAAIW8/0HjBNGwjRNMIErNyx8lrVf4Hy7TZ88x9ACLcBGAs/s1600/1.png)
[![](https://1.bp.blogspot.com/-32aEvFZCe6g/WmmZW11jZ0I/AAAAAAAAIXI/2Ei-9zh3KhQx06veBMtbWEa7H4tc3idvgCLcBGAs/s400/1.png)](https://1.bp.blogspot.com/-32aEvFZCe6g/WmmZW11jZ0I/AAAAAAAAIXI/2Ei-9zh3KhQx06veBMtbWEa7H4tc3idvgCLcBGAs/s1600/1.png)
[![](https://2.bp.blogspot.com/-1RqfQqrD0C8/WmmZoZZViaI/AAAAAAAAIXM/34faHBlj3c4KF4xz7FwZnZmWayUpSodlwCLcBGAs/s320/1.png)](https://2.bp.blogspot.com/-1RqfQqrD0C8/WmmZoZZViaI/AAAAAAAAIXM/34faHBlj3c4KF4xz7FwZnZmWayUpSodlwCLcBGAs/s1600/1.png)
你可以先用VS發行看看,應該會在專案的Root資料夾底下長出一個Publish的資料夾,底下內容如下
[![](https://1.bp.blogspot.com/-PzHy8-PeILA/WmmaFi-990I/AAAAAAAAIXU/lms69Y9-8BcER7sAvGlMt2x38tEUFQcagCLcBGAs/s640/1.png)](https://1.bp.blogspot.com/-PzHy8-PeILA/WmmaFi-990I/AAAAAAAAIXU/lms69Y9-8BcER7sAvGlMt2x38tEUFQcagCLcBGAs/s1600/1.png)
之後WebDeply就靠這些檔案了。 回到VSTS繼續設定
6.加入Visual Studio Test Task
[![](https://4.bp.blogspot.com/-QBXq7Esdoro/WmmarbzFXlI/AAAAAAAAIXc/yTYh8E4y8Uwq1NX4NTjHjxUJFoxvAJKvACLcBGAs/s400/1.png)](https://4.bp.blogspot.com/-QBXq7Esdoro/WmmarbzFXlI/AAAAAAAAIXc/yTYh8E4y8Uwq1NX4NTjHjxUJFoxvAJKvACLcBGAs/s1600/1.png)
[![](https://4.bp.blogspot.com/-Ik2JJshPoNw/WmmbErAetqI/AAAAAAAAIXg/iBT1z4W5SfUMPIwsR6Cgk8O5FC2Ox-KjwCLcBGAs/s400/1.png)](https://4.bp.blogspot.com/-Ik2JJshPoNw/WmmbErAetqI/AAAAAAAAIXg/iBT1z4W5SfUMPIwsR6Cgk8O5FC2Ox-KjwCLcBGAs/s1600/1.png)
紅框處是告訴這個Task,如何找到你的單元測試Dll來執行,如果你建立單元測試專案都是用預設的方式,那單元測試的專案名稱應該都會是 xxxTest,所以建置出來的Dll也會是xxxTest.dll,符合紅框預設尋找的條件,所以不用調整
7.加入Copy Files Task
目的是如果前面幾個Task都通過執行到這邊,表示建置沒有問題,且單元測試全部通過,所發行出來的檔案,加下來要把這些檔案複製出來,準備移到成品資料夾
[![](https://3.bp.blogspot.com/-Tr8vDR0SmDU/WmmciCbYKwI/AAAAAAAAIXw/5i0cUOgtWDQLXiCveVshcpqSZa1ZQscNACLcBGAs/s400/1.png)](https://3.bp.blogspot.com/-Tr8vDR0SmDU/WmmciCbYKwI/AAAAAAAAIXw/5i0cUOgtWDQLXiCveVshcpqSZa1ZQscNACLcBGAs/s1600/1.png)
[![](https://3.bp.blogspot.com/-kmgOU-k_3jY/Wmmc_n-HXlI/AAAAAAAAIX0/0P0WAy6oXRUmGStC-upMnLfFPWck3ydFACLcBGAs/s640/1.png)](https://3.bp.blogspot.com/-kmgOU-k_3jY/Wmmc_n-HXlI/AAAAAAAAIX0/0P0WAy6oXRUmGStC-upMnLfFPWck3ydFACLcBGAs/s1600/1.png)
黑框遮掉的部分就跟之前一樣是專案名稱,我的專案名稱是XXX.Application,所以那個區段請自行置換。
另外還記得Publish這個資料夾嗎?這就是我們剛剛在Visual Studio設定在CICD發行檔的建置發行檔存放的位置,套上預設VSTS建置專案的資料夾變數位置,就變成這行的值了
8.將成品資料夾內容丟到Drop資料夾
[![](https://3.bp.blogspot.com/-88XzfFqDwog/WmmeuQ9zKzI/AAAAAAAAIYE/oIV5xH2wEgADVD-jNi-boqu6ZySliBYnwCLcBGAs/s400/1.png)](https://3.bp.blogspot.com/-88XzfFqDwog/WmmeuQ9zKzI/AAAAAAAAIYE/oIV5xH2wEgADVD-jNi-boqu6ZySliBYnwCLcBGAs/s1600/1.png)
[![](https://2.bp.blogspot.com/-RJHr9xJXX60/Wmme3l784sI/AAAAAAAAIYI/Az3zsxDNF38IududQuL3s8zkk7WEDpGmQCLcBGAs/s640/1.png)](https://2.bp.blogspot.com/-RJHr9xJXX60/Wmme3l784sI/AAAAAAAAIYI/Az3zsxDNF38IududQuL3s8zkk7WEDpGmQCLcBGAs/s1600/1.png)
到這邊CI的任務大致完成,已經能將專案自動建置、單元測試、將成品打包準備佈署到Server,接下來如何將這成品佈署到Server就是CD的議題了,留待之後在說。
這邊還有最重要的一點,既然是持續整合,那這些任務如何自動化的持續整合,如果每次版控有異動都還要人來操作這些任務,那就失去了持續整合的意義。
將CI任務加上Trigger條件
[![](https://4.bp.blogspot.com/-mpvJaiE8Apc/WmmgTg2yIJI/AAAAAAAAIYY/7FH7zn14ovMWFtsIKCMYhFcW4k4Hm3SSACLcBGAs/s640/1.png)](https://4.bp.blogspot.com/-mpvJaiE8Apc/WmmgTg2yIJI/AAAAAAAAIYY/7FH7zn14ovMWFtsIKCMYhFcW4k4Hm3SSACLcBGAs/s1600/1.png)
這邊設定意思是說,當這個專案的Develop分支有新的Commit進來時,剛剛設定的那些任務就會被自動化的執行。
而每次執行的結果如下
[![](https://4.bp.blogspot.com/-22JmmaFCkjs/Wmmg5b-NLhI/AAAAAAAAIYg/H9clp3fIeF0NQsHTs96xEr3uSkvnExEfwCLcBGAs/s400/1.png)](https://4.bp.blogspot.com/-22JmmaFCkjs/Wmmg5b-NLhI/AAAAAAAAIYg/H9clp3fIeF0NQsHTs96xEr3uSkvnExEfwCLcBGAs/s1600/1.png)
點擊每一次進去可以看到執行的狀況,或是以及錯誤的Log
[![](https://3.bp.blogspot.com/-GNDMtKmEkwg/WmmhlqGuDTI/AAAAAAAAIYo/7tgSawThmfQw6sYKRu9B9k2TkyHwXBG2ACLcBGAs/s640/1.png)](https://3.bp.blogspot.com/-GNDMtKmEkwg/WmmhlqGuDTI/AAAAAAAAIYo/7tgSawThmfQw6sYKRu9B9k2TkyHwXBG2ACLcBGAs/s1600/1.png)
也可以手動排Queue,讓他立即依據現在最新版本或是特定版本去執行
[![](https://1.bp.blogspot.com/-EJjqIGXvgro/Wmmik_1pz3I/AAAAAAAAIY4/8QLNaTEmJrMhAK871kW4yf_YLSyUlMQ5QCLcBGAs/s640/1.png)](https://1.bp.blogspot.com/-EJjqIGXvgro/Wmmik_1pz3I/AAAAAAAAIY4/8QLNaTEmJrMhAK871kW4yf_YLSyUlMQ5QCLcBGAs/s1600/1.png)
[![](https://3.bp.blogspot.com/-X-V_2Mj63Cs/Wmmi0um07kI/AAAAAAAAIY8/hEtz4yx2s94wJppHAoL2eT6jR0a9DIzgACLcBGAs/s400/1.png)](https://3.bp.blogspot.com/-X-V_2Mj63Cs/Wmmi0um07kI/AAAAAAAAIY8/hEtz4yx2s94wJppHAoL2eT6jR0a9DIzgACLcBGAs/s1600/1.png)
Commit可以填入Git的Commit ID,如果不填就會用最新版執行建置。