本文简单讲解一个springboot项目如何通过PR将开发分支代码合并到master分支上,并触发流水线进行maven构建后部署主机的流程
以一个项目的master和dev分支为例,master作为主要分支,也是部署生产环境的分支,dev是开发新功能时基于master分支创建的。当功能开发完成且测试后没问题,就需要合并到master分支上。
- 开发人员接到新需求,基于master创建开发分支dev
- 功能开发好后,需要将dev分支上的代码发布到测试环境
- 创建PR,将dev分支的代码部署到测试环境上
- PR测试并审查通过,自动合并到master分支上,并部署到生产环境
创建PR
- 源分支即为新功能dev分支,需要合并到目标分支master上
- PR标题可根据功能名称进行填写
- 一般审查和测试通过后,PR进行关闭,同时关联的工作项也可一起关闭;至于是否需要删除分支则根据自己的情况;squash merge可以使每个被合并的分支在develop上就只有一个commit,方便该功能的回退
创建PR流水线
当我们本地将dev分支上的代码上传到gitee上dev分支后,需要将此时dev上的分支打包部署到测试环境上进行测试
- 点击并创建流水线
-
这里勾选Pull Request事件,分支匹配填入master。这时只要代码评审中有目标分支为master的,并且源分支有提交,就会触发这个流水线
-
流水线任务编排,进行maven打包构建。添加Java构建上传阶段
- 点击新任务,使用maven构建
- 配置maven构建信息
这里说下构建命令和构建存物
-
构建命令这里使用的是:先clean 然后 package 并且跳过测试
mvn -B clean package -Dmaven.test.skip=true -Dautoconfig.skip
-
构建物唯一标识指的是maven打包并压缩后的文件名,用于下一步主机部署时上传,会自动压缩为.tar.gz结尾的压缩包。这里可以随便填写
-
打包文件/目录指的是maven打包后需要去哪个文件夹下找个哪个文件进行打包,因为maven项目打包后jar包都是存在target目录下,所以这里指定为target/git_test.jar
- 主机部署
上一阶段构建成功后,就需要部署到主机上并开始运行项目了
- 执行主机组选择你的测试服务器
- 部署文件名就是上一阶段的构建物唯一标识
- 下载路径指的是需要将构建物放到你服务器上的哪个文件夹下
- 文件来源选择上游构建产出
- 选择对应的上传文件
- 部署脚本:上面操作执行完后,你的对应服务器目录下应该有个git_test.tar.gz文件。这里需要编写shell脚本来将服务运行起来,可参考下面
# 将压缩包解压
tar -zxvf /app/person/git_test/git_test.tar.gz -C /app/person/git_test
# 进入到jar目录
cd /app/person/git_test
# 停止服务,运行服务前先将正在跑的服务kill掉
PID=$(ps -ef | grep git_test.jar | grep -v grep | awk '{ print $2 }')
if [ -z "$PID" ]
then
echo Application is already stopped
else
echo kill -15 $PID
kill -15 $PID
echo Application is stopped
fi
# 启动服务
nohup java -jar git_test.jar >/dev/null 2>&1 &
7. 保存流水线
这里需要注意的是要将流水线保存到master分支上,因为触发的是目标源为master的分支
创建合并流水线
当代码被测试和评审通过之后,会自动merge到master分支上
- 创建流水线,事件监听选择push事件,分支匹配选择master。接下来的操作跟pr流水线一致,不再说明
可能存在的问题
以下列举出我在部署流水线中遇到的问题
- 由于项目中使用了rt.jar和jcr.jar,而jdk1.7之后这两个包就不在jdk的lib中了(在jre的lib下),所以maven中多了这么一行配置
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<compilerArgs>
<!-- 过期的方法的警告-->
<arg>-Xlint:deprecation</arg>
</compilerArgs>
<compilerArguments>
<!-- 是否输出所有的编译信息(包括类的加载等)-->
<!--<verbose />-->
<!-- 解决maven命令编译报错,因为rt.jar 和jce.jar在jre的lib下面,不在jdk的lib下面,
导致maven找不到(java7以后会出现这个问题),将这2个jar包拷贝到jdk的lib下面估计也好使-->
<bootclasspath>${java.home}\lib\rt.jar${path.separator}${java.home}\lib\jce.jar</bootclasspath>
</compilerArguments>
</configuration>
</plugin>
而gitee的流水线配置中没有java.home这个环境变量,会导致在maven构建阶段提示
fatal error: unable to locate package java.lang in classpath or bootclasspat
所以需要将 java.home 改成 JAVA_HOME ,JAVA_HOME这个变量是存在的
改动之后的maven配置为
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<compilerArgs>
<!-- 过期的方法的警告-->
<arg>-Xlint:deprecation</arg>
</compilerArgs>
<compilerArguments>
<!-- 是否输出所有的编译信息(包括类的加载等)-->
<!--<verbose />-->
<!-- 解决maven命令编译报错,因为rt.jar 和jce.jar在jre的lib下面,不在jdk的lib下面,
导致maven找不到(java7以后会出现这个问题),将这2个jar包拷贝到jdk的lib下面估计也好使-->
<bootclasspath>${JAVA_HOME}/jre/lib/rt.jar${path.separator}${JAVA_HOME}/jre/lib/jce.jar</bootclasspath>
</compilerArguments>
</configuration>
</plugin>
最后,如果你本地idea没有配置maven的${JAVA_HOME}变量,也会提示这个错误,进行如下配置即可