Augment实战-编写生产环境CICD脚本
一、背景
公司现有的CICD脚本(用于研发快速打包部署)太多了,开发环境一套、测试环境一套、生产环境一套、项目环境七八套,每个工程一套, 99%是重复的CICD代码,来一个环境就拷贝一份出来修改下,这样可维护性有点差。
准备重新调整下,把通用的功能抽出来,环境参数(测试、生产、项目)使用配置文件配置就行了。
二、实战
直接上提示词:
现有的这些CICD功能,我发现功能通用性还不是很强,比如现在只仅限于测试环境,也限于一个工程,我要实现一个通用的CID功能,帮我实现下,功有和要求包括以下:
1、配置和功能分离,配置项包括:
- 项目工程(gitlab库)可配置
- 项目子工程可配置
- 项目分支可配置
- 是否打镜像或者重启远程服务,可配置(现在通过jenkins参数传递)
- 版本号可配置
- 镜像库推送地址和账号可配置
- 镜像名和镜像版本号可配置
以上这些部分后期也可能都通过jenkins参数传递。
2、配置、功能、业务代码分离
- 配置放专门的配置文件目录下,方便增加或修改
- 功能主要包括更新代码、编译、打镜像、重启远程服务
- 代码放到对应的代码目录,不混到cicd脚本目录
3、CICD目录规范
- CICD目录,即当前要写的脚本目录,我已经在本工程cicd-sh/ 下面新建了一个common目录和关键配置文件,包含:
- backend 后端服务目录
- config 环境配置信息目录
- test 测试环境目录
- test.env 测试环境通用配置,比如JAVA_HOME位置、GIT_BRANCH默认代码分支、更新代码到本地服务器目录位置、推送镜像库地址账号密码、镜像版本、IS_PROD是否生产环境等
- project-a 某一个gitlab库(项目)工程配置目录
- sub-project-a.env 一个sub-project-a子工程的配置
- sub-project-b.env 另一个子工程的配置
- project-b 另一个gitlab库(项目)工程配置目录
- ... 其他更多工程配置目录
- prod 生产环境目录
- cicd.sh jenkins调用的主脚本,读取配置文件、更新代码,调用
- java-compile.sh java代码编译
- push-image.sh 镜像推送
- restart-service.sh 重启远程服务
- front 前端构建脚本目录,后续再开发相关脚本和配置,先忽略
4、 代码目录规范
构建脚本和构建的业务代码分享,把代码放到/root/code目录下面,按这个规范放:
/root/code/{gitlab库名}/{代码分支}/{gitlab库对应的代码}
这个目录规范会影响到CICD里面环境配置信息以及相关的cicd脚本,除了/root/code/目录已经建立,其他目录需要判断和建立
5、这些脚本功能的实现 还是按 jenkins机器(部署jenkins)、脚本执行机器(编译打包机器)、重启远程服务机器(远程是测试环境) 分离调用,不是一台服务器
开始干活
搞完后,基本没什么bug,一个就是路径有点问题,运行了下提示路径找不到,发给它修改下基本上修复了。
接下来遇到一个java工程编译问题:
→ 使用JAVA_HOME: /jdk1.8.0_231
→ 执行: mvn clean install -Pjar -Dmaven.test.skip=true
Unrecognized option: -Pjar
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.
Build step 'Execute shell' marked build as failure
Finished: FAILURE
让它修改,调了一个多小时,都没修复掉,它一直聚焦在JAVA运行环境调整,没办法修复。后来还是自己亲自下手调试,跟踪发现是cicd.sh里面 export MAVEN_OPTS 导致的,MAVEN_OPTS 是环境配置文件.env里面定义为一个字符参数 MAVEN_OPTS=“-Pjar -Dmaven.test.skip=true”,去掉export MAVEN_OPTS就好了,原因刚开始不明白,问了Augument就清楚了:
您提出了一个很好的问题,关于为什么export MAVEN_OPTS="-Pjar -Dmaven.test.skip=true"会导致Unrecognized option: -Pjar错误。
这个问题的原因可能与Java虚拟机(JVM)和Maven的参数处理机制有关:
原因分析
MAVEN_OPTS环境变量的用途:
MAVEN_OPTS环境变量通常用于传递给JVM的参数,而不是传递给Maven本身的参数
当您设置MAVEN_OPTS="-Pjar -Dmaven.test.skip=true"时,这些参数被传递给了JVM而不是Maven
参数传递机制:
-Pjar是Maven的参数,用于激活名为"jar"的profile
-Dmaven.test.skip=true虽然以-D开头,但它既可以被JVM识别(作为系统属性),也可以被Maven识别
当这两个参数通过MAVEN_OPTS传递时,JVM尝试解析-Pjar,但它不认识这个选项,因此报错
正确的参数传递方式:
Maven参数(如-Pjar)应该直接传递给mvn命令
JVM参数(如内存设置-Xmx2g)应该通过MAVEN_OPTS传递
顺便学习了下:MAVEN_OPTS 命名都是MAVEN关键字,怎么会传JVM参数呢? 另外,只要export MAVEN_OPTS就会影响吗? 不一定要mvn install $MAVEN_OPTS 才影响吧?
您提出了两个很好的问题,让我来解释:
1. 关于MAVEN_OPTS命名与用途
尽管名称中包含"MAVEN",但MAVEN_OPTS环境变量的实际用途是传递给JVM的参数,而不是Maven本身的参数。这确实容易造成混淆。
Maven的官方文档明确指出:
MAVEN_OPTS - 包含传递给Java虚拟机的参数,Maven在其中运行。例如,JVM内存设置可以在这里定义,例如export MAVEN_OPTS="-Xmx512m"。
这是因为Maven本身是一个Java应用程序,它运行在JVM上。MAVEN_OPTS环境变量用于配置运行Maven的JVM,而不是Maven的命令行选项。
2. 关于export MAVEN_OPTS的影响
是的,只要export MAVEN_OPTS设置了这个环境变量,它就会影响所有后续在该shell会话中启动的Maven进程,不需要显式地在命令行中使用mvn install $MAVEN_OPTS。
实际上,mvn install $MAVEN_OPTS这种写法是错误的,因为:
当您执行mvn install $MAVEN_OPTS时,shell会将$MAVEN_OPTS的值作为命令行参数传递给mvn命令
但Maven已经自动读取了MAVEN_OPTS环境变量的值并传递给JVM
这导致参数被传递了两次,一次通过环境变量,一次通过命令行
三、结果附件
这个是完整的研发部署的CICD脚本代码,有需要的可以下载下去查看学习下,也可以修改下直接自己拿去用
Jenkins里面按需配置参数(构建时可以使用这些变量):
shell脚本:
ssh -p 22 root@192.168.3.217 "export UPDATE_IMAGE=${UPDATE_IMAGE} && export UPDATE_REMOTE_SERVICE=${UPDATE_REMOTE_SERVICE} && export BRANCH=${BRANCH} && /root/cicd-sh/common/backend/cicd.sh test project-a sub-project-a"
因为我这jenkins机器(部署jenkins)、脚本执行机器(编译打包机器)、重启远程服务机器(远程是测试环境) 分离调用的,所以要带上jenkins参数到export环境变量,如果jenkins安装的服务器和执行构建脚本同一台服务器,就没必要带上export 。