持续集成
为什么会产成持续集成?
由于软件复杂度高,需求变化快
什么叫持续集成?
持续集成简称CI,集成是每个模板集合在一起,如lamp就是把linux,apache,mysql,php结合在一起,当把这些工具集成在一起才会发挥效果,再比如提交测试-拉取代码-执行测试-部署上线,持续集成就是每个环节都自动完成,从而提高效率,它本身并不是一种工具,只是一种理念
集成的条件:
开发环境统一,提交代码频率,必须用版本控制
持续集成组成
git/svn -> CI服务器 -> web服务器
持续集成的优势:
任何时间地点生成部署软件,增加项目的可见性,减低分析,减少重复过程
jenkins
概念:
jenkins是持续集成的工具
安装:
jenkins一般配合tomcat安装,官网下载jenkins.war包放在webapps下
插件:
Git plugin 让jenkins在git仓库中获取最新代码
Deploy to container Plugin 自动部署
邮箱:
我们不使用jenkins自带的邮箱,而是下载插件Email Extension
安装好之后再config中Extended E-mail Notification设置
default context type:模板
QA构建通知:$PROJECT_NAME - Build # $BUILD_NUMBER - $BUILD_STATUS
default recipients:模板1
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>${ENV, var="JOB_NAME"}-第${BUILD_NUMBER}次构建日志</title> </head> <body leftmargin="8" marginwidth="0" topmargin="8" marginheight="4" offset="0"> <table width="95%" cellpadding="0" cellspacing="0" style="font-size: 11pt; font-family: Tahoma, Arial, Helvetica, sans-serif"> <tr> 本邮件由系统自动发出,无需回复!<br/> 各位同事,大家好,以下为${PROJECT_NAME }项目构建信息</br> <td><font color="#CC0000">构建结果 - ${BUILD_STATUS}</font></td> </tr> <tr> <td><br /> <b><font color="#0B610B">构建信息</font></b> <hr size="2" width="100%" align="center" /></td> </tr> <tr> <td> <ul> <li>项目名称 : ${PROJECT_NAME}</li> <li>构建编号 : 第${BUILD_NUMBER}次构建</li> <li>触发原因: ${CAUSE}</li> <li>构建状态: ${BUILD_STATUS}</li> <li>构建日志: <a href="${BUILD_URL}console">${BUILD_URL}console</a></li> <li>构建 Url : <a href="${BUILD_URL}">${BUILD_URL}</a></li> <li>工作目录 : <a href="${PROJECT_URL}ws">${PROJECT_URL}ws</a></li> <li>项目 Url : <a href="${PROJECT_URL}">${PROJECT_URL}</a></li> </ul> <h4><font color="#0B610B">失败用例</font></h4> <hr size="2" width="100%" /> $FAILED_TESTS<br/> <h4><font color="#0B610B">最近提交(#$SVN_REVISION)</font></h4> <hr size="2" width="100%" /> <ul> ${CHANGES_SINCE_LAST_SUCCESS, reverse=true, format="%c", changesFormat="<li>%d [%a] %m</li>"} </ul> 详细提交: <a href="${PROJECT_URL}changes">${PROJECT_URL}changes</a><br/> </td> </tr> </table> </body> </html>
模板2:
(本邮件是程序自动下发的,请勿回复!)<br/><hr/> 项目名称:$PROJECT_NAME<br/><hr/> 构建编号:$BUILD_NUMBER<br/><hr/> 构建状态:$BUILD_STATUS<br/><hr/> 触发原因:${CAUSE}<br/><hr/> 构建日志地址:<a href="${BUILD_URL}console">${BUILD_URL}console</a><br/><hr/> 构建地址:<a href="$BUILD_URL">$BUILD_URL</a><br/><hr/> 变更集:${JELLY_SCRIPT,template="html"}<br/><hr/>
打开更多设置
之后点击保存,在具体项目中设置,选择构建后操作,在triggers中选择选择failure-any表示失败后都发送邮件,再选择recipient list,这是我们刚刚选择的邮件发送人,之后点击保存
jdk配置
进入全局工具配置
git配置
maven配置
其他软件插件也是差不多的
jenkins添加用户管理
jenkins定时任务 在jenkins中构建触发器的定时构建中,填写触发器规则,类似于linux的crontab定时任务
字段 | * | * | * | * | * |
含义 | 分钟 | 小时 | 天 | 月 | 星期 |
0-59 | 0-23 | 1-31 | 1-12 | 1-7 | |
每隔15分钟执行一次 | H/15 | * | * | * | * |
每天凌晨2点执行一次 | H | 2 | * | * | * |
每隔2小时执行一次 | H | H/2 | * | * | * |
每隔3天执行一次 | H | H | H/3 | * | * |
每隔1周执行一次 | H | H | H | * | H/1 |
每隔一个月执行一次 | H | H | H | H/1 | H |
每天9,5点执行一次 | H | 0,9,5 | * | * | * |
每天早上8点到晚上10点每三个小时执行一次 | H | 8-10/3 | * | * | * |
每周的1,3,5执行一次 | H | H | * | * | 1,3,5 |
规则 | |||||
H | 形参 | ||||
指定时间范围 | a-b | ||||
指定时间间隔 | / | ||||
指定变量取值 |
a,b,c |
jenkins远程触发器(通过url地址触发构建)
只要访问这个url地址就可以触发构建等操作 格式为jenkins_Url/job/test(webapps的项目名称)/build?token=token_name(具体指就是下方的身份验证令牌)
钩子程序触发构建(linux命令触发构建)
curl命令
指定请求方式,在linux中内置 -X参数 指定请求方式,-v参数 显示响应结果,-u参数 携带用户名/密码,-H参数 携带请求消息头信息
curl -X post -v -u jenkins登录用户名:登录密码 jenkins_Url/job/test(构建的项目名称)/build?token=token_name(具体指就是下方的身份验证令牌)
坑:
我尝试在服务器访问 curl -X POST -v -u root:xS(AD(*xxx! http://127.0.0.1:93/jenkins/job/test/build?token=ASDAaKSLJD,返回401多次百度还是不能解决问题
* About to connect() to 127.0.0.1 port 93 (#0) * Trying 127.0.0.1... * Connected to 127.0.0.1 (127.0.0.1) port 93 (#0) * Server auth using Basic with user 'root' > POST /jenkins/job/test/build?token=ASDAaKSLJD HTTP/1.1 > Authorization: Basic cm9vdDpDenkxMjM0Y2xlYXI= > User-Agent: curl/7.29.0 > Host: 127.0.0.1:93 > Accept: */* > < HTTP/1.1 401
我尝试把密码输错发现也返回这个错误,于是我加了引号莫名其妙就好了 curl -X POST -v -u root:'xS(AD(*xxx!' http://127.0.0.1:93/jenkins/job/test/build?token=ASDAaKSLJD
* About to connect() to 127.0.0.1 port 93 (#0) * Trying 127.0.0.1... * Connected to 127.0.0.1 (127.0.0.1) port 93 (#0) * Server auth using Basic with user 'root' > POST /jenkins/job/test/build?token=ASDAaKSLJD HTTP/1.1 > Authorization: Basic cm9vdDpDenkxMjM0ISE= > User-Agent: curl/7.29.0 > Host: 127.0.0.1:93 > Accept: */* > < HTTP/1.1 201
svn添加钩子程序 在 svn目录/hook/post-comit文件中添加方面的curl命令 chmod755权限,重启svn即可
git添加钩子程序,在git账户设置中webhook的payload_url中添加上面的curl命令,点击add webhook,在jenkins配置中csrf Protect跨站点请求打勾取消即可
坑:
使用钩子程序一个月了,开发在服务器改了代码,导致代码与svn服务器冲突,这怎么办呢,找到svn的构建
1、Use‘svn update’ as much as possible 第一次发布的时候,会把工作目录下的所有文件清空,然后check-out一份完整的项目到工作目录下; 以后更新的时候,不会判断已有文件是否在svn里存在。比如工作目录下的文件123在svn里不存在,那么更新的时候不会删除123。 不会判断工作目录下的文件是否被改动,只会判断svn是否有新版本需要更新。比如工作目录下的文件zzz.txt内容为zzz,svn上的zzz.txt内容为空,如果svn上zzz.txt没有新版本,则在更新的时候不会更新zzz.txt,也就是说如果手动修改了工作目录下的文件,如果此文件在svn上没有出现新版本,就不会更新。一旦svn上的zzz.txt有新版本后就会更新工作目录的zzz.txt,这时工作目录下会生成如下几个文件:zzz.txt、zzz.txt.mine、zzz.txt.r223、zzz.txt.r224,其中zzz.txt.r223为svn上老版本、zzz.txt.r224为svn上新版本、zzz.txt.mine为工作目录上的zzz.txt的副本、zzz.txt记录了文件变化。 svn上删除了文件,更新的时候,工作目录里的此文件也会被删除。但是如上例中的zzz.txt手动修改过,已经和svn上的不一样了,这时将不会被删除。 2、Alwayscheck out a fresh copy 第一次发布的时候,会把工作目录下的所有文件清空,然后check-out一份完整的项目到工作目录下; 每一次更新的时候,都会先清除工作目录下的所有文件,然后重新check-out一份完整的项目到工作目录下。 3、Emulateclean checkout by first deleting unversioned/ignored files,then ‘svn update’ 第一次发布的时候,会把工作目录下的所有文件清空,然后check-out一份完整的项目到工作目录下; 以后更新的时候会判断工作目录下的文件是否在svn里存在,如果不存在则删除,如果存在且有新版本则更新。 会判断工作目录下的文件是否被改动,不管有没有新版本,都会还原为svn上的最新版本。 svn上删除了文件,更新的时候,工作目录里的此文件也会被删除。 4、Use‘svn update’ as much as possible,with ‘svn revert’ before update 第一次发布的时候,会把工作目录下的所有文件清空,然后check-out一份完整的项目到工作目录下; 以后更新的时候不会判断工作目录下的文件是否在svn里存在。 会判断工作目录下的文件是否被改动,不管有没有新版本,都会还原为svn上的最新版本。 svn上删除了文件,更新的时候,工作目录里的此文件也会被删除。
参考 https://www.cnblogs.com/cheyunhua/p/8241903.html
jenkins构建超时插件
在我们编译或者请求服务器可能会出现超时,或者是系统bug导致请求堵塞,查看jenkins时会发现构建进度条变成红色,卡在一半的位置,这样导致不能及时反馈问题,jenkins自带的超时插件可以帮我们解决这样的问题
python操作jenkins
#首先安装 pip install jenkinsapi
#官方文档 https://jenkinsapi.readthedocs.io/en/latest/index.html
from jenkinsapi.jenkins import Jenkins j = Jenkins('http://xxx.xxx.x.x/jenkins', username='root', password='123456') print(j.version) # 返回服务器jenkins版本号 print(j.keys())#返回项目以列表形式返回 obj = j['你的项目名字'] #可以使用Job类方法 print(obj.get_last_good_build())#返回构建名称和最新构建号 print(obj.get_build_dict())#返回该构建的所有构建号和构建url以字典形式返回 #print(obj.get_config())#返回该作业的config.xml文件内容 #obj.delete_build(1)#删除指定构建号,参数为构建号 print(obj.get_description())#返回工作的描述信息 print(obj.get_last_completed_build())#不管状态如何,获得最后一个构建的构建名和构建号 print(obj.get_params())#获取参数 print(obj.has_params())#查看工作是否有参数,返回布尔值 print(obj.has_queued_build(2193))#查看当前列队中是否有构建号,返回布尔值 print(obj.is_running())#查看当前工作是否正在工作,返回布尔值 print(obj.is_enabled())#查看构建是否成功,返回布尔值 print(obj.is_queued())#查看当前工作是否在列队中,返回布尔值 print(obj.is_queued_or_running())#查看当期那工作是否在列队或者是否在工作中,返回布尔值 print(obj.poll())#返回一个大字典,包括了该工作的状态等信息 # print(obj.enable())#恢复该工作 # print(obj.disable())#禁用该工作 print(obj.get_full_name())#使用API返回作业的全名称 #jenkins类方法 print(j.get_job('kaidan'))#返回工作名称 j.get_jobs_info()#返回所有作业的地址路径和作业名称,返回一个生成器对象 j.create_job('name',xml)#创建job print(j.base_server_url())#返回jenkins的项目地址 print(j.build_job('项目名'))#按作业名称调用构建,传入工作名称,返回None import jenkinsapi print(jenkinsapi.__version__) # 查看jenkinsapi库版本 api=jenkinsapi.jenkins.Jenkins('http://xxx.xxx.xxx.x:8080/jenkins', username='root', password='123456') jobs = api.get_jobs_list()#获取所有job的列表 args = ["http://xxx.xxx.xxx.x:8080/jenkins",'test' ] kwargs = {"username":'root',"password":'123456'} #res = jenkinsapi.api.block_until_complete(*args,**kwargs)#等待列表中所有工作都完成,都完成了返回None print(jenkinsapi.api.get_artifacts(*args, **kwargs))#查找作业的最新构建的所有构件 print(jenkinsapi.api.get_build(*args,**kwargs))#一个方便的函数,可以根据构建号从jenkins作业中获取测试结果 res = jenkinsapi.api.get_latest_build(*args, **kwargs)#获取最新的测试结果 print(res.get_status())#获取构建结果,如FAILURE print(res.baseurl)#返回构建url res.get_console()#返回控制台输出结果,返回中文时可以能是乱码 需要在get_console中修改return content.decode('utf8')
#还有一个是python-jenkins
pip install python-jenkins,随便选哪个api框架都行
官方文档: https://python-jenkins.readthedocs.io/en/latest/api.html
jenkins获取用户root权限
起初是jenkins通过shell执行脚本时会报出Operation not permitted,原因是jenkins不是超级用户权限,当然不能修改删除一些东西,如果我们要强行添加root权限方便后续操作需要修改配置
vim /etc/sysconfig/jenkins JENKINS_USER="root" #修改或者添加这一行,并保存 #为jenkins添加权限 chown -R root:root /var/lib/jenkins chown -R root:root /var/cache/jenkins chown -R root:root /var/log/jenkins #重启jenkins service jenkins restart #查看jenkins进程为root启动表示成功 ps -ef | grep jenkins
jenkins时区时间问题
出现外国时间时只需要一行命令就可以解决
在系统管理-》脚本命令行中输入
System.setProperty('org.apache.commons.jelly.tags.fmt.timeZone', 'Asia/Shanghai')
版权声明:本文原创发表于 博客园,作者为 RainBol 本文欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则视为侵权。
每天凌晨2:00跑一次