一、概述
通常我們知道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
}
除此之前還有一鍵狀態更新,一鍵代碼合併等。
總結:雖然作爲後端開發人員可能不太容易,因爲腳本你沒有運維人員熟悉。但是踏踏實實,一步一個腳印,會讓你的知識更加全面。