一、繼續整合相關概念

1.1、什麼是持續整合?

隨著軟體開發複雜度的不斷提高,團隊開發成員間如何更好的協同工作以確保軟體開發的質量已經成為開發過程中不可迴避的問題。尤其是近年來敏捷開發在軟體領域越來越火,如何能在不間斷變化的需求中快速適應和保證軟體的質量顯得尤其重要。持續整合正是針對這一問題的一種軟體開發實踐。它倡導團隊開發成員必須經常整合他們的工作,甚至每天都可能發生多次整合。而每次整合都是通過自動化的構建來驗證,包括自動編譯、釋出和測試,從而儘快地發現整合錯誤,讓團隊能更快的開發內聚的軟體。

1.2、持續整合的原則

  • 需要版本控制工具來保障團隊成員提交的程式碼不會導致整合失敗。常用的版本控制工具有cvs、subversion、git、sourcesafe等;
  • 開發人員需要及時向版本控制庫中提交程式碼,也需要經常性地從版本控制庫中更新程式碼到本地;
  • 需要有專門的整合伺服器來執行整合構建。根據專案的實際情況,整合構建可以通過程式碼倉庫中程式碼的變動(如push事件、merge事件等)來自動觸發構建,也可以定時啟動構建,如每半小時構建一次;
  • 必須保證構建的成功。如果構建失敗,則修復構建過程中的錯誤將是優先順序最高的工作。一旦修復,需手動啟動一次構建。
  • 一個自動構建過程,包括自動編譯、分發、部署和測試等;
  • 一個程式碼倉庫,即需要版本控制工具來保障程式碼的可維護性,同時作為構建過程的素材庫;
  • 一個持續整合伺服器。即將介紹的Jenkins就是一個配置簡單和使用方便的持續整合伺服器。

1.3、持續整合系統的組成

二、Jenkins簡介和外掛

2.1、Jenkins簡介

Jenkins是一個開源專案,提供了一種易於使用的持續整合系統,使開發者從繁雜的整合中解脫出來,專注於更重要的業務邏輯實現上。同時Jenkins能實時監控整合中存在的錯誤,提供詳細的日誌檔案和提醒功能,還能用圖表的形式形象的展示專案構建的趨勢和穩定性。

2.2、外掛介紹

Jenkins提供了大量的外掛,這些外掛使Jenkins能實現很多複雜的功能。下面列出了部分持續整合所需的外掛:

  • Email Extension Plugin,郵件通知外掛。例如,構建失敗或成功後可以傳送相關資訊到指定的郵箱;
  • Publish Over SSH ,用於遠端伺服器釋出,將編譯生成的jar、war等檔案推送到遠端伺服器中指定的目錄;
  • Maven Integration plugin ,Maven整合外掛,缺少此外掛則新建任務時沒有Maven Project選項;
  • GitLab,用於從指定的程式碼倉庫中拉取需要構建的程式碼;
  • Sonar scanner,用於構建前或構建後對程式碼進行掃描;
  • Git parameter,基於Git的引數化構建;
  • HTML Publisher plugin,用於在Jenkins中配置HTML格式的報告;
  • Groovy Label Assignment plugin,用於執行Groovy程式碼;
  • NodeJS plugin,配置JavaScript的執行環境,作為前端程式碼的打包工具或構建工具;

2.3、外掛安裝

安裝外掛的步驟:在面板介面左側的導航欄中選擇Manager Jenkins ---> System Configuration ---> Manager Plugins,在外掛管理頁面中點選“可選外掛”選項卡,然後在輸入框中填寫需要安裝的外掛名字。

三、全域性工具配置

全域性工具配置主要對一些常用工具的名稱、版本、路徑和配置檔案進行設定。在面板左側的導航欄中點選“系統管理”,進入到“管理Jenkins”介面,選擇介面中的System Configuration ---> Global Tool Configuration後進入到“全域性工具配置”介面,依次對Maven配置、JDK、Git、Maven、NodeJS、Sonar Scanner等進行配置。

3.1、Maven配置

主要用於Maven的主配置檔案settings.xml的設定。settings.xml包含倉庫映象、本地映象和認證資訊等。一般預設的路徑有兩種:Global Maven Settings --- ${M2_HOME}/conf/settings.xml;User Maven Settings --- ${user.HOME}/.m2/settings.xml。如果兩個檔案都存在,會對內容進行合併,優先應用當前目錄下settings.xml中的設定。

3.2、JDK

如果已經安裝過JDK,這裡需要配置JDK的JAVA_HOME。

3.3、Git

Git的配置也很重要,因為大多數的任務都要獲取Git倉庫中的程式碼,所以這裡需要配置Git的執行路徑。

3.4、Maven

主要用於配置Maven的主目錄,可以新增多個,用Name來區分。如果系統中已經安裝Maven,這裡直接填寫MAVEN_HOME對應的路徑,Jenkins會在Master節點上進行檢查,檢視該目錄是否有效。

3.5、SonarQube Scanner

SonarQube Scanner用於程式碼的靜態質量掃描,可以自動安裝,也可以手動將其安裝在Master伺服器上。這裡採用的是自動安裝,在“版本”下拉選框中選擇所要安裝的版本號即可。

3.6、NodeJS

NodeJS是一個JavaScript的執行環境,作為打包工具或者構建工具。如果要在Jenkins中實現編譯、打包前端程式碼,則需要安裝此軟體。

四、系統配置

在Jenkins主面板左側的導航欄中選擇“系統管理”,進入到“管理Jenkins”介面,點選此介面中“系統配置”模組下的“系統配置”選項,進入到“配置”介面。

4.1、Jenkins Location

此項是可選的,指定安裝Jenkins的HTTP地址。這個值用來在郵件中生產Jenkins連結。此項是有必要的,因為Jenkins無法探測到自己的URL地址。

4.2、SonarQube servers

配置SonarQube所在伺服器的資訊,建立Jenkins和SonarQube之間的通訊。

Name自定義一個適合的名字;

Server URLSonarQube所在伺服器的URL(IP或域名加埠,埠號預設為9000);

Server authentication token這裡填寫SonarQube伺服器當前使用者的令牌。

SonarQube令牌的生成方法:登陸SonarQube伺服器,選擇“頭像”--->“我的賬號”--->“安全”--->在“生成令牌”文字框中輸入自定義的名稱,然後點選“生成”按鈕。生成的令牌ID只會顯示一次,所以如果有需要,可以進行備份

生成SonarQube當前使用者的令牌ID後,回到Jenkins的系統配置介面,並定位到“SonarQube servers”模組,點選“Server authentication token”選項的“新增”按鈕,選擇“Jenkins”,進入到“新增憑據”視窗。

型別:選擇Secret text;

Secret填入SonarQube當前使用者生成的令牌ID;

ID自定義一個名稱。

填寫完畢後,點選“新增”按鈕,然後在“Server authentication token”的下拉選框中選擇相應的憑據即可。

4.3、GitLab

配置將要構建的程式碼所在的GitLab伺服器資訊,建立Jenkins和GitLab伺服器之間的通訊。

Connection name自定義一個名稱;

Gitlab host URLGItLab所在伺服器的HTTP地址;

Credentials新增GitLab API token,該token由GItLab生成。

GitLab API token的生成方法:進入GitLab主頁,點選頁面右上角的頭像,在出現的懸框中點選“Settings”,進入到設定介面。在設定介面左側的導航欄中點選“Access Token”,進入“Access Token”介面。

Name自定義一個名稱;

Expires at新增生成token的時間(非必填項);

Scopes勾選api複選框;

Create personal access token點選此按鈕後會生成一個token,且生成的token會展示在“Active Personal Access Tokens”列表中。

生成GitLab API token後,回到Jenkins的系統配置介面,並定位到GitLab模組。點選Credentials的“新增”按鈕,選擇“jenkins”,進入到“新增憑據”視窗。

型別:選擇GitLab API token;

API token填入在GitLab中生成的API token;

ID自定義一個名稱(非必填項)。

所需的資訊配置完畢後,點選“Test Connection”按鈕,測試Jenkins和GitLab之間的連線是否成功。

4.4、Publish over SSH

若要將構建後生成的jar包(後端)或dist目錄檔案(前端)推送到遠端伺服器中,需配置此模組。在此我們選擇使用者名稱和密碼來連線遠端伺服器。

Name自定義一個名稱。在Job中使用Publish over SSH外掛時,此名稱將出現在“SSH Server”中“Name”選項的下拉列表中;

Hostname伺服器的主機名或IP地址;

Username伺服器的使用者名稱;

Remote Directory遠端伺服器上真實存在的目錄,而且“Username”指定的使用者要有訪問此資料夾的許可權,外掛將把檔案推送到此目錄下;

Use password authentication, or use a different key勾選此選項,並在“Passphrase / Password”中輸入與Username匹配的密碼。

配置完後點擊“Test Configuration”,測試是否可以連線成功。

4.5、Extended E-mail Notification

在Jenkins的使用中郵件提醒是一個常用功能,Jenkins預設安裝了 Mailer Plugin外掛用於實現此功能,但 Mailer Plugin功能簡單不能滿足一些複雜需求,如:自定義郵件標題、內容等。Extended E-mail Notification(ext mail)是一個功能更為齊全,使用也更為複雜的外掛。下面對此外掛的配置做簡要的說明。

SMTP ServerSMTP伺服器的地址;

SMPT PortSMTP的埠號,預設為25;

SMTP Username即在Jenkins Location模組中填寫的“系統管理員郵件地址”;

SMTP Password“系統管理員郵件地址”所對應的密碼;

Default user E-mail suffix預設的郵箱字尾;

Default Content Type預設的郵件內容格式;

Default Recipients預設收件人的郵箱地址(可填寫多個,中間用英文逗號隔開即可);

Default Subject郵件標題。例如,$PROJECT_NAME - Build # $BUILD_NUMBER - $BUILD_STATUS!。其中,$PROJECT_NAME為構建專案名稱,$BUILD_NUMBER為構建編號,$BUILD_STATUS為構建狀態;

Default Content:郵件內容;

 1 <!DOCTYPE html>
2 <html>
3 <head>
4 <meta charset="UTF-8">
5 <title>${ENV, var="JOB_NAME"}-第${BUILD_NUMBER}次構建日誌</title>
6 </head>
7
8 <body leftmargin="8" marginwidth="0" topmargin="8" marginheight="4"
9 offset="0">
10 <table width="95%" cellpadding="0" cellspacing="0"
11 style="font-size: 11pt; font-family: Tahoma, Arial, Helvetica, sans-serif">
12 <tr>
13 <td>(本郵件由Jenkins系統自動釋出,請勿回覆!)</td>
14 </tr>
15 <tr>
16 <td><h2>
17 <font color="#0000FF">構建結果 - ${BUILD_STATUS}</font>
18 </h2></td>
19 </tr>
20 <tr>
21 <td><br />
22 <b><font color="#0B610B">構建資訊</font></b>
23 <hr size="2" width="100%" align="center" /></td>
24 </tr>
25 <tr>
26 <td>
27 <ul>
28 <li>專案名稱: ${PROJECT_NAME}</li>
29 <li>構建編號: 第${BUILD_NUMBER}次構建</li>
30 <li>構建狀態: ${BUILD_STATUS}</li>
31 <li>觸發原因: ${CAUSE}</li>
32 <li>構建日誌: <a href="${BUILD_URL}console">${BUILD_URL}console</a></li>
33 <li>構建 Url : <a href="${BUILD_URL}">${BUILD_URL}</a></li>
34 <li>工作目錄 : <a href="${PROJECT_URL}ws">${PROJECT_URL}ws</a></li>
35 <li>專案 Url : <a href="${PROJECT_URL}">${PROJECT_URL}</a></li>
36 </ul>
37 </td>
38 </tr>
39 <tr>
40 <td><b><font color="#0B610B">Changes Since Last
41 Successful Build:</font></b>
42 <hr size="2" width="100%" align="center" /></td>
43 </tr>
44 <tr>
45 <td>
46 <ul>
47 <li>歷史變更記錄 : <a href="${PROJECT_URL}changes">${PROJECT_URL}changes</a></li>
48 </ul> ${CHANGES_SINCE_LAST_SUCCESS,reverse=true, format="Changes for Build #%n:<br />%c<br />",showPaths=true,changesFormat="<pre>[%a]<br />%m</pre>",pathFormat=" %p"}
49 </td>
50 </tr>
51 <tr>
52 <td><b>Failed Test Results</b>
53 <hr size="2" width="100%" align="center" /></td>
54 </tr>
55 <tr>
56 <td><pre style="font-size: 11pt; font-family: Tahoma, Arial, Helvetica, sans-serif">$FAILED_TESTS</pre>
57 <br /></td>
58 </tr>
59 <tr>
60 <td><b><font color="#0B610B">構建日誌 (最後 100行):</font></b>
61 <hr size="2" width="100%" align="center" /></td>
62 </tr>
63 <!-- <tr>
64 <td>Test Logs (if test has ran): <a
65 href="${PROJECT_URL}ws/TestResult/archive_logs/Log-Build-${BUILD_NUMBER}.zip">${PROJECT_URL}/ws/TestResult/archive_logs/Log-Build-${BUILD_NUMBER}.zip</a>
66 <br />
67 <br />
68 </td>
69 </tr> -->
70 <tr>
71 <td><textarea cols="80" rows="30" readonly="readonly"
72 style="font-family:Courier New">${BUILD_LOG, maxLines=100}

五、建立Maven專案

5.1、新建任務

首先進入Jenkins主介面,在面板左側的導航欄中點選“新建任務”,進入“新建任務”介面。

進入“新建任務”介面後,在“任務名稱”文字框中輸入一個合法的名稱(該名稱最好能簡短、清晰地描述所要構建的專案,且不能與已有的任務名稱重合),然後選擇“構建一個Maven專案”,點選左下角的“確定”按鈕,進入任務配置介面。

5.2、General

在“General”選項卡下勾選“丟棄舊的構建”,填寫需要保留的構建天數和構建的最大個數。若不及時清理舊的構建,則會消耗伺服器的磁碟空間。

5.3、原始碼管理

在“原始碼管理”模組中選擇Git。無論是GitHub還是私有的GitLab,一般都支援兩種模式:SSH模式和HTTP模式。

5.3.1 HTTP模式

Repository URL要構建的專案在GitLab中的HTTP地址。首先進入到所要構建的專案在GitLab中的主介面,在專案的URL下拉選框中選擇“HTTP”,並點選右側的“複製”按鈕,將複製的HTTP地址貼上到“Repository URL”文字框中即可。

Credentials點選右側的“新增”按鈕,選擇“Jenkins”選項後會彈出一個“新增憑據”彈窗。

新增憑據時,型別選擇“Username with password”,然後在“使用者名稱”文字框中輸入GitLab的登陸賬戶,“密碼”文字框中輸入與賬戶相匹配的密碼,“ID”文字框中填入自定義的名稱,但不能與已有的憑據ID重合。填寫完畢後,點選“新增”按鈕,所新增的憑據就會出現在“Credentials”的下拉選框中,在選框中選擇相應的憑據即可。

5.3.2 SSH模式

首先登陸Jenkins所在的master伺服器,檢查在~/.ssh目錄下是否有已生成的公鑰和私鑰。其中,公鑰的檔名為id_rsa.pub,私鑰的檔名為id_rsa。若公鑰和私鑰都存在,則將公鑰拷貝到GitLab中,私鑰拷貝到Jenkins中。

1)將公鑰拷貝到GitLab

首先登陸到GitLab中,點選頁面右上角的頭像,選擇Settings-->SSH Keys,進入到“SSH Keys”介面。

Key將Jenkins所在master伺服器上的公鑰(id_rsa.pub)拷貝到此文字框中;

Title填寫一個適合的名稱;

Add key點選此按鈕將公鑰新增到GitLab中;

Your SSH keys新增到GitLab的公鑰會顯示在此列表中。

2)新增Jenkins全域性憑據

首先登陸到Jenkins中,選擇系統管理-->Manager Credentials-->全域性憑據-->新增憑據,進入到“新增憑據”介面。

型別:選擇“SSH Username with private key”;

ID填寫一個獨一無二的名稱;

描述:簡短、清晰的描述此憑據的作用;

Username填寫Master伺服器的使用者名稱,如root;

Private Key將Master伺服器上的私鑰(id_rsa)拷貝到此文字框中。

設定好全域性憑據後,將GitLab中專案的SSH地址複製到Jenkins中相應job配置頁面的“原始碼管理”模組中。在“Credentials”中選擇相應的全域性憑據。

Branches to build要構建的程式碼在Git倉庫中的分支名。由於我們要將dev分支(開發分支程式碼,具體名稱視Gitlab中的情況而定)的程式碼merge到test分支(測試分支程式碼,具體名稱視Gitlab中的情況而定)上,所以此處填寫dev。若不需要在構建前執行merge操作,則此處填寫實際要構建的程式碼分支名稱即可。

5.3.3 Additional Behaviours

1Merge before build

由於我們要在構建前將dev分支的程式碼merge到test分支上,因此要在“Additional Behaviours”中新增一個“Merge before build”模組。若不需要在構建前執行merge操作,則可省略此步驟。

Name of repository遠端程式碼倉庫的名稱,即所要構建的程式碼分支所在的倉庫,預設填寫origin即可;

Branch to merge to程式碼將要merge到的分支。由於我們要將dev分支的程式碼merge到test分支,因此該處填寫test;

Merge strategy預設選擇default即可;

Fast-forward mode預設選擇--ff即可。

2)Custom user name/e-mail address

當在任務中配置了“Merge before build”或向遠端Git倉庫中push版本標籤時,會出現無法識別使用者的情況,如下圖所示:

要解決這個問題,需要在“Additional Behaviours”的“新增”下拉選框中選擇“Custom user name/e-mail address”選項,新增Gitlab使用者名稱和對應的電子郵箱。

檢視Gitlab使用者名稱和電子郵箱的方法:進入到Gitlab主頁,點選右上角的頭像,在出現的下拉選框中選擇“Settings”進入到設定介面。在設定介面中即可看到使用者名稱和對應的郵箱。然後將使用者名稱和郵箱貼上到“Custom user name/e-mail address”中相應的文字框中即可。

5.4、構建觸發器

若不需要自動觸發專案進行構建,可忽略此步驟。

5.4.1 Git事件觸發構建

定位到 “構建觸發器”模組,勾選“Build when a change is pushed to GitLab.”,並記下這一選項末尾的“GitLab webhook URL”。

此外,還要點選該選項中的“高階”按鈕,隨後點選“Secret token”項的 “Generate” ,生成 Secret token。儲存這裡生成的 Secret token,它將用於後面 GitLab 的配置。

下面對各項進行簡要介紹:

1Enabled GitLab triggers

Push Events當有程式碼Push到Git倉庫時,自動觸發Jenkins構建;

Opened Merge Request Events當在Git中新建一個Merge請求時,自動觸發Jenkins構建;

Accepted Merge Request Events當在GitLab中建立的Merge請求被接受後,自動觸發Jenkins構建。例如,在GItLab中,當dev01分支的程式碼請求merge到dev分支時,若此請求被成功處理,就會觸發Jenkins自動構建,Jenkins會將dev分支的程式碼merge到test分支;

Closed Merge Request Events當在GitLab中建立的Merge請求被關閉時,自動觸發Jenkins構建。

2保持預設選項

3Allowed branches

此項用於篩選可以觸發任務自動構建的程式碼分支。勾選“Filter branches by name”,在“inclued”文字框中填寫允許自動觸發任務構建的程式碼分支名稱,名稱之間用英文逗號分隔。

配置GitLab此處以merge觸發為例,即當Git倉庫中發生Merge事件時,觸發Jenkins自動構建。開啟GItLab,進入到相應的專案頁面中,在頁面左側的導航欄中選擇Settings--->Integrations,進入到“Integrations Settings”介面。在該介面中,在“URL”文字框中輸入“GitLab webhook URL”尾部的HTTP地址;在“Secret Token”中輸入在Jenkins中生成的Secret token;在“Trigger”中勾選“Merge Request events”,然後點選“Add Webhook”按鈕。

點選“Add webhook”按鈕後,新增的webhook會出現在“webhooks”列表中。在列表中選擇新新增的webhook,在其右邊的“Test”下拉列表中選擇相應的Trigger(即Merge requests events),點選後在頁面上方如果出現“Hook executed successfully:HTTP 200”的提示,則表明配置成功。

GitLab中建立Merge請求。首先,登陸GitLab伺服器,選擇相應的專案並進入到該專案頁面,在頁面左側的導航欄中選擇“Merge Requests”,進入到“Merge Requests”介面。在該介面的右上角點選“New Merge Request”,新建一個Merge請求。

在Merge請求頁面中,選擇相應的源專案、目標專案,以及源分支和目標分支。

點選“Compare branches and continue”,會進入到下一個頁面,在此頁面中可以填寫更為詳細的merge requests資訊。

點選“Submit合併請求”按鈕,進入下一個頁面,在該頁面中可以編輯或關閉此次merge請求。

當所指定的源分支中的程式碼發生更改後(即執行了git commit命令),在此頁面中會出現一個“Merge”按鈕。點選此按鈕後,源分支上的程式碼就會被merge到目標分支上。同時,會觸發Jenkins自動執行構建任務,將dev分支上的程式碼merge到test分支上。

5.4.2 定時構建

定時構建的選項包括“輪詢SCM”和“定時構建”。定時構建適用於每日構建或每週構建的任務,可以通過設定具體的時間點和時間段來執行指定的任務。構建任務的內容填寫在“日程表”文字框中,而且填寫完畢後下方還會提示上次執行和下次執行的時間點,用於驗證配置是否正確。

定時構建的語法是* * * * *

  • 第一個*表示分鐘,取值範圍是0~59。例如,5 * * * *表示每個小時的第5分鐘會構建一次;H/15 * * * *或*/15 * * * *表示每隔15分鐘構建一次;
  • 第2個*表示小時,取值範圍是0~23。例如,H 8 * * *表示每天8點構建一次;H 8-18/2 * * *表示每天8到18點每隔2個小時構建一次;H 8,12,22 * * *表示每天8點、12點、22點分別構建一次;
  • 第3個*表示每月的第幾天,取值範圍是1~31。H 8 4 * * 表示在每個月第4天的第8點構建一次;
  • 第4個*表示第幾個月,取值範圍是1~12。H 8 4 3 *表示在每年3月的第4天的8點構建一次;
  • 第5個*表示一週中的第幾天,取值範圍是0~7,其中0和7表示的都是週日。例如,H 8-18/2 * * 1-5表示週一到週五每天8點~18點每隔兩小時構建一次。

5.4.3 其它工程構建後觸發

當所要構建的兩個或多個專案之間存在關聯時,可以勾選此選項。在“關注的專案”文字框中可以填寫多個已存在的專案,專案之間用英文的逗號分隔。例如,任務B要在任務A構建成功後自動構建,可在“關注的專案”文字框中填寫A,同時選擇“只有構建穩定時觸發”,即只有專案A成功構建才會自動觸發B構建。

5.5、構建環境

5.5.1 構建前清理工作空間

若要在構建前清理工作空間,以免工作空間中的內容對本次構建產生影響和及時清理磁碟空間,可勾選“Delete workspace before build starts”選項。

5.5.2 生成格式化的版本號

Jenkins預設的構建版本號只是簡單的構建總次數,不包含有年月日及當日構建次數等資訊,可勾選“Create a formatted version number”選項自定義所需要的構建版本號。

Environment Variable Name填寫一個合適的名稱,此名稱可作為全域性環境變數被引用;

Version Number Format String填寫自定義的格式化構建版本號,如${JOB_NAME}_${BUILD_DATE_FORMATTED, "yyyyMMdd"}_${BUILDS_TODAY},其中,${JOB_NAME}為專案名稱,${BUILD_DATE_FORMATTED, "yyyyMMdd"}為格式化後的日期,${BUILDS_TODAY}為今日構建次數;

Skip Builds worse than當本次構建任務的狀態比此處所選的還要糟糕時,則本次構建不計入構建總次數。例如,此處選擇“SUCCESS”,但本次任務的構建狀態為“FAILURE”,則本次構建不計入今日(或周、月、年)構建總次數;

Build Display Name當勾選“Use the formatted version number for build display name”時,自定義的構建版本號會替代原來的“#XXX”顯示在工作列中,如下圖所示。

其他選項保持預設即可。

5.6、Pre Build

若構建前要利用Sonar Scanner對程式碼執行靜態質量掃描操作,則需要在“Add pre-build step”下拉選框中選擇“Execute SonarQube Scanner”選項。

下面對 “Execute SonarQube Scanner”各項做簡要的介紹:

Task to run自定義一個名稱(非必填項);

JDK在 JDK 選擇框中選擇 SonarQube Scanner 使用的 JDK(注意這裡必須是 JDK 不能是 JRE);

Path to project properties非必填項。這裡可以指定一個 sonar-project.properties 檔案,如果不指定的話會使用專案預設的 properties 檔案;

Analysis properties這裡需要輸入一些配置引數用來傳遞給 SonarQube,這裡的引數優先順序高於sonar-project.properties檔案裡面的引數,所以可以在這裡來配置所有的引數以替代 sonar-project.properties 檔案。下面介紹一些常用的引數:

  • sonar.login=admin:sonarqube使用者名稱,預設為admin;
  • sonar.password=admin:與sonarqube使用者名稱相匹配的密碼,預設為admin;
  • sonar.projectKey=opanalysis:在sonarqube介面中建立專案時填寫的“專案標識”;
  • sonar.projectName=opanalysis:在sonarqube介面中建立專案時填寫的“顯示名”;
  • sonar.language=java:指定要分析的開發語言(特定的開發語言對應了特定的規則);
  • sonar.projectVersion=$BUILD_VERSION:專案版本,可使用Jenkins環境變數;
  • sonar.sourceEncoding=UTF-8:原始碼的編碼格式;
  • sonar.sources=$WORKSPACE:指定需要分析的原始碼位置。這裡的$WORKSPACE 所指示的是當前Jenkins專案的目錄,即相對於jenkins的workspace路徑;
  • sonar.java.binaries=$WORKSPACE:指定需要分析的程式碼編譯後生成的class檔案的位置,相對於jenkins的workspace路徑。

Additional arguments非必填項。此輸入框中可以輸入一些附加的引數,示例中的-X意思是進入SonarQube Scanner的Debug模式,這樣會輸出更多的日誌資訊;

JVM Options非必填項。可以輸入在執行 SonarQube Scanner 時需要的JVM引數。

projectKeyprojectName的生成方法:生成sonar.projectKey和sonar.projectName時需要登陸SonarQube介面。在SonarQube介面中新建一個專案時,會要求輸入“專案標識”和“顯示名”,“專案標識”即“sonar.projectKey”,“顯示名”即“sonar.projectName”。

SonarQube介面中新建專案的步驟:

5.7、Build

Root POM最上層pom.xml檔案的路徑,這裡是相對於${WORKSPACE}的路徑。如果不做設定,預設是在工作目錄的根目錄下,填寫pom.xml即可。如果不是預設路徑,例如,在${WORKSPACE}/my-project/pom.xml下,這裡寫上/my-project/pom.xml。

Goals and options這裡就是mvn指令後面的部分,如clean package,也可以帶引數。比如,要跳過單元測試,就使用-Dmaven.test.skip=true。

5.8、構建後操作

在“構建後操作步驟”中新增“Git Publisher”和“Send build artifacts over SSH”。其中,“Git Publisher”的作用是將在Jenkins中merge後的程式碼push到遠端倉庫中相應的分支。“Send build artifacts over SSH”的作用是將編譯打包後的檔案(如war包、jar包)推送到遠端伺服器。

5.8.1 Git Publisher

Branch to push程式碼merge成功後要push到的分支的名稱。在我們的示例中,Jenkins在執行構建任務時,將dev分支上的程式碼merge到了test分支上。merge成功後,還需要將合併後的程式碼push到遠端倉庫中指定的分支上。此處我們將合併後的程式碼push到了test分支上;

Target remote name遠端程式碼倉庫的名稱,即上面所填寫的程式碼分支所在的Git倉庫。

Tags在將merge後的程式碼push到遠端倉庫中指定的分支時,還可以為此次提交的程式碼打上一個tag,此tag也會同時被push到遠端倉庫中。點選“Add Tags”按鈕,填寫相應的配置資訊。

5.8.2 Send build artifacts over SSH

在這個模組中配置相應的資訊,將構建後編譯生成的jar包推送到遠端伺服器上指定的目錄。也可編寫shell指令碼,對應用進行部署。

Name選擇在Jenkins“系統管理--->系統設定”中設定的SSH Server的名字;

Source files拷貝到遠端伺服器上的檔案。需要上傳的檔案必須位於當前的workspace中,否則會上傳失敗。如果只執行命令而不需要傳輸檔案時,此處可為空;

Remove prefix在“Source files”配置的路徑中要移除的字首。在Source files文字框中填入的地址,會預設在伺服器下建立相同的目錄,所以要將我們不需要的字首在這裡剔除掉,只傳輸XXX.jar;

Remote directory遠端伺服器接收檔案的目錄,此目錄是相對於“SSH Server”中的“Remote directory”的,如果不存在將會自動建立;

Exec command檔案傳輸任務執行完畢後,在遠端伺服器上執行的指令碼(可填寫指令碼所在目錄)。

Exec command中的指令碼:

 1 #! /bin/bash
2 #!/bin/bash
3 export PROJECT_HOME="/opt/opanalysis"
4 export JAR_HOME="$PROJECT_HOME/new-jar"
5 export BACKUP_HOME="$PROJECT_HOME/backup-jar"
6 export ANALYSIS=op-analysis.jar
7 export TEAMBITION=op-teambition.jar
8 export CAS=op-cas.jar
9 export GATEWAY=op-gateway.jar
10 export LOG_HOME="/opt/opanalysis/logs"
11 export ANALYSIS_log="$LOG_HOME/op-analysis.log"
12 export TEAMBITION_log="$LOG_HOME/op-teambition.log"
13 export CAS_log="$LOG_HOME/op-cas.log"
14 export GATEWAY_log="$LOG_HOME/op-gateway.log"
15 BACKUP_FILE=v${BUILD_VERSION}_$(date +%Y-%m-%d_%H:%M:%S)
16 echo "****** Backup old jar ******"
17 mkdir $BACKUP_HOME/$BACKUP_FILE
18 cp $JAR_HOME/*.jar $BACKUP_HOME/$BACKUP_FILE
19 echo "****** Remove old jar ******"
20 find $JAR_HOME -type f -name "*.jar" -print0 | xargs -0 rm -rf
21 echo "****** Copy new jar ******"
22 cp $PROJECT_HOME/op-analysis/target/$ANALYSIS $JAR_HOME
23 cp $PROJECT_HOME/op-teambition/target/$TEAMBITION $JAR_HOME
24 cp $PROJECT_HOME/op-cas/target/$CAS $JAR_HOME
25 cp $PROJECT_HOME/op-gateway/target/$GATEWAY $JAR_HOME
26 if [ -e $JAR_HOME/$ANALYSIS -a -e $JAR_HOME/$TEAMBITION -a -e $JAR_HOME/$CAS -a -e $JAR_HOME/$GATEWAY ]; then
27 echo "The new jars were successfully replicated"
28 else
29 echo "The new jars replication failed"
30 exit 1
31 fi
32 echo "****** Stop the old processes ******"
33 P_ID=$(ps -ef | grep -w $ANALYSIS | grep -v "grep" | awk '{print $2}')
34 if [ "$P_ID" == "" ]; then
35 echo "$ANALYSIS process does not exist or has stopped successfully"
36 else
37 kill -9 $P_ID
38 echo "$ANALYSIS was successfully killed"
39 fi
40 P_ID=$(ps -ef | grep -w $TEAMBITION | grep -v "grep" | awk '{print $2}')
41 if [ "$P_ID" == "" ]; then
42 echo "$TEAMBITION process does not exist or has stopped successfully"
43 else
44 kill -9 $P_ID
45 echo "$TEAMBITION was successfully killed"
46 fi
47 P_ID=$(ps -ef | grep -w $CAS | grep -v "grep" | awk '{print $2}')
48 if [ "$P_ID" == "" ]; then
49 echo "$CAS process does not exist or has stopped successfully"
50 else
51 kill -9 $P_ID
52 echo "$CAS was successfully killed"
53 fi
54 P_ID=$(ps -ef | grep -w $GATEWAY | grep -v "grep" | awk '{print $2}')
55 if [ "$P_ID" == "" ]; then
56 echo "$GATEWAY process does not exist or has stopped successfully"
57 else
58 kill -9 $P_ID
59 echo "$GATEWAY was successfully killed"
60 fi
61 echo "****** Old processes stop success ******"
62 echo "****** Start op-analysis.jar... ******"
63 nohup java -jar $JAR_HOME/$ANALYSIS > $ANALYSIS_log 2>&1 &
64 EXEXUTE_STATUS_ANALYSIS=$?
65 sleep 10
66 if [ $EXEXUTE_STATUS_ANALYSIS -eq 0 -a $(ps -ef | grep -w $ANALYSIS | grep -v "grep" | wc -l) -ne 0 ]; then
67 echo "$ANALYSIS started successfully"
68 else
69 echo "$ANALYSIS failed to start"
70 fi
71 echo "****** Start op-teambition.jar... ******"
72 nohup java -jar $JAR_HOME/$TEAMBITION > $TEAMBITION_log 2>&1 &
73 EXECUTE_STATUS_TEAMBITION=$?
74 sleep 10
75 if [ $EXECUTE_STATUS_TEAMBITION -eq 0 -a $(ps -ef | grep -w $TEAMBITION | grep -v "grep" | wc -l) -ne 0 ]; then
76 echo "$TEAMBITION started successfully"
77 else
78 echo "$TEAMBITION failed to start"
79 fi
80 echo "****** Start op-cas.jar... ******"
81 nohup java -jar $JAR_HOME/$CAS > $CAS_log 2>&1 &
82 EXECUTE_STATUS_CAS=$?
83 sleep 10
84 if [ $EXECUTE_STATUS_CAS -eq 0 -a $(ps -ef | grep -w $CAS | grep -v "grep" | wc -l) -ne 0 ]; then
85 echo "$CAS started successfully"
86 else
87 echo "$CAS failed to start"
88 fi
89 echo "****** Start op-gateway.jar... ******"
90 nohup java -jar $JAR_HOME/$GATEWAY > $GATEWAY_log 2>&1 &
91 EXECUTE_STATUS_GATEWAY=$?
92 sleep 10
93 if [ $EXECUTE_STATUS_GATEWAY -eq 0 -a $(ps -ef | grep -w $GATEWAY | grep -v "grep" | wc -l) -ne 0 ]; then
94 echo "$GATEWAY started successfully"
95 else
96 echo "$GATEWAY failed to start"
97 fi
98 echo "****** Over ******"

5.8.3 Editable Email Notification

在“增加構建後操作步驟”下拉選框中選擇“Editable Email Notification”,選擇後會在“構建後操作”中出現“Editable Email Notification”模組。

六、分散式構建

6.1、Jenkins執行模式--Master/Slave

Jenkins支援Master/Slave這種分散式執行模式。將安裝Jenkins的機器作為Master節點,然後使用者通過介面配置來新增Slave節點。在使用者配置具體任務的時候可以選擇Master機器本身或者某個Slave節點來執行。Jenkins在實際執行任務的時候,將作業分佈到指定的Master或Slave節點上,使得單個節點安裝的Jenkins伺服器能夠管理多個節點,執行大批量的任務,以及為它們提供不同的系統環境和配置。

6.2、通過介面新增Slave節點

建立和配置Jenkins Slave節點。選擇 系統管理-->節點管理--->新建節點 選項,可以建立全新的Slave節點,也可以從已有的Jenkins節點複製。

6.2.1 配置節點的一些基本資訊

名稱:節點獨一無二的名稱,自行命名;

描述:節點的描述;

執行器數量:在該節點可以並行執行的最大任務數量,建議和CPU的核心數相等,這裡設定的值太高會導致節點負荷過大,在執行多個任務時,任務執行耗時過長;

遠端工作目錄:指定Slave節點的workspace目錄,但是一些重要的資料會儲存在Master節點上,一些原始碼和檔案會直接放置在執行的Slave節點上,因此這裡需要指定一個目錄;

標籤:用來表示節點的群組。例如,如果節點都是Windows系統的節點,可以提供“Windows Node”作為標籤,在配置任務時可以不用指定具體的節點,而指定對應的群組;

用法:節點有兩種使用模式。預設是Use this node as much as possible。在這種模式下,如果任務沒有指定具體的執行節點,那麼會隨機指派一個可用節點。當節點配置為這種模式時,在需要的時候可以被Jenkins隨機呼叫。還有一種模式是Only build jobs with label expressions matching this node。在這種模式下,只有當任務指定使用該節點時,才會使用該節點,可以用於資源受嚴格控制的場景及專門用於某些任務。

6.2.2 Master節點和Slave節點的連線方式

這裡主要介紹Launch slave agents via SSH連線方式(配置節點前必須安裝SSH Agent Plugin外掛,否則不能出現Launch slave agents via SSH選項)。

啟動方式:選擇Launch slave agents via SSH;

主機:填寫Slave機器的IP地址;

Credentials新增憑證資訊

型別:選擇SSH Username with private key;

ID:填寫一個獨一無二的ID名;

描述:填寫能清楚描述此憑證的資訊;

Username:填寫Master節點所在伺服器的使用者名稱;

Private Key:填寫Master節點所在伺服器的私鑰。

在配置Slave節點資訊之前,需要將Master節點伺服器上的公鑰推送到Slave節點伺服器上:

 1 # 生成公鑰和私鑰
2 ssh-keygen -t rsa
3 # 進入到公鑰和私鑰所在的目錄
4 cd ~/.ssh
5 # 檢視生成的公鑰
6 cat id_rsa.pub
7 # 檢視生成的私鑰
8 cat id_rsa
9 # 將公鑰推送到Slave節點伺服器上
10 ssh-copy-id -i ~/.ssh/id_rsa.pub [email protected]

若沒有登陸Master節點伺服器的許可權,可以在Slave節點所在伺服器的~/.ssh目錄下新建一個authorized_keys的檔案,並將Master節點伺服器的公鑰貼上在此檔案中。

6.3、配置節點的工具執行路徑

在系統的全域性配置中,我們會設定一些工具的執行路徑。如果在Slave節點上工具的執行路徑與全域性配置不同,就需要重新選擇工具名稱,給予新的路徑,覆蓋全域性配置中的預設路徑。建議在系統的全域性工具配置中已有的工具都要在Slave節點所在的伺服器上安裝,否則構建任務的時候會出錯。

6.4、在Slave節點上執行任務

選擇一個要在Slave節點上執行的任務,進入到其設定介面,定位到介面中的General模組,勾選“限制專案的執行節點”,在出現的文字框中輸入Slave節點的名稱,應用並儲存該配置,當構建該任務時,會自動在該Slave節點上執行。

6.5、構建過程中可能出現的問題

(1)無法從遠端Git倉庫中拉取程式碼

需要將GitLab所在伺服器的IP地址和對應的域名新增到Slave伺服器的hosts檔案中:

# 編輯hosts檔案
vim /etc/hosts

(2)無法將Sonar Scanner的程式碼掃描結果傳送到Sonar Qube上進行展示

需要將Sonar Qube的使用者名稱和對應的登陸密碼新增到Analysis properties中:

(3)無法找到Maven的配置檔案

在slave伺服器中,maven的配置檔案(settings.xml)的路徑需要和master伺服器上的路徑一致,否則構建時會出錯。

七、前端專案構建和部署

在對前端專案進行構建之前,需要在Jenkins的Master伺服器上安裝NodeJs、在Jenkins上安裝NodeJS外掛。此外還要在測試伺服器上安裝Nginx。

進入到測試伺服器,在nginx的安裝目錄下找到nginx.conf檔案,並使用vim命令對該檔案進行編輯。

7.1、新建任務

首先進入Jenkins主介面,在面板左側的導航欄中點選“新建任務”,進入“新建任務”介面。

進入“新建任務”介面後,在“任務名稱”文字框中輸入一個合法的名稱(該名稱最好能簡短、清晰地描述所要構建的專案,且不能與已有的任務名稱重合),然後選擇“構建一個自由風格的軟體專案”,點選左下角的“確定”按鈕,進入任務配置介面。

7.2、General

請參考5.2節

7.3、原始碼管理

請參考5.3節

7.4、構建觸發器

請參考5.4節

7.5、構建環境

前端程式碼在構建時需要NodeJS進行編譯、打包,所以要在“構建環境”中配置NodeJS環境。安裝NodeJS外掛後,會在“構建環境”模組中出現“Provide Node & npm bin/ folder to PATH“選項,勾選此選項。

NodeJS Installation在“全域性工具配置”介面中指定NodeJS安裝路徑時所填寫的名稱會出現在此下拉列表中,在列表中選擇所需的名稱即可;

npmrc file選擇“- use system default –”;

Cache location選擇“Default (~/.npm or %APP_DATA%\npm-cache)”。

“構建環境”模組中的其他選項配置請參考5.5節。

7.6、構建

7.6.1 執行shell

在“構建”模組的“增加構建步驟”下拉選框中選擇“執行shell”選項,然後在“執行shell”的“命令”文字框中輸入編譯、打包前端程式碼的命令。

命令如下:

 1 #!/bin/bash
2 export WORKSPACE_HOME="/var/lib/jenkins/workspace/operation-analysis-front"
3 # 進入專案的工作空間
4 cd $WORKSPACE_HOME
5 # 執行npm install後,npm會根據在package.json中對各種依賴的定義去安裝這些依賴
6 npm install
7 # 打包專案程式碼。打包完成後會生成一個dist目錄,所要部署的檔案就存放在dist目錄下
8 npm run test
9 # 進入到dist目錄
10 cd $WORKSPACE_HOME/dist
11 # 刪除舊的壓縮檔案
12 rm -f dist.tar.gz
13 # 對新的部署檔案進行打包壓縮
14 tar -zcvf dist.tar.gz *

7.6.2 Execute SonarQube Scanner

請參考5.6節。不同的是前端程式碼的掃描物件為JavaScript,因此程式碼語言要設定成js,即sonar.language=js。

7.7、構建後操作

7.7.1 Git Publisher

請參考5.8.1節

7.7.2 Send build artifacts over SSH

在這個模組中配置相應的資訊,將構建後編譯生成的dist目錄下的部署檔案推送到遠端伺服器上指定的目錄。

Name選擇在Jenkins“系統管理--->系統設定”中設定的SSH Server的名字;

Source files拷貝到遠端伺服器上的檔案。需要上傳的檔案必須位於當前的workspace中,否則會上傳失敗。可填寫相對於workspace的路徑名。例如,由於我們將dist目錄下的檔案打包成了一個壓縮包,所以此處填寫dist/dist.tar.gz即可;

Remove prefix在“Source files”配置的路徑中要移除的字首。在Source files文字框中填入的地址,會預設在伺服器中建立相同的目錄,所以要將我們不需要的字首在這裡剔除掉,例如,去掉dist;

Remote directory遠端伺服器接收檔案的目錄,此目錄是相對於“SSH Server”中的“Remote directory”的,如果不存在將會自動建立;

Exec command檔案傳輸任務執行完畢後,在遠端伺服器上執行的指令碼(可填寫指令碼所在目錄)。

Exec command中的指令碼如下:

 1 #!/bin/bash
2 export PROJECT_HOME="/usr/local/operation_analysis/op-web-package"
3 export DIST_HOME="$PROJECT_HOME/dist"
4 export BACKUP_HOME="$PROJECT_HOME/backup-dist"
5 export TARGET_HOME="/opt/opanalysis-front"
6 BACKUP_FILE="v${BUILD_VERSION}_$(date +%Y-%m-%d_%H:%M:%S)"
7 echo "****** Backup old dist ******"
8 mkdir $BACKUP_HOME/$BACKUP_FILE
9 cp -r $DIST_HOME $BACKUP_HOME/$BACKUP_FILE
10 echo "****** Remove old dist ******"
11 rm -rf $DIST_HOME/*
12 echo "****** Copy new dist ******"
13 mv $TARGET_HOME/dist.tar.gz $DIST_HOME
14 tar -zxvf $DIST_HOME/dist.tar.gz -C $DIST_HOME
15 rm -rf $DIST_HOME/dist.tar.gz

八、SonarQube的安裝

1、配置JDK

useradd java
passwd java
cd /home/java
wget https://www.oracle.com/webapps/redirect/signon?nexturl=https://download.oracle.com/otn/java/jdk/8u271-b09/61ae65e088624f5aaa0b1d2d801acb16/jdk-8u271-linux-x64.tar.gz
tar -zxvf jdk-8u271-linux-x64.tar.gz
vim /etc/profile
export JAVA_HOME=/home/java/jdk1.8.0_271
export PATH=$JAVA_HOME/bin:$PATH
source /etc/profile
java -version
ln -s /home/java/jdk1.8.0_271/bin/java /usr/bin/java

2、下載並安裝SonarQube

wget https://binaries.sonarsource.com/Distribution/sonarqube/sonarqube-7.6.zip
cp sonarqube-7.6 /opt
cd /opt/sonarqube/conf
# 修改sonar的配置檔案
vim sonar.properties
sonar.jdbc.username=sonar
sonar.jdbc.password=sonar
sonar.login=admin
sonar.password=admin
sonar.jdbc.url=jdbc:mysql://localhost:3306/sonar?useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&useConfigs=maxPerformance&useSSL=false
# 新增sonar使用者(必須以非root使用者啟動sonarqube)
useradd sonar
passwd sonar
chown -R sonar:sonar /opt/sonarqube/
chmod -R 755 /opt/sonarqube
su sonar
# 啟動sonarqube
cd /opt/sonarqube/bin/linux-x86-64/
./sonar.sh console

安裝過程中可能會出現的問題:

1)Encounteredanerrorrunningmain:java.nio.file.AccessDeniedExcepti

解決辦法:刪除sonarqube/temp、sonarqube/logs目錄下的所有檔案即可;

2)java.sql.SQLException:CannotcreatePoolableConnectionFactory(Accessdenied)

資料庫賬號授權有問題。

解決辦法:刪除sonar的庫表,賬號,重新進行建表與授權。

安裝sonar-scanner:

cd /usr/local

# 下載sonar scanner

wget https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-4.4.0.2170-linux.zip

# 解壓

tar -zxvf sonar-scanner-cli-4.4.0.2170-linux.zip

# 進入到配置檔案目錄下

cd sonar-scanner-4.4.0.2170-linux/conf

# 修改sonar-scanner.properties檔案:

sonar.host.url=http://localhost:9000(localhost修改為sonarqube所在的IP地址)

九、安裝MySQL

[root@localhost /]# rpm -qa | grep mysql
# 若已安裝了MySQL,執行刪除命令
[root@localhost /]# rpm -e --nodeps mysql-libs-5.1.73-5.el6_6.x86_64
# 再次執行查詢命令,檢視是否刪除成功
[root@localhost /]# rpm -qa | grep mysql
# 查詢所有MySQL對應的資料夾
[root@localhost /]# whereis mysql
mysql: /usr/bin/mysql /usr/include/mysql
[root@localhost lib]# find / -name mysql
/data/mysql
/data/mysql/mysql
# 刪除相關目錄或檔案
[root@localhost /]# rm -rf /usr/bin/mysql /usr/include/mysql /data/mysql /data/mysql/mysql
# 驗證是否刪除完畢
[root@localhost /]# whereis mysql
mysql:
[root@localhost /]# find / -name mysql
[root@localhost /]#
# 檢查MySQL使用者和使用者組是否存在,如果沒有則建立
[root@localhost /]# cat /etc/group | grep mysql
[root@localhost /]# cat /etc/passwd | grep mysql
[root@localhost /]# groupadd mysql
[root@localhost /]# useradd -r -g mysql mysql
# 下載MySQL
[root@localhost /]# wget https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.24-linux-glibc2.12-x86_64.tar.gz
# 執行解壓縮命令
[root@localhost /]# tar xzvf mysql-5.7.24-linux-glibc2.12-x86_64.tar.gz
[root@localhost /]# ls
mysql-5.7.24-linux-glibc2.12-x86_64
mysql-5.7.24-linux-glibc2.12-x86_64.tar.gz
[root@localhost /]# mv mysql-5.7.24-linux-glibc2.12-x86_64 /usr/local/
[root@localhost /]# cd /usr/local/
[root@localhost /]# mv mysql-5.7.24-linux-glibc2.12-x86_64 mysql
[root@localhost /]# mkdir /usr/local/mysql/data
# 更改mysql目錄下所有的目錄及檔案所屬的使用者和使用者組,以及許可權
[root@localhost /]# chown -R mysql:mysql /usr/local/mysql
[root@localhost /]# chmod -R 755 /usr/local/mysql
# 編譯安裝並初始化mysql,務必記住初始化輸出日誌末尾的密碼(資料庫管理員臨時密碼)
[root@localhost /]# cd /usr/local/mysql/bin
[root@localhost bin]# ./mysqld --initialize --user=mysql --datadir=/usr/local/mysql/data --basedir=/usr/local/mysql
# 測試啟動mysql伺服器
[root@localhost /]# /usr/local/mysql/support-files/mysql.server start
# 新增軟連線,並重啟mysql服務
[root@localhost /]# ln -s /usr/local/mysql/support-files/mysql.server /etc/init.d/mysql
[root@localhost /]# ln -s /usr/local/mysql/bin/mysql /usr/bin/mysql
[root@localhost /]# service mysql restart
#登陸mysql,修改密碼(密碼為初始化mysql時生成的臨時密碼)
[root@localhost /]# mysql -u root -p
Enter password:
mysql>set password for root@localhost = password('yourpass');
# 設定開機自啟動
[root@localhost /]# cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld
[root@localhost /]# chmod +x /etc/init.d/mysqld
[root@localhost /]# chkconfig --add mysqld
[root@localhost /]# chkconfig --list

十、安裝Jenkins

# yum的repos中預設是沒有Jenkins的,需要先將Jenkins儲存庫新增到yum repos
sudo wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo
sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io.key
yum install jenkins
#安裝完畢後進入jenkins配置檔案
vi /etc/sysconfig/jenkins
JENKINS_USER="root"
JENKINS_PORT="8081"
service jenkins start

十一、安裝NodeJS

#下載壓縮包
cd /usr/local
wget https://nodejs.org/dist/latest-v12.x/node-v12.19.0-linux-x64.tar.xz
tar -xvf node-v12.19.0-linux-x64.tar.xz
mv node-12.19.0 node
#進入到node目錄的bin中,檢查是否安裝成功
cd node/bin
./node -v
#配置軟連結,使全域性都可以使用node命令
ln -s /usr/local/node/bin/node /usr/bin/node
ln -s /usr/local/node/bin/npm /usr/bin/npm
#配置node檔案安裝路徑
cd /usr/local/node
mkdir node_global
mkdir node_cache
npm config set prefix “node_global”
npm config set cache “node_cache”
#在全域性下檢視node和npm版本
node -v
npm -v

十二、安裝Nginx

 1 #環境安裝
2 yum -y install gcc gcc-c++ autoconf automake make
3 yum -y install make zlib-devel gcc-c++ libtool openssl openssl-devel
4 #下載壓縮包
5 cd /usr/local
6 wget http://nginx.org/download/nginx-1.9.9.tar.gz
7 #解壓壓縮包
8 tar -zxvf nginx-1.9.9.tar.gz
9 #進入nginx目錄
10 cd nginx-1.9.9
11 #設定安裝目錄為/usr/local/nginx
12 ./configure --prefix=/usr/local/nginx
13 #編譯、安裝
14 make
15 make install
16 #啟動nginx服務
17 cd /usr/local/nginx/sbin
18 ./nginx

修改Nginx配置檔案:

 1 cd /usr/local/nginx/conf
2 vim nginx.conf
3 server {
4 listen 8801;
5 root /usr/share/nginx/html;
6
7 # Load configuration files for the default server block.
8 include /etc/nginx/default.d/*.conf;
9
10 location / {
11 root /usr/local/operation_analysis/op-web-package/dist;
12 }
13
14 location /op-analysis {
15 proxy_pass http://172.16.239.51:8101/op-analysis;
16 }
17
18 error_page 404 /404.html;
19 location = /40x.html {
20 }
21
22 error_page 500 502 503 504 /50x.html;
23 location = /50x.html {
24 }
25 }

十三、介面自動化整合

13.1、安裝JDK

 1 useradd java  #新增java使用者
2 passwd java
3 cd /home/java
4 wget https://www.oracle.com/webapps/redirect/signon?nexturl=https://download.oracle.com/otn/java/jdk/8u271-b09/61ae65e088624f5aaa0b1d2d801acb16/jdk-8u271-linux-x64.tar.gz
5 tar -zxvf jdk-8u271-linux-x64.tar.gz
6 vim /etc/profile
7 export JAVA_HOME=/home/java/jdk1.8.0_271
8 export PATH=$JAVA_HOME/bin:$PATH
9 source /etc/profile
10 java -version
11 ln -s /home/java/jdk1.8.0_271/bin/java /usr/bin/java

13.2、安裝Maven

官網下載地址:http://maven.apache.org/download.cgi

1 tar -zxvf apache-maven-3.6.3-bin.tar.gz -C /usr/local/maven
2 vim /etc/profile
3 export M2_HOME=/usr/local/maven/apache-maven-3.6.3
4 export PATH=$PATH:$M2_HOME/bin
5 source /etc/profile
6 mven -version

13.3、Maven工程構建

13.4、Maven工程子目錄建立

建立maven工程後,在工程目錄下建立如下所需的資料夾

src/test/resources:存放報告模板檔案

src/test/jmeter:存放jmeter配置檔案及測試指令碼

說明:

1)這裡的resources下放的是報告模板檔案:jmeter-results-report-apitest.xsl等,以及模板用到的資原始檔:collapse.png和expand.png (從 apache-jmeter-3.3\extras下複製而來);

2)jmeter.properties等是jmeter配置檔案(從apache-jmeter-3.3\bin下複製而來),字尾.jmx為jmeter指令碼(後續只需要把本地除錯通過的jmeter指令碼放入如圖這個目錄就可以了);

3)如果properties檔案有過更改,則把相關的propertie檔案也複製到jmeter資料夾裡,否則系統會使用預設的jmeter配置檔案。

13.5、JMeter配置檔案修改

jmeter執行結果檔案預設儲存的不是xml格式,無法轉化成html格式。

jmeter執行結果檔案預設有很多執行資料是不儲存的,而測試報告需要這些資料。

開啟jmeter.properti檔案,做如下修改:

1)去掉註釋(#),修改csv為xml。

2) 新增jtl檔案結果引數

 1 jmeter.save.saveservice.data_type=true
2 jmeter.save.saveservice.label=true
3 jmeter.save.saveservice.response_code=true
4 # response_data is not currently supported for CSV output
5 jmeter.save.saveservice.response_data=true
6 # Save ResponseData for failed samples
7 jmeter.save.saveservice.response_data.on_error=false
8 jmeter.save.saveservice.response_message=true
9 jmeter.save.saveservice.successful=true
10 jmeter.save.saveservice.thread_name=true
11 jmeter.save.saveservice.time=true
12 jmeter.save.saveservice.subresults=true
13 jmeter.save.saveservice.assertions=true
14 jmeter.save.saveservice.latency=true
15 jmeter.save.saveservice.connect_time=true
16 jmeter.save.saveservice.samplerData=true
17 jmeter.save.saveservice.responseHeaders=true
18 jmeter.save.saveservice.requestHeaders=true
19 jmeter.save.saveservice.encoding=false
20 jmeter.save.saveservice.bytes=true
21 jmeter.save.saveservice.url=true
22 jmeter.save.saveservice.filename=true
23 jmeter.save.saveservice.hostname=true
24 jmeter.save.saveservice.thread_counts=true
25 jmeter.save.saveservice.sample_count=true
26 jmeter.save.saveservice.idle_time=true

13.6、編輯pom.xml檔案

  1 <project xmlns="http://maven.apache.org/POM/4.0.0"
2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
4 <modelVersion>4.0.0</modelVersion>
5
6 <groupId>APITest</groupId>
7 <artifactId>JMeter</artifactId>
8 <version>0.0.1-SNAPSHOT</version>
9
10 <name>JMeterTest</name>
11 <url>http://maven.apache.org</url>
12 <dependencies>
13 <dependency>
14 <groupId>junit</groupId>
15 <artifactId>junit</artifactId>
16 <version>3.8.1</version>
17 <scope>test</scope>
18 </dependency>
19 <dependency>
20 <groupId>javax.servlet</groupId>
21 <artifactId>servlet-api</artifactId>
22 <version>3.0-alpha-1</version>
23 </dependency>
24 <dependency>
25 <groupId>mysql</groupId>
26 <artifactId>mysql-connector-java</artifactId>
27 <version>5.1.13</version>
28 </dependency>
29 <!-- <dependency> <groupId>org.apache.jmeter</groupId> <artifactId>ApacheJMeter_jdbc</artifactId>
30 <version>2.11</version> </dependency> <dependency> <groupId>com.oracle</groupId>
31 <artifactId>ojdbc14</artifactId> <version>10.2.0.5</version> </dependency> -->
32 <!-- MySql 5.5 Connector -->
33 </dependencies>
34 <properties>
35 <jmeter.result.jtl.dir>${project.build.directory}\jmeter\results</jmeter.result.jtl.dir>
36 <jmeter.result.html.dir>${project.build.directory}\jmeter\html</jmeter.result.html.dir>
37 <jmeter.result.html.dir1>${project.build.directory}\jmeter\html1</jmeter.result.html.dir1>
38 <jmeter.result.html.dir2>${project.build.directory}\jmeter\html2</jmeter.result.html.dir2>
39 <ReportName>TestReport</ReportName>
40 </properties>
41 <pluginRepositories>
42 <pluginRepository>
43 <id>Codehaus repository</id>
44 <url>http://repository.codehaus.org/</url>
45 <releases>
46 <enabled>true</enabled>
47 <updatePolicy>always</updatePolicy>
48 </releases>
49 <snapshots>
50 <enabled>true</enabled>
51 <updatePolicy>always</updatePolicy>
52 </snapshots>
53 </pluginRepository>
54 </pluginRepositories>
55 <build>
56 <finalName>vet2</finalName>
57 <plugins>
58 <plugin>
59 <!—核心外掛,用來執行jmx指令碼,注意版本號-->
60 <groupId>com.lazerycode.jmeter</groupId>
61 <artifactId>jmeter-maven-plugin</artifactId>
62 <version>2.7.0</version>
63 <executions>
64 <execution>
65 <id>test</id>
66 <phase>verify</phase>
67 <goals>
68 <goal>jmeter</goal>
69 </goals>
70 <!-- <configuration> <resultsFileFormat>csv</resultsFileFormat> </configuration> -->
71 </execution>
72 </executions>
73 <configuration>
74 <!-- 設定jmeter生成結果檔案格式 -->
75 <resultsFileFormat>xml</resultsFileFormat>
76 <!-- 設定忽略失敗是否停止執行 -->
77 <ignoreResultFailures>true</ignoreResultFailures>
78 <!-- 設定結果是否有時間戳 -->
79 <testResultsTimestamp>flase</testResultsTimestamp>
80 <generateReports>false</generateReports>
81 <testFilesIncluded>
82 <!-- 指定執行的jmeter指令碼 -->
83 <jMeterTestFile>*.jmx</jMeterTestFile>
84 </testFilesIncluded>
85 </configuration>
86 </plugin>
87 <!-- <plugin> <groupId>org.apache.jmeter</groupId> <artifactId>ApacheJMeter_jdbc</artifactId>
88 <version>2.11</version> </plugin> -->
89
90 <plugin>
91 <artifactId>maven-compiler-plugin</artifactId>
92 <configuration>
93 <source>1.8</source>
94 <target>1.8</target>
95 <encoding>UTF-8</encoding>
96 <compilerArguments>
97 <extdirs>src\test\jmeter\lib</extdirs>
98 </compilerArguments>
99 </configuration>
100 </plugin>
101
102 <plugin>
103 <!--根據xsl模版把jtl檔案轉換成html,官網地址: http://www.mojohaus.org/xml-maven-plugin/examples/transform-saxon.html-->
104 <groupId>org.codehaus.mojo</groupId>
105 <artifactId>xml-maven-plugin</artifactId>
106 <version>1.0.2</version>
107 <executions>
108 <execution>
109 <phase>verify</phase>
110 <goals>
111 <goal>transform</goal>
112 </goals>
113 </execution>
114 </executions>
115 <configuration>
116 <transformationSets>
117 <transformationSet>
118 <dir>${jmeter.result.jtl.dir}</dir>
119 <stylesheet>src/test/resources/jmeter-results-detail-report_21.xsl</stylesheet>
120 <outputDir>${jmeter.result.html.dir}</outputDir>
121 <fileMappers>
122 <fileMapper
123 implementation="org.codehaus.plexus.components.io.filemappers.FileExtensionMapper">
124 <targetExtension>html</targetExtension>
125 </fileMapper>
126 </fileMappers>
127 </transformationSet>
128 <transformationSet>
129 <!-- 可以根據不同的模版,同時生成多個html報告 -->
130 <dir>${jmeter.result.jtl.dir}</dir>
131 <stylesheet>src/test/resources/jmeter.results.shanhe.me.xsl</stylesheet>
132 <outputDir>${jmeter.result.html.dir1}</outputDir>
133 <fileMappers>
134 <fileMapper
135 implementation="org.codehaus.plexus.components.io.filemappers.FileExtensionMapper">
136 <targetExtension>html</targetExtension>
137 </fileMapper>
138 </fileMappers>
139 </transformationSet>
140 <transformationSet>
141 <dir>${jmeter.result.jtl.dir}</dir>
142 <stylesheet>src/test/resources/jmeter-results-report-apitest.xsl</stylesheet>
143 <outputDir>${jmeter.result.html.dir2}</outputDir>
144 <fileMappers>
145 <fileMapper
146 implementation="org.codehaus.plexus.components.io.filemappers.FileExtensionMapper">
147 <targetExtension>html</targetExtension>
148 </fileMapper>
149 </fileMappers>
150 </transformationSet>
151 </transformationSets>
152 </configuration>
153 </plugin>
154 <plugin>
155 <groupId>org.apache.maven.plugins</groupId>
156 <artifactId>maven-dependency-plugin</artifactId>
157 <executions>
158 <execution>
159 <id>copy-dependencies</id>
160 <phase>prepare-package</phase>
161 <goals>
162 <goal>copy-dependencies</goal>
163 </goals>
164 <configuration>
165 <outputDirectory>${project.build.directory}/jmeter/lib</outputDirectory>
166 <overWriteReleases>false</overWriteReleases>
167 <overWriteSnapshots>false</overWriteSnapshots>
168 <overWriteIfNewer>true</overWriteIfNewer>
169 </configuration>
170 </execution>
171 </executions>
172 </plugin>
173 <plugin>
174 <groupId>org.apache.maven.plugins</groupId>
175 <artifactId>maven-jar-plugin</artifactId>
176 <configuration>
177 <archive>
178 <manifest>
179 <addClasspath>true</addClasspath>
180 <classpathPrefix>lib/</classpathPrefix>
181 <mainClass>theMainClass</mainClass>
182 </manifest>
183 </archive>
184 </configuration>
185 </plugin>
186 <!-- 把resources資料夾下面的檔案拷貝到jmeter/html目錄下 -->
187 <plugin>
188 <artifactId>maven-resources-plugin</artifactId>
189 <executions>
190 <execution>
191 <id>copy-resources-html</id>
192 <phase>compile</phase>
193 <goals>
194 <goal>copy-resources</goal>
195 </goals>
196 <configuration>
197 <!-- test可以在環境變數中定義,也可以將下面寫成絕對地址 -->
198 <outputDirectory>${project.build.directory}/jmeter/html</outputDirectory>
199 <resources>
200 <resource>
201 <!-- basedir標識所有工程 -->
202 <directory>${basedir}/src/test/resources</directory>
203 <filtering>true</filtering>
204 </resource>
205 </resources>
206 </configuration>
207 </execution>
208 </executions>
209 </plugin>
210 <!-- 把resources資料夾下面的檔案拷貝到jmeter/lib/ext目錄下 -->
211 <plugin>
212 <artifactId>maven-resources-plugin</artifactId>
213 <executions>
214 <execution>
215 <id>copy-resources-lib</id>
216 <phase>compile</phase>
217 <goals>
218 <goal>copy-resources</goal>
219 </goals>
220 <configuration>
221 <!-- test可以在環境變數中定義,也可以將下面寫成絕對地址 -->
222 <outputDirectory>${project.build.directory}/jmeter/lib/ext</outputDirectory>
223 <resources>
224 <resource>
225 <!-- basedir標識所有工程 -->
226 <directory>${basedir}/src/test/lib</directory>
227 <filtering>false</filtering>
228 </resource>
229 </resources>
230 </configuration>
231 </execution>
232 </executions>
233 </plugin>
234
235 </plugins>
236 <defaultGoal>clean</defaultGoal>
237 </build>
238 </project>

Maven配置說明:

jmeter.result.jtl.dir:生成.jtl格式的測試報告路徑

jmeter.result.html.dir:生成.html格式的測試報告路徑

jmeter-maven-plugin:jmeter執行jmx指令碼核心外掛

jmeterExtensions:配置jmeter擴充套件依賴包

kg.apc:jmeter-plugins-json:2.6:jmeter用來做json資料斷言用的外掛

testFilesDirectory:指定jmx資料夾

testFilesIncluded:指定可執行測試指令碼

testFilesExcluded:指定不可執行測試指令碼

13.7、外掛安裝

需要安裝的外掛:HTML Publisher plugin、Groovy Label Assignment plugin。

因為Jenkins安全預設把如下功能都關閉了,需要 Groovy 外掛執行 Groovy 指令碼開啟:

1、javascript

2、html上的內建外掛

3、內建css或從其它網站的css

4、從其它網站的圖片

5、AJAX

構建配置時,填寫如下Groovy指令碼,每次構建後執行這段指令碼開啟如上功能:

System.setProperty("hudson.model.DirectoryBrowserSupport.CSP",
"")。

13.8、Jenkins構建任務

1)構建一個maven專案。

2)在General模組中勾選“Groovy script to restrict where this
project can be run”,並在“Groovy Script”中輸入上述的程式碼。

3)原始碼管理

4)構建配置

5)構建後操作

十四、git相關知識

14.1、建立版本庫

首先需要建立一個版本庫,用於儲存該專案本身及其歷史。為此,我們需要在該專案目錄中使用init命令。對於一個帶版本庫的專案目錄,我們通常稱之為工作區:

>cd
d:/projects/first-steps

>git init

Init命令會在上述目錄中建立一個名為.git的隱藏目錄,並在其中建立一個版本庫。

接下來,我們需要將foo.txt和bar.txt這兩個檔案新增到版本庫中去。第一步,我們要先用add命令來確定哪些檔案應被包含在下次提交中。第二步,再用commit命令將修改傳送到版本庫中:

>git add bar.txt foo.txt

>git commit --meaasge
“Sample project imported”

如果我們對工作區中的檔案進行了修改,status命令會顯示出該專案自上次提交以來所發生的所有修改:

>git status

如果我們還想看到更多細節性的內容,也可以通過diff命令來顯示其每個被修改的行:

>git diff foo.txt

所有的修改都必須要先被歸檔成一次新的提交。我們要對修改過的檔案和新檔案執行add命令,並對要刪除的檔案使用rm命令:

>git add foo.txt bar.html

>git rm bar.txt

現在再次呼叫status命令,我們會看到所有的修改已經被納入了下一次提交中:

>git status

然後用commit命令提交這些修改:

>git commit –message
“Some changes”

log命令可用來顯示專案的歷史,所有的提交都會按時間順序被降序排列出來:

>git log

在Git中,每個開發者擁有的是一個屬於他/她自己的、自帶獨立版本庫的工作區,因此這已經是一個不依賴於中央伺服器的、完整的版本控制系統了。開發者們可以通過交換各自版本庫中的提交來實現專案合作。

14.2、克隆版本庫

新開發者首先要有一個屬於他/她自己的版本庫副本(也稱為克隆體)。該副本中包含了所有的原始資訊與整個專案的歷史資訊。下面,我們用clone命令來建立一個克隆體:

>git clone
d:/projects/first-steps d:/projects/first-steps-clone

現在的專案結構為:

現在我們來修改一下first-steps/foo.txt檔案,並執行以下操作來建立一次新提交:

> cd
d:/projects/first-steps

> git add foo.txt

> git commit --message
"A change in the original."

現在,新的提交已經被存入了我們原來的first-steps版本庫中,但其克隆版本庫(first-stepsclone)中依然缺失這次提交。我們再來修改克隆版本庫中的first-steps-clone/bar.html檔案,並執行以下操作:

> cd
d:/projects/first-steps-clone

> git add bar.html

> git commit --message
"A change in the clone."

現在,我們在兩個版本庫中各做了一次新的提交。接下來,我們要用pull命令將原版本庫中的新提交傳遞給它的克隆體。由於之前我們在建立克隆版本庫時,原版本庫的路徑就已經被儲存在了它的克隆體中,因此pull命令知道該從哪裡去取回新的提交。

> cd
d:/projects/first-steps-clone

> git pull

pull命令從原版本庫中取回了新的修改,將它們與克隆體中的本地修改進行了對比,並在工作區中合併了兩邊的修改,建立了一次新的提交。這個過程就是所謂的合併merge

在拉回(pull)、合併(merge)的過程完成之後,我們可以用一個新的log命令來檢視結果:

> git log --graph

在沒有引數的情況下,pull命令只在克隆版本庫中能發揮作用,因為只有該克隆體中有預設的原版本庫的連線。當我們執行pull操作時,也可以用引數來指定任意版本庫的路徑,以便從某一特定開發分支中提取相關修改。下面的指令能讓我們將克隆體中的修改pull到原版本庫中:

> cd
/projects/first-steps    #
切換到原版本庫

> git pull
/projects/first-steps-clone master    #
將克隆體中的修改pull到原版本中

14.3、分支

在一個Git版本庫中,總是唯一存在著一個活動分支。我們可以用branch命令(不帶選項)來列出當前所有的分支。其中用星號(*凸顯的就是當前的活躍分支:

> git branch

  a-branch

* master 

  still-a-branch

一般情況下,活動分支將會被繼續用於接受所有新的提交,並將分支指標移動至最近的那次提交。當然,我們也可以用checkout命令來改變當前的活躍分支:

> git checkout a-branch

下面,我們來建立一個新的分支

1)為當前提交建立分支:

>git branch a-branch

2)切換到新分支:

>git checkout a-branch

快捷方式,建立並切換分支:

>git checkout -b a-branch

通常情況下,我們可以用checkout命令在分支之間來回切換。但是,如果這時候工作區還存在著一些修改,我們就必須要先決定好如何處理這部分修改。

我們可以通過branch
-d
命令來刪除分支:

1)刪除一個已被終止的分支:

>git branch -d a-branch

2)刪除一個開啟的分支:

如果我們在試圖刪除一個分支時自己還未轉移到不同的分支(例如master分支)上,Git就會給出一個警告,並拒絕該刪除操作。如果你堅持要刪除該分支的話,就需要在命令中使用-D選項:

> git brach -D a-branch

14.4、合併分支

使用merge命令來進行分支合併是Git中最重要的操作之一。我們可以通過指定分支名稱來選擇待合併修改的分支。然後,Git會基於合併的內容來建立一次新的提交。

git merge命令用於合併指定分支到當前分支:

>git checkout test    # 切換到test分支

>git merge dev    # dev分支合併到test分支

14.5、建立標籤

1)建立一個普通的標籤

在下面的例子中,我們會為master分支上的當前版本建立一個名為1.2.3.4的標籤,並將其註釋為“Freshly
built.”:

> git tag 1.2.3.4 master
-m "Freshly built."

2)推送某單一標籤

推送操作通常不會自動傳送標籤。但如果我們明確指定了某個標籤名,該標籤就可以被傳送了:

> git push origin V1.0.0

3)將標籤傳送到指定的分支(test)上:

>git push origin test
V1.0.0

14.6、git常用命令

1、遠端倉庫相關命令

檢出倉庫:$ git clone
git://github.com/jquery/jquery.git

檢視遠端倉庫:$ git remote -v

新增遠端倉庫:$ git remote add [name] [url]

刪除遠端倉庫:$ git remote rm [name]

修改遠端倉庫:$ git remote set -url --push [name]
[newUrl]

拉取遠端倉庫:$ git pull [remoteName] [localBranchName]

推送遠端倉庫:$ git push [remoteName] [localBranchName]

如果想把本地的某個分支test提交到遠端倉庫,並作為遠端倉庫的master分支,或者作為另外一個名叫test的分支,如下:

$git push origin test:master // 提交本地test分支作為遠端的master分支

$git push origin test:test // 提交本地test分支作為遠端的test分支

2、分支(branch)操作相關命令

檢視本地分支:$ git branch

檢視遠端分支:$ git branch
-r

建立本地分支:$ git branch
[name]
----注意新分支建立後不會自動切換為當前分支

切換分支:$ git checkout
[name]

建立新分支並立即切換到新分支:$
git checkout -b [name]

刪除分支:$ git branch
-d [name]
---- -d選項只能刪除已經參與了合併的分支,對於未有合併的分支是無法刪除的。如果想強制刪除一個分支,可以使用-D選項:$git branch -D [name]

合併分支:$ git merge
[name]
----將名稱為[name]的分支與當前分支合併

建立遠端分支(本地分支push到遠端):$ git push
origin [name]

3、版本(tag)操作相關命令

檢視版本:$ git tag

建立版本:$ git tag [name]                                                                                           

刪除版本:$ git tag -d
[name]

檢視遠端版本:$ git tag -r

合併遠端倉庫的tag到本地:$ git pull
origin --tags

上傳本地tag到遠端倉庫:$ git push
origin --tags

建立帶註釋的tag:$ git tag -a
[name] -m 'yourMessage'

對指定的commit ID建立版本:$ git tag -a
[name] [commit ID] -m ‘yourMessage’

檢視版本的詳細資訊:$
git show [name]

4、其它命令

改變檔名字:$ git mv old-filename
new-filename

刪除檔案:$ git rm filename

檢視本地目錄和暫存區之間檔案的差異:$ git diff filename

檢視暫存區和本地倉庫之間檔案的差異:$ git diff --cached filename

檢視提交日誌:$ git log、$ git log
--oneline、$ git log -n

本地檔案誤操作回退:

使用暫存區內容覆蓋本地目錄:$
git checkout filename

本地檔案提交至暫存區後的回退操作:

1)本地倉庫覆蓋暫存區:$ git reset HEAD filename

2)暫存區覆蓋本地目錄:$ git checkout -- filename

多次提交後會回退到某個版本:

$ git log --oneline #檢視版本號

$ git reset --hard <版本號> #回退到指定的版本號

十五、分支管理模式

15.1、開發階段

1)       
除了master分支建立一個供所有開發人員開發的dev分支;

2)       
開發人員在dev分支上進行工作,隨時隨地commit,每天push一次到伺服器;

3)       
push程式碼前需要進行pull操作,因為有可能在之前有別的成員先進行了push操作,如果有衝突還需要進行衝突解決;

4)       
每天上班後所有成員對dev進行pull操作,獲取所有成員push的程式碼,有衝突需要解決;

5)       
團隊Leader每天將dev合併一次到master

15.2、測試階段

1)       
測試進入後就需要新增test分支;

2)       
在開發人員將程式碼pushdev分支後,可以在dev基礎上建立test分支,測試人員以test分支搭建測試環境,開始測試;

3)       
開發人員在接收到bug後,直接在測試分支上修改,然後讓測試人員進行驗證;

4)       
每天團隊Leader將測試分支上修改的bug合併到dev分支上,這樣所有團隊成員當天修復的bug都會在第二天被團隊其他人pull下來;

5)       
團隊Leader每天將dev合併一次到master

15.3、上線階段

1)     
系統上線後試執行階段會存在兩種改動:bug和優化需求,bug通常當天解決晚上部署,優化需求通常週末部署;

2)     
bug當天能修復的就直接在test分支上修復,然後進行測試,驗證通過後合併到master

3)     
bug當天不能修復的就針對該bug建立一個分支,修復完後合併到test分支進行測試,驗證通過後合併到master

4)     
每個優化需求都以master分支為基礎建立一個feature分支,完成後合併到dev分支,開發人員可以先交叉測試,然後將dev合併到test進行測試,驗證通過後合併到master

5)     
master始終是一個乾淨的,可釋出的分支。

15.4、merge request模式

1)     
需求或是Bug都是用Issue來表示;

2)     
雖然Issue不支援多層級,但結合里程碑、標籤等還是可以很好的對任務和Bug進行管理;

3)     
管理員和團隊成員都可以進行Issue的建立;

4)     
任務的接收者對Issue建立Merge Request

5)     
完成任務後推送程式碼到Merge Request對應的分支;

6)     
管理員對程式碼進行Merge

15.5、merge request工作流程

1)設定重要分支受保護

2)建立issue

3)任務建立後,開發人員就可以根據該任務建立Merge Request

------------------------------

初始化版本庫,並提交到遠端伺服器端

mkdir WebApp

cd WebApp

git init本地初始化

touch README

git add README新增檔案

git commit -m 'first commit'

git remote add origin [email protected]:daixu/WebApp.git增加一個遠端伺服器端

上面的命令會增加URL地址為'[email protected]:daixu/WebApp.git',名稱為origin的遠端伺服器庫,以後提交程式碼的時候只需要使用origin別名即可。