一.简介

都是在推送代码后,再切换到Jenkins界面,手动点击构建。显然不够自动化,应该让每次代码变动后,就自动进行构建才对。对于pipeline触发条件,一般从时间触发和事件触发。

二.时间触发

时间触发是指定义一个时间,时间到了就触发pipeline执行。在pipeline中,使用trigger指令来定义时间触发,只能定义在pipeline块下。支持cron pollSCM upstream三种方式。其它方式可以通过插件来实现。

定时触发

定时执行就像cronjob,一到时间点就执行。它的使用场景通常是执行一些周期性的job,比如每晚构建。

pipeline {
    agent any
    triggers {
        cron('0 0 * * *')
    }
    stages {
        stage('Nightly build') {
            steps {
                echo "这是一个耗时的构建,每天凌晨执行"
            }
        }
    }
}

Jenkins tigger cron语法采用UNIX cron语法(有细微差别)。一条cron包含5个字段,使用空格或者Tab分隔,格式为:分,时,日,月,周

  • MINUTE:一小时内的分钟,取值范围为0~59
  • HOUR:一天内的小时,0~23
  • DOM:一个月的某几天,1~31
  • MONTH:月份,取值1~12
  • DOW:星期几,取值0~7 0和7代表周日

还可以使用以下特殊字符,一次性指定多个值

  • *匹配所有
  • M-N,匹配M到N之间的值
  • M-N/X or */x  指定到N范围内,以X值为步长
  • A,B,...,Z 使用逗号枚举多值

在一些大型组织中,会同时存在大量的同一时刻执行的定时任务,比如N个半夜零点 0 0 * * * 执行的任务。这样会产生负载不均衡。在Jenkins tigger cron语法中使用H字符来解决这一问题,H代表hash。对于没必要精确到零点0分执行的任务,cron可以这样写: H 0 * * *,代表零点0分支59分之前任何一个时间点执行。

需要注意的是,H应用在DOM,一个月的某一天字段时会有不准确的情况,因为10月有31天,而2月却是28天。

Jenkins trigger cron还设计了一些人性化的别名:@yearly、@annually、@monthly、@weekly、@daily、@midnight和@hourly。

例如@hourly与 H * * * *相同,代表一小时内的任何时间;@midnight实际上代表在半夜12:00到凌晨2:59之前的某个时间。其它别名很少有应用场景。

轮询代码仓库

轮询代码仓库是指定期到代码仓库询问代码是否有变化,如果有变化就执行。有读者会问:那多久轮询一次?笔者的回答是:越频繁越好。

因为构建的间隔时间越长,在一次构建内就可能会包含多次代码提交。当构建失败时,你无法马上知道那一次代码提交导致了构建失败。总之,越不频繁集成,得到的持续集成的好就越少。

triggers {

    pollSCM('H/1 * * * *')

}

这种一般用于特殊情况,比如外网的代码仓库无法调用内网的jenkins。则需要用这种方式。

三.事件触发

事件触发就是发生了某个事件就触发pipeline执行,这个事件可以是你能想到的任何事件,比如手动在界面上触发、其它job主动触发、HTTP API Webhook触发等。

由上游任务触发

当B任务的执行依赖A任务的执行结果时,A就被称为B的上游任务。

在Jenkins 2.22及以上版本中,trigger指令开始支持upstream类型的触发条件。upstream的作用就是能让B pipeline自行决定依赖哪些上游任务。

triggers {
    upstream(upstreamProjects: 'job1,job2', threshold: hudson.model.Result.SUCCESS)
}

当upstreamProjects参数接收多个任务时,使用逗号分隔。threshold参数是指上游任务的执行结构是什么值时触发。hudson.model.Result是一个枚举,包括以下值:

  • ABORTED 任务被手动中止
  • FAILURE 构建失败
  • SUCCESS 构建成功
  • UNSTABLE 存在一些错误,但不至于构建失败
  • NOT_BUILT 在多阶段构建时,前面阶段的问题导致后面阶段无法执行

注意:这种需要手动构建当前任务一次,让jenkins加载pipeline后,trigger指令才生效

gitlab通知触发

gitlab通知触发是指当gitlab发现源代码有变化时,触发jenkins执行构建。

由gitlab主动通知进行构建的好处是显而易见的,这样很容易就解决了我们之前提到的轮询代码仓库时“多久轮询一次”的问题,实现每一次代码变化都对应一次构建。

1.安装jenkins插件

安装Generic Webhook Trigger Plugin、git、Gitlab API Plugin、GitLab Plugin插件,注意不是gitlab hook插件(已废弃)

2.在gitlab创建一个项目,test-a,地址http://1.1.1.1/book/test-a

3.在jenkins上创建pipelien项目,可以同名称test-a。正常在不使用pipeline进行这个触发配置的时候,也可以用页面进行配置,勾选相当于开始接收外界发来的请求。

这里要注意,上面标注的URL是固定输出的信息,实际项目地址要看WEB栏,这个才是真实地址的

4.生成个人API的Token,用于安全验证

5.在gitlab项目的设置里,配置钩子

URL填入如下

http://账号名:刚才生成的Token@Jenkins的地址/job/test-a/build?job=test-a&token=随机写个项目token,这里随便打

URL直接粘贴了我的

http://zhuhaoran:119db4649f157c0a25f7d2b541d3f4d7da@10.0.12.9:8080/job/test-a/build?job=test-a&token=t8vcxwuza023ehzcftzr5a74vkpto6xr

现在网络上可能有各种配置,可能老版本适用,但我用的2.220就各种用不了,最后从官网找到这个能用的配置。

为什么这么配置:

gitlab代码有更新,就会通过上面这个url,将一些请求和相关内容通过post方式传给Jenkins。Jenkins发现你的test-a项目开启了这个触发功能,就会根据pipeline的配置进行相应处理,符合条件后就会触发执行。

如果只粘贴Jenkins web配置中显示的地址+Token,会报错403问题。这是因为如果没指定账号密码,gitlab只能通过匿名用户去访问Jenkins去传参。

但现在大多全局安全配置里,是Role-Based Strategy插件方式管理的

往上都说403要这样,我感觉是真的蠢,这样会不安全,而且插件管理和这个只能选择一个。

6.编写pipeline,要保存执行一下这个job让配置生效,具体的参数含义在末尾

pipeline {
agent any triggers {
gitlab(triggerOnPush: true,
triggerOnMergeRequest: true,
branchFilterType: "All",
secretToken: "t8vcxwuza023ehzcftzr5a74vkpto6xr")
} stages {
stage('pull') {
steps {
echo '拉取代码'
}
}
}
}

会发现这里自动勾上了,这是因为pipeline其实就是配置的这个选项,但版本化管理会更好。

7.在gitlab上点击一下触发,看是否jenkins job被触发了

8.然后在gitlab项目中,随意修改个文件,看是否也能自动触发

9.参数含义

triggerOnPush: 当Gitlab触发push事件时,是否执行构建

triggerOnMergeRequest: 当Gitlab触发mergeRequest事件时,是否执行构建

branchFilterType: 只有符合条件的分支才会触发构建,必选,否则无法实现触发。
All: 所有分支
NameBasedFilter: 基于分支名进行过滤,多个分支名使用逗号分隔
includeBranchesSpec: 基于branchFilterType值,输入期望包括的分支的规则
excludeBranchesSpec: 基于branchFilterType值,输入期望排除的分支的规则
RegexBasedFilter: 基于正则表达式对分支名进行过滤
sourceBranchRegex: 定义期望的通过正则表达式限制的分支规则 secretToken: 指定这个job_name的token验证字符

如果只允许master分支push后才触发,就如下配置,token使用了全局变量,这样多个项目都可以用一个token,比较方便(内网比较适合)

triggers {
gitlab(triggersOnPush: true,
triggersOnMergeRequest: true,
branchFilterType: "NameBasedFilter",
includeBranchesSpec: "master",
secretToken: "${env.git_token}")
}

用正则匹配,适合对分支号进行规则定义的项目

triggers {
gitlab(triggersOnPush: true,
triggersOnMergeRequest: true,
branchFilterType: "RegexBasedFilter",
sourceBranchRegex: "dev.*",
secretToken: "${env.git_token}")
}

四.通用触发接口

GWT

前文中,我们讲到安装GitLab插件后,GitLab系统就可以发送Webhook触发Jenkins项目的执行。那是不是说其他系统想触发Jenkins项目执行,也需要找一个插件或者开发一个插件来实现呢?

有了Generic Webhook Trigger插件就不需要了,安装Generic Webhook Trigger插件(下文使用GWT简称)后, Jenkins会暴露一个API: <JENKINS URL>/generic-webhook-triggerlinvoke,即由GWT插件来处理此API的请求。

GWT插件接收到JSON或XML的HTTP POST请求后,根据我们配置的规则决定触发哪个Jenkins项目。下面我们先感受一下,然后再详细介绍GWT各参数的含义,现在我们创建一个普通的pipeline项目。

代码如下:

pipeline {
agent any
triggers {
GenericTrigger(
genericVariables:[
[key: 'ref', value: '$.ref']
],
token:'secret',
causeString: 'Triggered on $ref',
printContri butedVariables: true,
printPostContent: true
)
}
stages {
stage('Some step') {
steps {
sh "echo $ref"
sh "printenv"
}
}
}
}

执行一次job后才会生效,然后发起一次HTTP POST请求

curl -X POST -H "Content-Type: application/json" -d '{ "ref": "refs/heads/master" }' -vs http://192.168.23.11:8667/jenkins/generic-webhook-trigger/invoke?token=secret

接着,我们就看到pipeline被触发执行了。日志如下:

Triggered on refs/heads/master
省略git操作细节部分
Seen branch in repository origin/dev
Seen branch in repository origin/ master
Seen 2 remote branches Obtained Jenkinsfile from 6b2c6a36ac5fade7448596a5fc67ee33be4bab95
Running in Durability level: MAX_ SURVIVABILITY
Generi cWebhookEnvironmentContributor
Received :
{ "ref": "refs/heads/master" }
Contributing variables:
ref = refs/heads/master

GenericTrigger触发条件由GWT插件提供。此触发条件可以说是GWT的所有内容。将GenericTrigger触发条件分为5部分,这样更易于理解各参数的作用。

  • 从HTTP POST请求中提取参数值
  • token,GWT插件用于标识Jenkins项目的唯一性
  • 根据请求参数值判断是否触发Jenkins项目的执行
  • 日志打印控制
  • Webhook响应控制

提取参数

一个HTTP POST请求可以从三个维度提取参数,即POST body、URL参数和header。

GWT插件提供了三个参数分别对这三个维度的数据进行提取。

  1. genericVariables :提取POST body中的参数。
genericVariables:[
[key: 'ref', value: '$.ref'] ,
[key: 'before'
value: ' $.before',
expressionType:' JSONPath
regexpFilter:
defaultValue:
]
]
  • value: JSONPath表 达式,或者XPath 表达式,取决于expressionType参数值,用于从POST body中提取值。
  • key :从POST body中提取出的值的新变铭,可用于pipeline其他步骤。
  • expressionType :可选, value的表达式类型, 默认为JSONPath。当请求为XML内容时,必须指定XPath值。
  • defaultValue:可选,当提取不到值,且defaultValue不为空时,则使用defaultValue作为返回值。
  • regexpFilter :可选,过滤表达式,对提取出来的值进行过滤。其实就是string.replaceAll ( regexpFilter ,"");。string是从HTTP请求中提取出来的值。

2.genericRequestVariables :从URL参数中提取值。

  • key :提取出的值的新变量名,可用于pipeline其他步骤。
  • regexpFilter :对提取出的值进行过滤。

3.genericHeaderVariables :从HTTP header中提取值。

genericHeaderVariables的用法与genericRequestVariables-样,区别是它是从HTTP header中提取值的。

触发某个具体项目

上面可以看到GenericTrigger方法有一个token参数

GenericTrigger(
token: 'secret',
)
}

token参数的作用是标识一个pipeline在Jenkins中的唯一性(当然,没有人阻止你让所有的pipeline使用同-个token)。

为什么需要这个参数呢?这要从GWT插件的原理说起。当Jenkins接收到generic-webhooktriggerlinvoke接口的请求时,会将请求代理给GWT插件处理。GWT插件内部会从Jenkins实例对象中取出所有的参数化Jenkins项目,包括pipeline然后进行遍历。

如果在参数化项目中GenericTrigger配置的token的值与Webhook请求时的token的值一致,则触发此参数化项目。如果多个参数化项目的token值一样,则它们都会被触发。

pipeline的token可以被设置为Jenkins的项目名

比如:

triggers {
GenericTrigger(
//省略
token: env.JOB_NAME,
//省略
)
}

过滤请求值

上节所说的不完全正确。GWT并不只是根据token值来判断是否触发,还可以根据我们提取出的值进行判断。

示例如下:

GenericTrigger(
genericVariables:[
[key: ' refValue',value: '$.ref']
],
token: env.JOB_NAME,
regexpFilterText:'$refValue',
regexpFilterExpression: 'refs/heads/(master|dev)'
)
  • regexpilterText: 需要进行匹配的key。例子中,我们使用从POST body中提取出的refValue变量值。
  • regexpFilterExpression :正则表达式。

如果regexpFilterText参数的值符合regexpilterExpression参数的正则表达式,则触发执行。

控制打印内容

打印日志有助于调试。GWT插件提供了三个参数。

  • printPostContent :布尔值, 将Webhook请求信息打印到日志上。
  • printContributedVariables:布尔值,将提取后的变量名及变量
  • 值打印出来。
  • causeString :字符串类型,触发原因可以直接引用提取后的变量,如causeString : 'Triggered on $msg'。

控制响应

GWT插件最近才加入的一个参数:

silenResponse: 布尔类型,在正常情况下当Webhook请求发布成功后,GWT插件会返回HTTP 200状态码和触发结果给调用方。但是当设置为true时,就只返回HTTP 200状态码,不返回触发结果。

Jenkins触发构建的更多相关文章

  1. Gitlab源码库里代码提交后,如何触发jenkins自动构建?

    版本库里代码提交后,如何触发jenkins自动构建?这是一个面试题,感觉自己回答的并不好,因为并没有用过这个功能,之前公司实际项目用的是svn版本管理,一般都用立刻构建,和定时任务构建(不管代码是否有 ...

  2. jenkins+maven+gitlab触发构建

    1.安装插件 安装gitlab插件 回到项目配置在“构建触发器”那里有一个Build when a change is pushed to GitLab. GitLab webhook选项复制选项里的 ...

  3. SVN怎么触发Jenkins自动构建

    通常,有几种方式可以在SVN仓库发生改变时触发Jenkins进行构建.第一种是,Jenkins主动轮询SVN仓库:第二种是,在SVN客户端(如TortoiseSVN)创建客户端hooks来触发构建:第 ...

  4. jira webhook 事件触发并程序代码调用jenkins接口触发构建操作

    要解决的问题 开发管理工具触发站点构建事件,事件处理中需要调用Jenkins接口开始构建动作. 我的应用场景: 使用jira作为管理工具,在jira中创建自定义的工作流来规定测试,上线,发布等流程,并 ...

  5. 使用gitlab, jenkins搭建CI(持续集成)系统(2) -- 配置webhook触发构建

    1. 在gitlab上配置192.168.1.30的ssh秘钥,使jenkins可以操作gitlab上的project 进入gitlab,点击右上角 点击 Settings -> SSH key ...

  6. Gitlab+Jenkins学习之路(十一)之Jenkins自动触发构建和发布

    思路图: 一.下载gitlab plugin jenkins-->系统管理-->管理插件-->下载并安装gitlab plugin 二.配置gitlab认证 路径:Jenkins-- ...

  7. 实战:向GitHub提交代码时触发Jenkins自动构建

    当我们提交代码到GitHub后,可以在Jenkins上执行构建,但是每次都要动手去执行略显麻烦,今天我们就来实战Jenkins的自动构建功能,每次提交代码到GitHub后,Jenkins会进行自动构建 ...

  8. 六、配置github的pull request触发jenkins自动构建

    之前的配置,都是向master分支push操作触发jenkins进行构建,但是在一般的正常工作中,不会允许程序员直接向主分支推送代码:正常都是fork一个本地的分支,在本地分支调试完后,向主干分支提交 ...

  9. 五、配置jenkins定时构建或上游job触发构建

    我们之前说的都是通过检测github是否有push动作,即代码是否有更新,一旦检测到push动作就出发jenkins构建: 但是除了这种方式,我们可能还会需要定时进行构建,比如在每天的凌晨1:00构建 ...

随机推荐

  1. Spark面试题(五)——数据倾斜调优

    1.数据倾斜 数据倾斜指的是,并行处理的数据集中,某一部分(如Spark或Kafka的一个Partition)的数据显著多于其它部分,从而使得该部分的处理速度成为整个数据集处理的瓶颈. 数据倾斜俩大直 ...

  2. 配置Google支付相关参数(client_id, client_secret, refresh_token)

    1. 登陆Google开发者账号,点击左边API权限 Google控制台 创建新项目 转到 Google Play 管理中心的 API 权限页面. 接受<服务条款>. 点击创建新项目. 系 ...

  3. Json数据使用及学习方法

    以前对json的了解并不是很清楚,因为使用很少,所以也没有特意的研究.只知道json是轻量级的数据交换格式,可以被多种语言方便的处理,也是大型门户站接口使用的主要数据格式. 而最近做了个项目,涉及到j ...

  4. VS2013中using System.Windows.Forms;引用不成功

    命名空间"System"中不存在类型或命名空间名称"Windows" 项目右侧--解决资源管理器---引用---右键--添加引用---在.NET下拉框找---找 ...

  5. Jenkins教程(八)实现 GitLab 触发 Jenkins 自动按模块发布前端

    楔子 上篇文章解决了提交/合并请求自动触发的需求,但所有前端模块都在同一个代码仓库里,如何获取变更文件路径确定要发布哪个模块呢?本文将带你解决这个问题. 思路 分别解决 3 个问题: 获取变更的文件列 ...

  6. could not extract ResultSet

    使用jpa进行代码更新:update的时候发现代码出现了异常:could not extract ResultSet 在数据库看数据并没有更新,后发现更新操作需要加一个注解 注释:当设置nativeQ ...

  7. js--迭代器总结

    前言 我们已经熟练使用set.map.array几种集合类型了,掌握了map(),for..of..,filter()等迭代集合的方法,你是否思考过,js引擎是怎么迭代的,怎么判断迭代是否结束,本文来 ...

  8. mysql proxy 数据库读写分离字符集乱码

    mysql proxy 数据库读写分离字符集乱码 解决办法 在对应配置后端数据库服务器的配置.cnf中加入如下代码 init-connect='SET NAME UTF8' skip-characte ...

  9. Dango之form校验组件

    目录 1.引入案例 2. form组件的功能 3. form组件的使用 3.1 自定义form校验类 3.2 校验数据 3.3 渲染页面 3.4 展示错误信息 3.5 自定义校验结果 3.6 form ...

  10. 学习java的第二十一天

    一.今日收获 1.java完全学习手册第三章算法的3.2排序,比较了跟c语言排序上的不同 2.观看哔哩哔哩上的教学视频 二.今日问题 1.快速排序法的运行调试多次 2.哔哩哔哩教学视频的一些术语不太理 ...