1. 程式人生 > >Jenkins 配合 GitLab 實現分支的自動合併、自動建立 Tag

Jenkins 配合 GitLab 實現分支的自動合併、自動建立 Tag

Jenkins 配合 GitLab 實現分支的自動合併、自動建立 Tag

背景

GitFlow工作流簡介

Gitflow工作流定義了一個圍繞專案釋出的嚴格分支模型,它會相對複雜一點,但提供了用於一個健壯的用於管理大型專案的框架,非常適合用來管理大型專案的釋出和維護。 貫穿整個開發週期,masterdevelop分支是一直存在的,master分支可以被視為穩定的分支, 而develop分支是相對穩定的分支,特性開發會在feature分支上進行,釋出會在release分支上進行,而bug修復則會在hotfix分支上進行,這樣也有效避免了不同型別的開發工作在程式碼層級的耦合和干擾。

GitFlow工作流優化

  • hotfix和release的結果都要合併到master和develop中,為什麼?因為它們的修改結果將持續影響這後續的開發和維護,必須合併以保證程式碼的一致性。

  • 當線上專案需要版本回退,或者需要簡單記錄迭代版本時,我們常在master分支上打上 Tag 標籤,例如:

    • 功能釋出:release_20190101_當月版本數
    • BUG修復:hotfix_20190101_修復次數

本文基於GitFlow工作流,將利用Jenkins配合GitLab實現以下自動化任務

  • master分支程式碼更新後,自動將程式碼合併到develop分支
  • master分支程式碼更新後,自動在master分支提交中打 tag

Jenkins自動任務Job的建立

Jenkins是一個用Java編寫的開源的持續整合工具,可以與Git打通,監聽Git的merge, push事件,觸發執行Jenkins的指定任務(job),例如執行單元測試。更多的是:當代碼變更時可以觸發打包部署、效能測試、介面測試、監控、日誌分析等。專案釋出的任何一個環節都可自動完成,無需太多的人工干預,有利於減少重複過程以節省時間和工作量等。

如何建立Jenkins Job

下面列出自動任務Jenkins Job的建立過程,供參考。建立過程如下:

  • 首先,建立一個任務,輸入名稱,選擇“構建一個自由風格的軟體專案” 確定即可。

  • General:填寫專案名稱及描述;Label Expression 是在Jenkins admin 中配置的節點(container, node),一個Label Expression 是一組docker,當多個不同的Job同時執行的時候,可以實現並行。

  • 原始碼管理:在Repository URL中填寫GitLab中的專案地址;Branches to build此處的Branch Specifier是觸發Jenkins Job時由Jenkins自動拉取的程式碼的分支,可以填寫一個固定的指定分支,如master,也可以寫正則表示式。另外,也可以填寫${gitlabSourceBranch}。如果填寫${gitlabSourceBranch},表示從git讀取Merge Request的源分支,使用該變數,則不能手工點選Job的“立即構建”執行job了,因為讀取不到這個變數只能通過git push事件觸發了。具體可以根據應用場景選擇。

  • 構建觸發器:下面截圖中指定的是:僅當產生 push 事件時且目標分支為master時觸發此job。這裡可以根據需求來具體配置。Filter branches by name:僅當目標分支為 master 時觸發Job。

  • 構建環境 & 構建:構建環境勾選第一項指在每次構建開始之前先清空工作空間;構建中的Execute shell Command 中就可以配置我們自動化指令碼,我們可以把這些指令碼放到專案根目錄當中,也可以放到一個GitLab倉庫當中,來統一管理指令碼(文末附指令碼示例)。


  • 構建後操作(Editable Email Notification):用於配置郵件提醒。

    • Disable Extended Email Publisher:勾選後,郵件就不傳送;
    • Project Recipient List:收件人地址;多個收件人郵件地址用逗號進行分割;
    • Project Reply-To List:允許回覆人的地址;預設為$DEFAULT_REPLYTO;
    • Content Type:郵件文件的型別,可以設定HTML等格式;
    • Default Subject:預設郵件標題;也可以使用$DEFAULT_SUBJECT;
    • Default Content:預設郵件內容,這裡可以寫HTML檔案,引用Jenkins內部的一些變數;也可以使用預設內容:$DEFAULT_CONTENT;
    • Attach Build Log:傳送的郵件是否包含日誌。

    Triggers 中的配置需要注意下,一般配置為Job執行失敗的時候傳送郵件


Jenkins Job 如何與 Git 關聯

在GitLab專案的Settings中找到如下圖的配置:勾選“Active”,指定在Git Push 或 mr 建立/更新/合併時觸發指定的 Jenkins url,Project name 為Jenkins 中配置的Job名稱,使用者名稱、密碼是jenkins的賬號和密碼。

整體步驟梳理

  1. GitLab上準備一個專案工程;
  2. 安裝Jenkins以及相關的GitLab外掛;
  3. Jenkins配置GitLab訪問許可權;
  4. Jenkins上建立一個Job,對應步驟1中的專案工程;
  5. GitLab專案中配置Jenkins;
  6. 修改專案工程的原始碼,並提交到GitLab上;
  7. 檢查Jenkins的構建任務是否會觸發配置的指令碼。

指令碼示例

以下為master分支程式碼更新後,自動在master分支提交中打 tag的指令碼示例,僅供參考:

( Tag 標籤命名規則: release_當前日期_當月版本_當季度版本_當年版本 )

#!/bin/sh
echo **********************************Start********************************
date
# 獲取最近一次遠端 master 提交的 commit id
sha1=`git rev-parse remotes/origin/master^{commit}`
# 獲取姓名及郵箱,來配置git提交者資訊
name=`git show --pretty=%an $sha1 | awk 'NR==1{print}'`
email=`git show --pretty=%ce $sha1 | awk 'NR==1{print}'`
echo '################# 當前提交人資訊:'
echo $name 
echo $email 
git config --global user.name $name
git config --global user.email $email

# 獲取 merge 的源分支字首
function getOriginPrefix(){
  # 獲取分支所屬
  info_sha1=`git show $sha1 | grep 'Merge:' | cut -d' ' -f3`
  info_branch=`git branch -r --contains $info_sha1`
  # 判斷是否 hotfix 分支
  isHotfix=`echo "${info_branch}" | grep 'origin/hotfix'`
  if [ -n "$isHotfix" ]; then 
    echo 'hotfix'
  else
    echo 'release'
  fi
}
originBra=$(getOriginPrefix)
echo '################# 獲取的源分支字首為:' $originBra

# 獲取最近一次建立的標籤
latestTag=`git for-each-ref --sort=-taggerdate --format "%(tag)" refs/tags | grep $originBra | head -n 1`
# 獲取最近標籤的年
latestYear=`echo "${latestTag}" | awk -F_ '{print substr($2,1,4)}'`
# 獲取最近標籤的月
latestMonth=`echo "${latestTag}" | awk -F_ '{print substr($2,5,2)}'`
# 獲取最近標籤的季度
latestQuarter=`echo "${latestMonth}" | awk '{print int(($0-1)/3)+1}'`

# 獲取當年
currentYear=`date +%Y`
# 獲取當月
currentMonth=`date +%m`
# 獲取當日
currentDay=`date +%Y%m%d`
# 獲取當前季度
currentQuarter=`echo $currentMonth | awk '{print int(($0-1)/3)+1}'`

# 計算當月版本號
if [ $latestMonth -eq $currentMonth ]; then 
  currentMonthVersion=`echo "${latestTag}" | awk -F_ '{print $3+1}'`
else
  currentMonthVersion='1'
fi

# 計算當季度版本號
if [ $latestQuarter -eq $currentQuarter ]; then 
  currentQuarterVersion=`echo "${latestTag}" | awk -F_ '{print $4+1}'`
else
  currentQuarterVersion='1'
fi

# 計算當年版本號
if [ $latestYear -eq $currentYear ]; then 
  currentVersion=`echo "${latestTag}" | awk -F_ '{print $5+1}'`
else
  currentVersion='1'
fi

# 獲取最終標籤名 
newVersion=$originBra'_'$currentDay'_'$currentMonthVersion'_'$currentQuarterVersion'_'$currentVersion

# 建立標籤
git tag -a $newVersion -m '提交人: '$name
git push origin --tags
newTag=`git tag -l | grep $newVersion`
echo '################# 最近建立的標籤為:' $latestTag
echo '################# 自動計算的標籤為:' $newVersion
echo '################# 自動建立的標籤為:' $newTag
echo **********************************End**********************************

參考資料

Jenkins 官方文件

GitLab 官方文件

GitFlow 工作流

轉載請標註出處,謝謝!https://www.cnblogs.com/mycognos/p/10247648.html