實戰-jira集成gitlab,jenkins持續集成部署實現方案

一、概述

通常我們知道jira是軟件項目流程管理工具,通過該工具,項目負責人可以分配人物給項目上的開發人員,開發人員隨着開發的進度更新狀態,進而反饋開發進度,項目的部署單獨使用jenkins來實現。但是料想組內開發人員編寫的代碼能夠通過jira一鍵發佈打包,測試,合併到主分支,這樣就更好。

二、jira自定義流程

2.1、自定義版本任務流程

每次有一個版本需求的時候,我們需要自定義一個版本,命名爲版本任務。版本任務的流程大致有創建版本任務-集成部署與測試-DEV部署與測試-MST部署與測試-版本發佈-版本驗收-清理版本任務 這幾個過程。

 

 

2.2、自定義集成任務流程

每個版本需求可以細分出來很多任務需求,分配給對應的後端開發人員,前段開發人員。此時,我們也需要根據版本任務來創建每個開發人員的集成任務。開發任務主要包括創建分支-集成開發與測試-集成合並-DEV測試與合併-MST測試與合併等狀態。具體流程和以上版本任務創建類似。

三、jira集成gitlab

jira集成gitlab可以實現將git的commit信息上傳到jira項目的問題中,方便管理人員或開發人員查閱。

3.1、gitlab中的配置

1、登錄gitlab後臺,進入需要配置的項目,再點擊 Settings->Integrations->JIRA,如圖:

 

2、配置jira信息,如圖:

 

以上參數都需要配置:

Active、Trigger、Merge request:都勾上

Web URL:JIRA項目的基礎URL

Web API URL:如果在JIRA中沒有特殊配置API的URL,還是填上面的URL

Username:JIRA賬戶用戶名

Enter new password: JIRA賬戶密碼

Transition ID:此時填寫的在JIRA中對應的流程關閉ID,此時填1371,如圖:

 

3、填寫完成後保存,若填寫信息有誤會保存失敗。

4、測試在git中按照 jira任務編號+提交人+註釋內容 的註釋規範提交代碼,jira中相關任務

下就會出現具體的提交信息:

 

3.2 、jira中的配置

若要進一步友好展示,可進行jira插件選擇安裝。

四、jira集成jenkins

4.1、jenkins中的配置

jenkins中需要安裝的插件如下:

JIRA Integration for Jenkins

Jira Issue Updater

JIRA Pipeline Steps

JIRA plugin

JIRA Trigger Plugin

JiraTestResultReporter plugin

1、安裝完 JIRA Trigger Plugin插件後,在系統管理->系統設置中,需要配置該插件和jira的關聯:

 

4.2、jira中的配置

1、配置webhook,即網絡鉤子,jira->管理->系統->高級,找到WebHook:

 

2、創建webhook,點擊保存即可。如圖:

 

3、接口調試,通過訪問 http://ip:20003/jenkins/jiratriggerwebhookreceiver/ ,可查看jenkins接口是的能調通,若出現下圖,則表示可以調通:

asd

4、配置任務(版本任務和集成任務)

上面分別創建了JIRA的兩個任務流程,每個任務流程的每個按鈕都分別有個唯一的key值,通過jira點擊相應的按鈕,通過唯一的key可以觸發jenkins的腳本進行唯一的構建。

以版本任務進行闡釋:

 

JQL filter:指定觸發對象,project=WUZ指的是jira中項目關鍵字爲WUZ的項目,JQLfilter 包括:project、issue等

Comment pattern:jira備註中的comment,當用戶在jira中添加指定備註時,會觸發jenkins構建

Jenkins parameter:jenkins中的參數名稱

Issue attribute path:jira issue中提取出得需要傳給jenkins的屬性值

注:JIRA filed ID 和 Custom Field ID 可通過http://120.79.168.18:20000/rest/api/2/field 地址查詢

5、最後,只要修改jira的任務狀態,就會觸發jenkins自動構建,如圖:

 

五、jenkins shell腳本編寫

現在jira集成了jenkins,通過觸發jira的button實現jenkins的自動構建,那麼如果我們同時開發和部署多個項目,又該如何處理呢?

所以爲了做到拓展性,我們直接通過shell腳本編寫(重點講解從檢出代碼到打包部署的過程)。

5.1、項目檢出

可以根據JIRA上對應的不同項目名去檢出對應的項目。

# git 檢出任務分支

function check_out_code(){

    code_path=$1

fixVersionName=$2

echo "fixVersionName:${fixVersionName}"

git clone http://$jenkins_name:[email protected]/two/${project_name}.git $CLONE_ADDRESS

git clone http://$jenkins_name:[email protected]/two/${msf_project_name}.git $MSF_CLONE_ADDRESS

if [ ! -d ${git_check_out_code_path} ];

then

echo "項目還沒被檢出"

git init

git checkout -b ${fixVersionName}

else

echo "項目已經被檢出"

cd ${git_check_out_code_path}

#用代碼庫中的文件完全覆蓋本地工作版本

existing_branch=`git branch -a`

echo "遠程倉庫存在的分支:${existing_branch}"

for(( i=0;i<${#existing_branch[@]};i++)) do

brachName=$(echo \"${existing_branch[i]}\" |sed 's/\"//g')

if [[ $brachName =~ ${fixVersionName} ]]

then

echo "更新分支:${fixVersionName}"

git reset --hard

git pull origin ${fixVersionName}

fi

done;

fi

}

5.2、項目構建

構建可以按模塊構建,也可以構建整個項目

# gradle按照模塊的構建,根據不同的模塊進行模塊構建

function get_deployed_module()

{

if [[  ${module_code} = "ADMIN" ]]

then

  deployed_module='bee-core:bee_admin'

fi

if [[  ${module_code} = "CLIENT" ]]

then

  deployed_module='bee-core:bee_client'

fi

if [[  ${module_code} = "API" ]]

then

  deployed_module='bee-core:bee_api'

fi

if [[  ${module_code} = "TSK" ]]

then

  deployed_module='bee-core:bee_taskserver'

fi

if [[  ${module_code} = "MSG" ]]

then

  deployed_module='bee-core:bee_message'

fi

if [[  ${module_code} = "ORGAN" ]]

then

  deployed_module='bee-core:bee_organ'

fi

if [[  ${module_code} = "ACT" ]]

then

  deployed_module='bee-act:bee-act-admin'

fi

}

# gradle構建整個項目

function mvn_build()

{

cd ${build_based_path}

if [[  ${module_code} = "ALL" ]]

then

gradle clean

    gradle bootRepackage

else

gradle :${deployed_module}:clean

gradle :${deployed_module}:bootRepackage

fi

echo -e "============Gradle構建完成=============="

}

5.3、項目部署

由於模塊較多,現在就舉例說明後臺管理模塊的部署。具體流程

1、kill -9  admin_pid

2、拷貝admin jar包到部署路徑。

3、開啓admin文件自動在服務器上傳輸(如果jenkins和jar包不在同一個服務器上則需要改流程)。

4、運行部署命令進行項目部署。

5、將部署成功的狀態反饋到JIRA日誌信息

#部署admin 模塊

function deploy_admin_module()

{

jira_button_code=$1

echo -e "============開啓自動化部署admin!=============="

#admin_pid=`ps -ef | grep ${admin_deploy_path}/${admin_archive_name} | grep -v grep | awk '{print $2}'`

admin_pid=$(ssh -p 5000 [email protected]"ps -ef | grep ${admin_deploy_path}/${admin_archive_name} | grep -v grep | awk  '{print $2}'"| awk '{print $2}')

if [ -n "$admin_pid" ]

then

echo "admin_pid="$admin_pid

  ssh -p 5000 [email protected] "kill -9 ${admin_pid}"

fi

echo "開始拷貝admin jar包到部署路徑..."

cp -f ${git_check_out_code_path}/src/${projectName}/${common_module}/${admin_module}/build/libs/${admin_archive_name} ${deploy_path}/${admin_module}

echo "開始啓動程序..."

export BUILD_ID=dontKillMe

#sleep 30s

echo "開啓admin文件自動在服務器上傳輸."

    scp_put 132.124.2.10 root '*******&' ${deploy_path}/${admin_module}  ${deploy_path}

if [ ${jira_button_code} = "B471" ];

then

excute "/usr/bin/nohup nohup java -jar ${admin_deploy_path}/${admin_archive_name} --spring.cloud.config.profile=master --spring.cloud.config.profile=master --spring.application.name=${admin_spring_application_name} --server.port=${admin_port} --eureka.client.service-url.defaultZone=http://${register_center_ip_adress}:${port}/eureka -Xms64m -Xmx512m -XX:MaxMetaspaceSize=512m -XX:CompressedClassSpaceSize=64m -Xss256k -Xmn8m -XX:InitialCodeCacheSize=4m -XX:ReservedCodeCacheSize=8m -XX:MaxDirectMemorySize=16m  >/dev/null 2>&1 &"

else

excute "/usr/bin/nohup nohup java -jar ${admin_deploy_path}/${admin_archive_name} --spring.cloud.config.profile=dev --spring.cloud.config.profile=dev --spring.application.name=${admin_spring_application_name} --server.port=${admin_port} --eureka.client.service-url.defaultZone=http://${register_center_ip_adress}:${port}/eureka -Xms64m -Xmx512m -XX:MaxMetaspaceSize=512m -XX:CompressedClassSpaceSize=64m -Xss256k -Xmn8m -XX:InitialCodeCacheSize=4m -XX:ReservedCodeCacheSize=8m -XX:MaxDirectMemorySize=16m  >/dev/null 2>&1 &"

fi

echo -e "============自動化部署admin成功!============"

echo -e '\n\n'

}

 

function get_rest_web_api_login()

{

echo "開始登錄JIRA賬戶"

curl -c cookie.txt -d "os_username="${os_username}"&os_password="${os_password} -v ${login_api_uri}

cd ${cookie_file_path}

cookieContents=`cat ${cookie_file_path}/cookie.txt | awk -F "[JSESSIONID]" '/JSESSIONID/{print$0}'`

cookieContentsCutOut=$(echo $cookieContents | cut -d '/' -f 2)

JSESSIONID_STRING=$(echo ${cookieContentsCutOut} |tr -d " ")

JSESSIONID=${JSESSIONID_STRING:16}

echo "開始獲取登錄後的JSESSIONID"

echo "cookie文件中包含jSessionId的內容爲:::::${cookieContents}"

echo "JIRA賬戶登錄後的JSESSIONID的值爲:::::${JSESSIONID}"

}

function get_jira_login_status()

{

echo "開始判斷登錄狀態是否失效"

login_status_log=`curl --cookie JSESSIONID=${JSESSIONID} ${login_api_uri}`

echo "登錄狀態信息爲....${login_status_log}"

if [[  ${login_status_log} =~ "errorMessages" ]]

then

echo "JIRA還未登錄,開始登錄"

curl -c cookie.txt -d "os_username="${os_username}"&os_password="${os_password} -v ${login_api_uri}

cd ${cookie_file_path}

cookieContents=`cat ${cookie_file_path}/cookie.txt | awk -F "[JSESSIONID]" '/JSESSIONID/{print$0}'`

cookieContentsCutOut=$(echo $cookieContents | cut -d '/' -f 2)

JSESSIONID_STRING=$(echo ${cookieContentsCutOut} |tr -d " ")

JSESSIONID=${JSESSIONID_STRING:16}

else

echo "JIRA已經登錄"

fi

}

 

function add_post_build_comments()

{

commentCotents=$1

echo "JIRA_ISSUE_KEY[$JIRA_ISSUE_KEY]..."

echo "開始增加構建後的JIRA日誌信息"

echo "add_post_build_comments參數:"$commentCotents

add_post_build_comments_status_result=`curl --cookie JSESSIONID=${JSESSIONID} --request POST --data '{"body": "'${commentCotents}'"}' --header 'Accept: application/json' --header 'Content-Type: application/json' ${issue_api_uri}/${JIRA_ISSUE_KEY}/comment`

echo "版本分支創建的結果:${add_post_build_comments_status_result}"

if [[  ${add_post_build_comments_status_result} =~ "errorMessages" ]]

then

echo "JIRA 版本分支構建JIRA日誌信息增加失敗"

else

echo "JIRA 版本分支構建JIRA日誌信息增加成功"

fi

}

除此之前還有一鍵狀態更新,一鍵代碼合併等。

總結:雖然作爲後端開發人員可能不太容易,因爲腳本你沒有運維人員熟悉。但是踏踏實實,一步一個腳印,會讓你的知識更加全面。

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