一、概述

通常我们知道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:$jenkins_password@gitlab.youxinsign.com/two/${project_name}.git $CLONE_ADDRESS

git clone http://$jenkins_name:$jenkins_password@gitlab.youxinsign.com/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 root@132.124.2.10"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 root@132.124.2.10 "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

}

除此之前还有一键状态更新,一键代码合并等。

总结:虽然作为后端开发人员可能不太容易,因为脚本你没有运维人员熟悉。但是踏踏实实,一步一个脚印,会让你的知识更加全面。

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐