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**********************************
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章