一.简介

都是在推送代码后,再切换到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. R数据分析:纵向数据如何做中介,交叉滞后中介模型介绍

    看似小小的中介,废了我好多脑细胞,这个东西真的不简单,从7月份有人问我,我多重中介,到现在的纵向数据中介,从一般的回归做法,到结构方程框架下的路径分析法,到反事实框架做法,从中介变量和因变量到是连续变 ...

  2. netcore项目中IStartupFilter使用

    背景: netcore项目中有些服务是在通过中间件来通信的,比如orleans组件.它里面服务和客户端会指定网关和端口,我们只需要开放客户端给外界,服务端关闭端口.相当于去掉host,这样省掉了些指定 ...

  3. 编译使用nginx

    nginx-1.18.0 ./configure --prefix=$HOME/nginx --with-http_ssl_module make -j32; make install [fangju ...

  4. WinForm训练一_改变窗体大小

    1 //引用系统命名空间 2 using System; 3 //项目命名空间 4 using System.Collections.Generic; 5 using System.Component ...

  5. SQL语句修改字段类型与第一次SQLServer试验解答

    SQL语句修改字段类型 mysql中 alert table name modify column name type; 例子:修改user表中的name属性类型为varchar(50) alert ...

  6. 爬虫进阶篇(一)scrapy

    1.本教程默认认为您已经像我一样是个半吊子爬虫程序员 2.学习爬虫首先要懂得request,json,bs4,re,xpath,pymysql,random,time,文件相关,理解网络编程基本原理, ...

  7. SubsamplingScaleImageView 源码解析

    一开始没打算分析 SubsamplingScaleImageView 这个开源的图片浏览器的,因为这个库在我们 App 中使用了,觉得自己对这个库还是比较熟悉的,结果某天再看看到源码介绍的时候,才发现 ...

  8. 8.5 Ingress实现基于域名的多虚拟主机、URL转发、及多域名https实现等案例

    1.什么是Ingress Ingress 公开了从k8s集群外部到集群内服务的 HTTP 和 HTTPS 路由. 流量路由由 Ingress 资源上定义的规则控制. 可以将 Ingress 配置为服务 ...

  9. Codeforces 1063F - String Journey(后缀数组+线段树+dp)

    Codeforces 题面传送门 & 洛谷题面传送门 神仙题,做了我整整 2.5h,写篇题解纪念下逝去的中午 后排膜拜 1 年前就独立切掉此题的 ymx,我在 2021 年的第 5270 个小 ...

  10. Atcoder Grand Contest 038 F - Two Permutations(集合划分模型+最小割)

    洛谷题面传送门 & Atcoder 题面传送门 好久前做的题了--今天偶然想起来要补个题解 首先考虑排列 \(A_i\) 要么等于 \(i\),要么等于 \(P_i\) 这个条件有什么用.我们 ...