SVN怎么触发Jenkins自动构建
通常,有几种方式可以在SVN仓库发生改变时触发Jenkins进行构建。第一种是,Jenkins主动轮询SVN仓库;第二种是,在SVN客户端(如TortoiseSVN)创建客户端hooks来触发构建;第三种是,在SVN服务器端,创建仓库hooks来触发构建。而我所要介绍的就是这第三种。
在http://svnbook.red-bean.com/en/1.5/svn.reposadmin.create.html#svn.reposadmin.create.hooks这里可以找到如何创建仓库hooks的指导说明。
现在假设,我有一个仓库名为"auto_everything",在SVN管理页面的版本库列表中也可以看到:

登录到SVN服务器上,找到该仓库所在目录(可以用find命令搜一下):

在该仓库目录下,有一个hooks目录,默认情况下该目录下有一些模板文件(.tmpl文件):

SVN的仓库hooks的原理是这样的:当你对该仓库执行一些操作时,比如创建一个新的revision版本或修改一个未版本化的属性,就会触发hooks目录下的相应程序。操作的事件(或时间节点)是跟程序文件名相对应的。举个例子,post-commit,代表,你往该仓库提交完成后,如果此时hooks目录下有一个叫做post-commit的程序文件的话,该程序就会被触发执行。该程序文件可以是任意可执行的程序,比如shell脚本、python脚本、二进制程序等,它需要有可执行权限。
SVN在执行该hooks文件时,同时会传入三个参数:该仓库的路径(REPOS)、修订版本号(REV)、事务名称(TXN_NAME,这个不知道什么鬼,不过也用不上)。在https://wiki.jenkins.io/display/JENKINS/Subversion+Plugin这里可以找到利用post-commit hook来触发Jenkins执行的示例脚本。
|
#!/bin/sh REPOS="$1" # 本仓库的目录路径 REV="$2" # 版本修订号 UUID=`svnlook uuid $REPOS` /usr/bin/wget \ --header "Content-Type:text/plain;charset=UTF-8" \ --post-data "`svnlook changed --revision $REV $REPOS`" \ --output-document "-" \ --timeout=2 \ http://server/subversion/${UUID}/notifyCommit?rev=$REV |
注一:出于安全考虑,SVN在调用hooks程序时是不传入任何环境变量的,包括PATH路径。所以,如果为了方面书写命令,我们我们需要自己设置PATH路径:
|
svn_dir=/home/svn/csvn # SVN安装目录 export PATH=$svn_dir/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin |
注二:注意到rev=$REV参数,这是告诉Jenkins签出该hook程序所报告的那个版本号。如果你的job定义了多个subversion模块位置,这可能会导致签出代码不一致 - 因此那种情况下就推荐你省去 '?rev=$REV' ,这会使得Jenkins签出最新版本的代码。
注三:为了让Jenkins中的job可以被触发,job需要被显式地配置为启用SCM轮询才行,未启用SCM轮询选项的job将不会被post-commit hook所触发。下图为在job中启用SCM轮询的示例:

注四:为了让上面的脚本可以正常工作,Jenkins需要允许匿名用户有读取权限。在"系统管理"→"全局安全配置"中,可以启用:

当然,通常我们的Jenkins会有更加严格的访问权限控制,我们不会这么做。后面会介绍。
注五:如果Jenkins启用了跨站点请求伪造防护(默认启用)选项,那么上面的请求会返回一个403错误("No valid crumb was included")。在"系统管理"→"全局安全配置"中,可以看到跨站点请求伪造防护是否有启用:

为了避免该问题,请求所需的crumb可以从URL地址http://server/crumbIssuer/api/xml (或/api/json)获取到。可以通过在wget请求中添加类似于下面的代码来解决:
|
--header `wget -q --output-document - \ 'http://server/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)'` |
注六:由于wget在给定的超时时间内访问不成功时,它默认会尝试最多20次,--timeout=2在一个性能较差的SVN服务器上可能会导致Jenkins扫描仓库非常多次,进一步减慢了SVN服务器,然后使用Jenkins不响应。对该问题的可能的解决办法是增加超时时间,减小重试次数(如--retries=3),或者在wget命令最后面添加2>&1 &来异步地调用wget(因此忽略了所有的通信错误)。
timeout值太低会导致你的commit操作hang住并抛出502错误(如果你是在一个proxy后面)或post-commit错误。增加超时值,直到你不再看到wget重试,应该可以修复这个问题。
考虑到上面总总情况,实际生产环境中,我建议按照如下操作步骤进行。
1、 首先,在Jenkins中,不要允许匿名用户有读取权限。相反,我们可以登录进去,在用户的设置界面("用户"→ 选择某个用户 →"设置"),找到用户的API Token并记下来,我们后面在程序中可以通过该token来访问Jenkins。你使用的是哪个用户的token,程序就具有那个用户的访问权限。


2、 保持跨站点请求伪造防护为启用。在"系统管理"→"全局安全配置"中,可以设置:

3、 对于需要被post-commit hook所触发的job,要启用它的"Poll SCM"选项:

4、 在SVN服务器上,所选仓库的hooks目录中,创建程序文件post-commit:
|
[root@gw ~]# cd /home/svn/csvn/data/repositories/auto_everything/hooks [root@gw hooks]# touch post-commit [root@gw hooks]# chown svn:svn post-commit # 跟SVN的httpd程序的所属用户相同 [root@gw hooks]# chmod 755 post-commit # 需要有可执行权限 |
我们使用python来编写该程序:
|
[root@gw hooks]# vim post-commit #!/usr/bin/env python # -*- coding: utf-8 -*- import urllib2, sys, os, base64, json # 本仓库的目录路径 repos_path = sys.argv[1] # 版本修订号 revision = sys.argv[2] # svnlook命令所在路径 svnlook = '/home/svn/csvn/bin/svnlook' # Jenkins的地址 baseurl = 'http://172.31.2.8:8080' # Jenkins用户和用户的api token user_id = 'admin' api_token = '0e5127a9b050097b14e72b1485cf5e39' def my_urlopen(url, data=None, header={ }): request = urllib2.Request(url, data) base64string = base64.encodestring('%s:%s' % (user_id, api_token)).replace('\n', '') header['Authorization'] = 'Basic %s' % base64string for key in header: request.add_header(key, header[key]) try: response = urllib2.urlopen(request) except urllib2.URLError as e: print '[Exception URLError]:', e sys.exit(1) else: result = response.read( ) finally: if 'response' in vars( ): response.close( ) return result def main( ): # 获取uuid值 command = r'%s uuid %s' % (svnlook, repos_path) with os.popen(command) as f: uuid = f.read( ).strip( ) # 获取仓库变更信息 command = r'%s changed --revision %s %s' % (svnlook, revision, repos_path) with os.popen(command) as f: data = f.read( ).strip( ) # 获取crumb url = r'%s/crumbIssuer/api/json' % baseurl crumb_dict = json.loads(my_urlopen(url)) # 触发Jenkins url = r'%s/subversion/%s/notifyCommit?rev=%s' % (baseurl, uuid, revision) header={'Content-Type':'text/plain', 'charset':'UTF-8', crumb_dict['crumbRequestField']:crumb_dict['crumb']} my_urlopen(url, data, header) main( ) |
这样就设置好了。可以找一个项目的文件夹,在里面随便新建一个问题,然后提交。如果SVN的post-commit有触发Jenkins进行构建的话,在Jenkins管理页面中就可以看到有job在运行了,在Jenkins的系统日志中也会产生类似下面的信息:
|
[root@gw ~]# tail -n 100 -f /opt/jenkins/jenkins.log Jun 25, 2018 9:03:17 AM jenkins.scm.impl.subversion.SubversionSCMSource$ListenerImpl onNotify INFO: Received post-commit hook from 7c771039-8f78-4126-8c20-220196ed6f6c for revision 21 on paths [example-pipeline/test.txt] Jun 25, 2018 9:03:17 AM jenkins.scm.impl.subversion.SubversionSCMSource$ListenerImpl onNotify INFO: No subversion consumers for UUID 7c771039-8f78-4126-8c20-220196ed6f6c Jun 25, 2018 9:03:18 AM hudson.triggers.SCMTrigger$Runner run INFO: SCM changes detected in example-pipeline. Triggering #4 Jun 25, 2018 9:03:33 AM org.jenkinsci.plugins.workflow.job.WorkflowRun finish INFO: example-pipeline #4 completed: SUCCESS |
实际生产环境中,一个SVN仓库可能会存放有多个项目,对应多个Jenkins job。但经过测试,发现没有任何问题。当我们将修改提交到SVN仓库中时,只有那些文件有变动的项目对应的job才会被触发。这可能是Jenkins有检查,每一次变动都涉及到哪些文件,跟现有job的SVN源码路径是否匹配,如果有匹配到,才会触发这个job。不过需要注意的是,不管是新增文件还是删除文件,只要项目文件发生变动,都会触发项目的job进行自动构建的。
SVN怎么触发Jenkins自动构建的更多相关文章
- Gitlab源码库里代码提交后,如何触发jenkins自动构建?
版本库里代码提交后,如何触发jenkins自动构建?这是一个面试题,感觉自己回答的并不好,因为并没有用过这个功能,之前公司实际项目用的是svn版本管理,一般都用立刻构建,和定时任务构建(不管代码是否有 ...
- 实战:向GitHub提交代码时触发Jenkins自动构建
当我们提交代码到GitHub后,可以在Jenkins上执行构建,但是每次都要动手去执行略显麻烦,今天我们就来实战Jenkins的自动构建功能,每次提交代码到GitHub后,Jenkins会进行自动构建 ...
- 六、配置github的pull request触发jenkins自动构建
之前的配置,都是向master分支push操作触发jenkins进行构建,但是在一般的正常工作中,不会允许程序员直接向主分支推送代码:正常都是fork一个本地的分支,在本地分支调试完后,向主干分支提交 ...
- 配置github的pull request触发jenkins自动构建
参照: https://www.cnblogs.com/zanjiahaoge666/p/6402738.html 之前的配置,都是向master分支push操作触发jenkins进行构建,但是在一般 ...
- gitlab实现webhook触发jenkins 自动,构建,测试,push webhook构子 总结
最新一直在学习 工作 + 学习 去掉 90% 所以blog 一直没更 真是很不好! exsi ceph gitlab jenkins harbor k8s docker-compose ap ...
- 通过gitlab的webhook触发Jenkins自动构建设置
1.Jenkins job中勾选Build when a change is pushed to GitLab 2.Gitlab project 页面setting选择Integrations,配置w ...
- 如何创建一个项目,让gitlab自动触发jenkins进行构建
前进是:你已经配置好jenkins+gitlab自动化布置了,这里只是常规构建新的项目时,需要做的配置,记录下来,以免忘了又着急 参考这篇博客: https://www.jianshu.com/p/e ...
- 使用Docker+Jenkins自动构建部署
环境 Windows 10 Docker Version 18.06.1-ce-win73 (19507) 运行jenkins 运行jenkins 容器 docker run -d --name ln ...
- Gitlab使用Webhook实现Push代码后的jenkins自动构建
本文出自https://www.cnblogs.com/kevingrace/p/6479813.html 怕以后找不到,所以先写到自己博客中 Gitlab利用Webhook实现Push代码后的jen ...
随机推荐
- 如何利用Power BI 制作动态搜索界面
最近Power BI有了最新更新,想着利用 Power BI 工具制造一个动态的搜索界面,比如动态切换搜索引擎,分别从百度.360.搜狗等搜索苹果最新新闻.通过一番测试,最终实现了相关功能. 数据加载 ...
- elk的安装部署
Elk日志安装文档 需要用到有三个软件包 和redis 分布式部署:已上图就是分布式部署的架构图 Logstash : 是部署在前台的应用上,收集数据的 和部署在redis和elasticsea ...
- verilog实现中值滤波
前言 项目需要,想要实现算法中的其中一步即中值滤波,同时,因为图像处理部分中值滤波相对来说还是比较简单的,将中值滤波的硬件实现作为进入FPGA领域的第一次尝试.虽然说网上有较多关于中值滤波的文档,可是 ...
- 前端解析websocket数据问题
buf []byte //err = websocket.Message.Send(ws, buf) err = websocket.Message.Send(ws, string(buf[:])) ...
- 【BZOJ1202】【HNOI2005】狡猾的商人
查分约束好,好写好调好AC! 原题: 刁姹接到一个任务,为税务部门调查一位商人的账本,看看账本是不是伪造的.账本上记录了n个月以来的收入情况,其中第i 个月的收入额为Ai(i=1,2,3...n-1, ...
- whistle.js连接ios手机中https步骤
1:对于安卓直接扫码安装https的证书: 对于ios 连接电脑发出的wifi,打开whistle,配置代理之后(一定要保证先链接电脑发出的wifi,且配置代理) 用Safari打开网址:http: ...
- scala学习笔记-面向对象编程之Trait
将trait作为接口使用 1 // Scala中的Triat是一种特殊的概念 2 // 首先我们可以将Trait作为接口来使用,此时的Triat就与Java中的接口非常类似 3 // 在triat中可 ...
- 内置函数——filter和map
filter filter()函数接收一个函数 f 和一个list,这个函数 f 的作用是对每个元素进行判断,返回 True或 False , filter()根据判断结果自动过滤掉不符合条件的元 ...
- tile38 一款开源的geo 数据库
tile38 是基于golang 编写的geo 数据库,支持地理空间索引.实时地理围栏,同时也支持leader-flower 的部署模型 备注: 下边测试一个简单的地理围栏功能 环境准备 docker ...
- 【甘道夫】MapReduce实现矩阵乘法--实现代码
之前写了一篇分析MapReduce实现矩阵乘法算法的文章: [甘道夫]Mapreduce实现矩阵乘法的算法思路 为了让大家更直观的了解程序运行,今天编写了实现代码供大家參考. 编程环境: java v ...