---
title: Jenkins + TFS(Azure DevOps Server) + Windows
lang: zh
tags: Jenkins, TFS, Azure DevOps Server, Windows, CI, CD
description: The steps of setting up the environment of CI/CD on Windows, using Jenkins and Azure DevOps Server.
image: https://jenkins.io/images/logos/jenkins/jenkins.svg
---
# Jenkins Intro

__Table of Contents__
[TOC]
## 基本流程圖
```flow
s=>start: 本地測試通過
e=>end: 收工
vc=>operation: 版本控制(commit or sign in)
Jen=>inputoutput: Jenkins
build=>condition: Build
test=>condition: Test
deploy=>condition: Deploy
notify=>operation: Notify someone
s->vc->Jen->build->test->deploy->e
build(yes)->test
build(no)->notify
test(yes)->deploy
test(no)->notify
deploy(yes)->e
deploy(no)->notify
```
## Jenkins 簡介
 
Jenkins是一款由Java編寫的開源的持續整合(Continuous Integration,簡稱 CI )工具。
Jenkins提供了軟體開發的持續整合服務。它執行在Servlet容器中(例如Apache Tomcat)。它支援軟體組態管理(SCM)工具(包括AccuRev SCM、CVS、Subversion、Git、Perforce、Clearcase和RTC),可以執行基於Apache Ant和Apache Maven的專案,以及任意的Shell指令碼和Windows批次處理命令。
可以通過各種手段觸發構建。例如提交給版本控制系統時被觸發,也可以通過類似[Cron](https://zh.wikipedia.org/wiki/Cron)的
機制排程,也可以在其他的構建已經完成時,還可以通過一個特定的URL進行請求。
## 於Windows環境中安裝Jenkins

前往[Jenkins官網](https://jenkins.io/)下載Windows版的安裝檔。安裝檔內含有JRE,因此不須額外下載。
按照說明操作,即可完成安裝與初次登入。
## 啟動與開啟Jenkins
Jenkins預設於本機的8080埠,只要開啟網頁瀏覽器,並於網址列輸入` http://localhost:8080 `即可進入。
若尚未啟動Jenkins,則須依照下列指示操作:
1. Jenkins預設安裝位置為` C:\Program Files (x86)\Jenkins `
2. 開啟命令提示字元(CMD)前往該目錄下的` /jre/bin `檔案夾
3. 對根目錄下的 *jenkins.war* 執行` java -jar ../../jenkins.war `指令即可啟動
## 儀表板(Dashboard)介紹
僅針對本篇會使用到的部分大略簡單介紹
### 新增項目 (New Item)
新增工作的頁面,可新增許多不同種類的專案:
- 自由格式專案 (Freestyle project) - 本篇使用的專案
- 管線 (Pipeline) - 通常用於大量建置
安裝額外的外掛(plugin)後,能新增其他對應的工作,例如:Maven project
### 管理Jenkins (Manage Jenkins)
用於系統性的管理項目都會在此操作:
- 設定系統 (Configure Sytem) - 設定語言、E-mail設定、FTP設定
- 全域工具設定 (Global Tool Configuration) - 外掛的設定,例如:MSBuild、MSTest、VSTest
- 管理外掛程式 (Manage Plugins) - 安裝、更新或檢視外掛
## 建置Azure DevOps Server(TFS)上的專案
使用 TFVC 版本管理,利用MSBuild建置 TFS 上的專案
### 前置作業
於管理外掛程式頁面的右上角篩選欄位搜尋,安裝以下外掛:
- [Team Foundation Server Plug-in](https://plugins.jenkins.io/tfs/)
- [MSbuild Plugin](https://plugins.jenkins.io/msbuild/)
勾選需要安裝的項目後,按下**下載並於重新啟動後安裝**即可
#### 設定MSBuild
1. 若已有Visual Studio IDE則可能已安裝於該檔案夾底下;若無,則需前往Microsoft下載MSBuild。
目前[^1]最新版本為[MSBuild 2019](https://visualstudio.microsoft.com/zh-hant/downloads/?q=build+tools "Build Tools for Visual Studio 2019")。
2. 安裝完成後,前往 **Global Tool Configuration** 設定MSBuild
3. 找到MSBuild欄位,點選**新增MSBuild**
4. 輸入之後將顯示於Jenkins內的名稱,像是v15.0、MSBuild v16
5. 最後填上MSBuild.exe所在的資料夾位置即可儲存離開,例如:`"C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\MSBuild\Current\Bin"`
### 新增自由格式專案 (Freestyle project)
1. 於**儀表板(Dashboard)** 左側點選 **新增項目(New Item)**
2. 輸入此工作(Job)名稱,選選 **自由格式(Freestyle)** 專案,再點選OK即完成
### 設定專案 (Configuration)
1. 進入專案後,於左側點選 **設定(Configure)**
2. 於**原始碼管理(Source Code Management)** 勾選使用 TFVC,填入相關資料
   | Name           | Value                               |
   | -------------- | ----------------------------------- |
   | Collection URL | http://192.168.xx.xxx:8080/tfs/ABD/ |
   | Project path   | $/Dev/JenkinsTest[^2]               |
   | Credentials    | Manual                              |
3. 於建置欄位新增建置步驟**Build a Visaul Studio project or solution using MSBuild**,選擇之前設定的MSBuild版本,需要建置的檔案,以及額外參數。E.g.,
   | Name                   | Value              |
   | ---------------------- | ------------------ |
   | MSBuild Version        | MSBuilv4           |
   | MSBuild File           | AsyncCoinMiner.sln |
   | Command Line Arguments | /t:restore         |
4. 按下儲存後即完成
### 建置 (Build Now)
1. 設定完成後,於專案頁面左側點選**馬上建置(Build Now)**,即開始運行
2. 結果可於**建置歷程(Build History)** 查看::red_circle:紅色表示失敗,:large_blue_circle:藍色表示成功
3. 點擊該次建置的**Console Output**可查看詳細內容
## 測試專案
使用VSTest(或MSTest)進行測試作業
### 前置作業
於**管理外掛程式(Manage Plugins)** 頁面安裝[VSTest Runner plugin](https://plugins.jenkins.io/vstestrunner/)
若擁有Visual Studio IDE,則預設安裝於
_%Program Files(x86)%\\Microsoft Visual Studio\\<version>\\<edition>\\common7\\ide\\CommonExtensions\\<Platform | Microsoft>_
,例如:`C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\Extensions\TestPlatform\vstest.console.exe`
若無則需安裝[Visual Studio](https://visualstudio.microsoft.com/zh-hant/thank-you-downloading-visual-studio/?sku=Community&rel=16 "Visual Studio 2019 Community")
#### 設定VSTest
1. 進入**Global Tool Configuration** 頁面
2. 於VSTest欄位按下**新增VSTest**
3. 填入名稱與vstest執行檔的路徑,例如:
   | Name           | Value                                                                                                                      |
   | -------------- | -------------------------------------------------------------------------------------------------------------------------- |
   | Name           | VSTest                                                                                                                     |
   | Path to VSTest | "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\Extensions\TestPlatform\vstest.console.exe"[^3] |
4. 按下儲存後即完成
### 設定專案 (Configure)
1. 於建置項目按下**新增建置步驟(Add build step)**,並選擇**Run unit tests with VSTest.console**
2. 在Test Files欄位填入需要測試的檔案,e.g., `UnitTestProject1/bin/Debug/netcoreapp3.1/UnitTestProject1.dll`
3. 按下儲存即完成
### 測試結果
建置完成後,即可到**Console Output**查看測試結果
## 專案部署
利用FTP傳送檔案至指定位置
### 前置作業
於管理外掛程式(Manage Plugins)安裝[Publish over FTP](https://plugins.jenkins.io/publish-over-ftp/)
#### 設定FTP Server
1. 前往**設定系統(Configure System)** 頁面
2. 於**Publish over FTP**欄位點選**新增(Add)**
3. 填上所需資料,e.g.,
   | Name             | Value      |
   | ---------------- | ---------- |
   | Name             | Local Host |
   | Hostname         | localhost  |
   | Username         | root       |
   | Password         | pwd        |
   | Remote Directory |            |
4. 可於**進階(Advanced)** 設定埠號、TLS...
5. 按下儲存後即完成
### 設定專案 (Configure)
1. 於**建置後動作(Post-build Actions)** 欄位按下**新增建置後動作(Add post-build action)**
2. 選擇之前設定好的名稱
3. 填入需要上傳的檔案、移除路徑前綴...,e.g.,
   | Name             | Value                                   |
   | ---------------- | --------------------------------------- |
   | Source files     | AsyncCoinMiner/bin/Debug/netcoreapp3.1/ |
   | Remove Prefix    | AsyncCoinMiner/bin/                     |
   | Remote directory | /                                       |
4. 進階(Advanced)內部可設定要排除的檔案...
5. 按下儲存即完成
最後於專案頁面按下**馬上建置(Build Now)** 後即可部署至指定伺服器
## 自動建置
除了手動按下馬上建置(Build Now)以外,還有許多方法能夠讓Jenkins觸發建置行為。
以觸發建置器上的選項來看,目前較常用的有:
- Build when a change is pushed on to TFS/Team Services
- 輪詢 SCM (Poll SCM)
由於第一個方法需要取得 TFS 的權限,因此對於無法輕易取得權限者較不易達成,故本章節將著重在使用輪詢SCM來達成定時檢查是否有新版本需要執行操作。
### Build when a change is pushed on to TFS/Team Services
在TFS的專案設定中,設定服務掛勾(Service Hooks)即可使用
### 輪詢SCM (Poll SCM)
標準Schedule寫法為類似cron的語法,每行5個欄位,使用空格或TAB分格開
```
* * * * *
```
`*` 代表任何符合規範的數字
| 欄位順序 | 意義                                 |
| -------- | ------------------------------------ |
| 1        | 分鐘,0~59                           |
| 2        | 小時,0~23                           |
| 3        | 該月天數,1~31                       |
| 4        | 月份,1~12                           |
| 5        | 星期中的日子,0~7,其中0和7皆為星期天 |
#### 範例
- `H/3 * * * *` - 每三分鐘執行一次
- `13 H/2 * * *` - 每兩個小時的13分執行一次
- `H(0-29)/10 * * * *` - 每10分鐘在每小時的前半小時執行一次(可能是 :04, :14, :24)
- `30 9-18/2 * * 1-5` - 在每個工作天從9點到18點每兩個小時的30分執行一次
- `H H 1,15 2-12 *` - 除了一月以外的每個月1號和15號一天一次
若有需要額外定義時區,須於第一行標註`TZ=Asia/Taipei`
## 建置後通知
建置完成後,通常我們會需要知道結果如何,是否成功。因此讓Jenkins自動在建置結束後發送通知,是最有效益的做法,通常會有以下幾種方法可以達成:
- 寄送E-mail
- Teams通知
### E-mail
1. 在專案設定(Configure)中,新增建置後動作
2. 選擇E-mail通知(E-mail Notification)
3. 填入E-mail信箱並儲存即完成
:::warning
由於防火牆的問題,因此可能會無法成功收發郵件
:::
### Teams
傳送到Teams的頻道通知需要藉由雙方的外掛程式來達成
#### Teams外掛
1. 在要設置通知的團隊頻道上點選右鍵,並選擇連接器
2. 在左上角篩選欄位輸入++Jenkins++即可找到Jenkins並新增
3. 進入設定後,先填入將來要顯示的名稱,並按下建立
4. 接著複製產生的**Webhook URL**,可參考下方說明設定Jenkins的連接器
#### Jenkins外掛
1. 進入管理外掛頁面,安裝[Office 365 Connector](https://plugins.jenkins.io/Office-365-Connector/)
2. 進入想要傳送通知的專案設定(Configure)頁面
3. 於Office 365 Connector按下**新增Webhook**
4. 於URL欄位貼上剛才複製的Webhook URL,並填入顯示名稱
5. 進入進階(Advanced)並勾選所有項目即可收到所有狀態的通知
6. 按下儲存即完成
## 錯誤清單
曾發生的錯誤
- > Querying for remote changeset at '...' as of '...' ...
  > Query returned no result!
  路徑不合法,可能包含URL encoded字元
- > FATAL: com.microsoft.tfs.core.exceptions.TECoreException: 伺服器無法處理要求。 ---> TF400367: 無法執行要求,因為主機類型不符。請檢查任何連接資訊並驗證資訊是否正確。要求是對 Deployment, Organization 執行。
  > com.microsoft.tfs.core.ws.runtime.exceptions.SOAPFault: 伺服器無法處理要求。 ---> TF400367: 無法執行要求,因為主機類型不符。請檢查任何連接資訊並驗證資訊是否正確。要求是對 Deployment, Organization 執行。
  
  TFS 路徑有誤
- > C:\\Program Files (x86)\\Jenkins\\workspace\\AsyncCoinMiner.csproj : error MSB4236: 找不到指定的 SDK 'Microsoft.NET.Sdk'。
  
  套件尚未被還原,建置參數加入`/t:restore`以還原套件
- > C:\\Program Files (x86)\\Jenkins\\workspace\\GithubTest\\samples\\helloworld\\helloworld.csproj(1,1): error MSB4041: 專案的預設 XML 命名空間必須是 MSBuild XML 命名空間。如果使用 MSBuild 2003 格式設計專案,請將 xmlns="http://schemas.microsoft.com/developer/msbuild/2003" 加入至 <Project> 項目。如果是使用舊版的 1.0 或 1.2 格式設計專案,請將專案轉換為 MSBuild 2003 的格式。
  MSBuild版本太舊,無法處理新版 .net core框架,下載最新版本MSBuild以解決問題
  
[^1]: 撰文時間 2020/2/11
[^2]: 須注意不能為中文,或使用URL編碼
[^3]: 由於路徑名稱中有空格,若不加括號可能會造成建置時的指令錯誤
*[CI]: Continuous Integration
*[CD]: Continuous Deployment
*[TFS]: Team Foundation Service (Azure DevOps Server)
*[TFVC]: Team Foundation Version Control
*[SCM]: Software Configuration Management