[作者:Surpassme]parameters 又称参数化,通过参数化可以决定pipeline运行期的行为。pipeline主要支持两种形式的参数化parameters命令参数化和插件参数化,这里先介绍通过parameters的参数化形式,通过paramters命令参数化时,parameters仅允许放置在pipeline块中
Jenkins pipeline目前支持的参数化类型主要如下所示:
[作者:Surpassme]数据类型为字符串类型,示例如下所示:
parameters{
string(name:"stringParaName",
defaultValue:"stringDefaultValue",
description:"string default description")
}
[作者:Surpassme]数据类型为多选文本类型,换行使用\n,示例如下所示:
parameters{
text(name:"textParaName",
defaultValue:"dev\ntest\nrelease",
description:"text default description"
)
}
[作者:Surpassme]数据类型为布尔类型,示例如下所示:
parameters{
booleanParam(name:"boolParaName",
defaultValue:true,
description:"boolean default descripiton"
)
}
[作者:Surpassme] 数据类型为参数选择类型,若存在多个选择,可以使用\n或["paramsA","paramsB"],示例如下所示:
parameters{
choice(name:"choiceParaName",
choices:["dev","test","release"],
description:"choice default description"
)
}
[作者:Surpassme]数据类型为密码类型,示例如下所示
parameters{
password(name:"passwordParaName",
defaultValue:"Surpass",
description:"password default description"
)
}
实际工程项目中,参数不可能全部是单一类型的参数,pipeline中也可以支持定义多参数,示例如下所示:
parameters{
string(name:"stringParaName",
defaultValue:"stringDefaultValue",
description:"string default description")
text(name:"textParaName",
defaultValue:"dev\ntest\nrelease",
description:"text default description"
)
booleanParam(name:"boolParaName",
defaultValue:true,
description:"boolean default descripiton"
)
choice(name:"choiceParaName",
choices:["dev","test","release"],
description:"choice default description"
)
password(name:"passwordParaName",
defaultValue:"Surpass",
description:"password default description"
)
}
在Jenkins pipeline中新增参数化后,
至少要执行一次,才能被Jenkins加载生效,当再次执行时,就可以设置或选择参数。
[作者:Surpassme]triggers 用于定义运行pipeline的触发器,根据触发条件,又可以划分为时间触发(主要包含 cron 和 pollSCM)和事件触发(主要包含upstream和Webhook)两个维度,详细解释如下所示:
triggers
仅能定义在pipeline块下
时间触发是指定义一个时间,在到达指定时间后,运行pipeline
事件触发是指发生了某个事件后,再运行pipeline。例如,手动在界面上触发、其他job触发、HTTP API Webhook触发等。
[作者:Surpassme] cron 触发适用于周期性的job。例如每天执行job等。示例如下所示:
pipeline{
agent any
options{
timestamps()
}
triggers{
cron("*/1 * * * *")
}
stages{
stage("cron demo"){
steps{
echo "running cron demo"
}
}
}
}
Jenkins triggers cron语法采用的是类似于Linux中的cron语法。一个cron包含5个字段,使用空格或Tab分隔,格式如下所示:
MINUTE HOUR DAY MONTH WEEK
以上各个字段解释如下所示:
0~591~230~311~120~7,其中0和7代表星期天对于DAY会有一些不准确的地方,因为一个月有天数可能有28、29、30和31等
以上为基本用法,也可以使用一些特殊字符,一次指定多个值
在一些大型项目中,为避免在同一时刻运行多个定时任务,造成负载过重,通常使用H(代表Hash)来避免出现此类问题。对于一些没有必要精确到指定时间运行的任务,则通过使用H方式,示例如下所示:
H 22 * * *
以上这种写法,则代表在
0~59分钟之间任何一个时间点执行
[作者:Surpassme]pollSCM也称轮询代码仓库,是指定定期到代码仓库询问代码是否有变化,如果有变化,则执行pipeline。示例如下所示:
pipeline{
agent any
options{
timestamps()
}
triggers{
pollSCM("*/1 * * * *")
}
environment{
SUB_DIR_PATH="SURPASS_TEST"
GitURL="https://gitlab.surpassme.com/jenkins/surpassme_test.git"
}
parameters{
gitParameter(name:"REGISTORY_TAG_BRANCH_NAME",
type:"PT_BRANCH_TAG",
branchFilter: "origin/(.*)",
defaultValue: "master",
selectedValue: "DEFAULT",
sortMode:"DESCENDING_SMART",
useRepository:"https://gitlab.surpassme.com/jenkins/surpassme_test.git",
description: "please choose registory branch or tag")
}
stages{
stage("pull code"){
steps{
checkout([
$class:"GitSCM",
branches:[[name:"${params.REGISTORY_TAG_BRANCH_NAME}"]],
doGenerateSubmoduleConfigurations: false,
extensions: [[$class:"RelativeTargetDirectory",relativeTargetDir:"${env.SUB_DIR_PATH}"]],
gitTool: "Default",
submoduleCfg: [],
userRemoteConfigs:[[credentialsId:" 5fa35f44-8ad0-4c82-9d27-481a03ef6c7d",url:"${env.GitURL}"]]
]
)
}
}
stage("pollSCM demo"){
steps{
echo "running pollSCM demo"
}
}
}
}
在实际应用时,如果代码有变化,一般是由代码仓库主动通知Jenkins,若由Jenkins去频繁代码仓库检查,一是不好定义轮询时间,二也会加重代码仓库的负担。一般不推荐使用这种方式。
[作者:Surpassme]当任务B的运行需要依赖任务A的运行结果时,则任务A称之为任务B的上游任务。upstream主要功能是让任务B自行决定依赖哪些上游任务。示例如下所示:
pipeline{
agent any
triggers{
upstream(upstreamProjects:"09-ParamtersSimple,10-cronSample",
threshold:hudson.model.Result.SUCCESS
)
}
stages{
stage("upsteam demo"){
steps{
echo "stream demo"
}
}
}
}
运行结果如下所示:

以上参数详细解释如下所示:
,分隔。ABORTED: 任务被手动中止FAILURE: 任务运行失败SUCCESS: 任务运行成功UNSTABLE: 任务运行不稳定,存在一些错误,但不会导致任务运行失败NOT_BUILT: 多阶段构建时,前面阶段的问题导致后面阶段无法运行[作者:Surpassme]通过Webhook来触发,一般又可以分为Gitlab触发和通用触发。
GitLab触发一般是当GitLab发现代码仓库有变化时,触发Jenkins来执行pipeline,利用这个特性能够较好的解决pollSCM所带来的问题。
以下来演示手动如何创建GitLab触发的过程,步骤如下所示:
GitLab手动触发需要的插件为
GitLab和Git

Jenkins暴露的Webhook地址格式一般为:http://jenkins-master-address/project/
<项目名>
Secret token


[作者:Surpassme]对于手动配置GitLab Webhook也非常简单,但却不适合批量部署使用,其实通过Jenkinsfiles也可以实现。示例如下所示:
pipeline{
agent any
triggers{
gitlab(triggerOnPush:true,
triggerOnMergeRequest:true,
branchFilterType:"All",
secretToken:"232414e2f208ae6c9b26f455c7c1937f"
)
}
stages{
stage("GitLab trigger demo"){
steps{
echo "GitLab trigger demo"
}
}
}
}
GitLab trigger主要参数配置如下所示:
[作者:Surpassme]当GitLab产生push事件时,触发运行pipeline
当GitLab触发mergeRequest事件时,触发运行pipeline
为必选参数,只有符合条件的分支才允许运行pipeline。可设置值为:
- NameBasedFilter: 基于分支名进行过滤,多个分支名使用,分隔
- RegexBasedFilter: 基于正则表达式对分支名进行过滤
- All: 所有分支都会被触发
访问Jenkins的Token,可以使用随机字符串工具生成
[作者:Surpassme]前面主要使用的GitLab插件来配置触发,但如果不是GitLab也是可以配置触发。安装插件Generic Webhook Trigger(https://plugins.jenkins.io/generic-webhook-trigger/),在安装Generic Webhook Trigger插件后,Jenkins会暴露一个API接口(http://jenkins-master-address/generic-webhook-trigger/invoke)来处理此API的语法。示例如下所示:
pipeline{
agent any
options{
timestamps()
}
triggers{
GenericTrigger(
genericVariables:[
[
key:'ref',
value:'$.ref'
]
],
causeString:'Triggered on $ref',
token:"232414e2f208ae6c9b26f455c7c1937f",
tokenCredentialId: "",
printContributedVariables: true,
printPostContent: true,
silentResponse: false,
shouldNotFlattern: false,
regexpFilterText: '$ref',
regexpFilterExpression: "refs/heads/"
)
}
stages{
stage("generic trigger webhook demo"){
steps{
echo "generic trigger webhook demo"
sh "echo $ref"
}
}
}
}
注意事项如下所示:
引号的使用,这里单双引号还是有区别的以下我们可以发送一个HTTP请求,来验证效果,如下所示:

运行结果如下所示:

[作者:Surpassme]when 命令允许pipeline在满足指定的条件时,才执行某个阶段。使用when指令的注意事项如下所示:
至少要包含一个条件所有子条件都满足才能执行某个阶段not、allOf、anyOf等来满足更加灵活的条件匹配[作者:Surpassme]单个条件的主要使用用法如下所示:
branch当构建分支与给定的分支匹配,则执行该阶段,示例如下所示:
pipeline{
agent any
stages{
stage("branch release"){
when{
branch "release"
}
steps{
echo "build on branch release"
}
}
stage("branch test"){
when{
branch "test"
}
steps{
echo "build on branch test"
}
}
}
}
branch 仅适用于多分支pipeline
changelog[作者:Surpassme]如果代码仓库的changlog符合相应的正则表达式,则执行某个阶段,示例如下所示:
pipeline{
agent any
stages{
stage("changlog demo"){
when{
changelog '.*^\\[DEPENDENCY\\] .+$'
}
steps{
echo "build on changelog"
}
}
}
}
changeset[作者:Surpassme]如果代码仓库变更集合中包含一个或多个文件符合给定的Ant风格路径表达式,则执行某个阶段,示例如下所示:
pipeline{
agent any
stages{
stage("changeset demo"){
when{
changeset "**/*.go"
}
steps{
echo "build on changeset"
}
}
}
}
environment[作者:Surpassme]当环境变量的值与给定的值相同时,则执行某个阶段,示例如下所示:
pipeline{
agent any
environment{
NAME="Surpass"
}
stages{
stage("environment demo"){
when{
environment name:"NAME",value:"Surpass"
}
steps{
echo "build on environment"
}
}
}
}
equals[作者:Surpassme]当给定的值与期望值相等进,则执行某个阶段,示例如下所示:
pipeline{
agent any
parameters{
string(name:"name",
defaultValue:"Surpass",
description:"test name"
)
}
stages{
stage("equals demo"){
when{
equals actual: "${params.name}" ,expected:"Surpass"
}
steps{
echo "build on equals"
}
}
}
}
expression [作者:Surpassme]如果表达式返回为true时,则执行某个阶段,示例如下所示:
pipeline{
agent any
parameters{
string(name:"name",
defaultValue:"Surpass",
description:"test name"
)
}
stages{
stage("expression demo"){
when{
expression {
return params.name == "Surpass"
}
}
steps{
echo "build on expression"
}
}
}
}
当表达式返回的是字符串时,必须转换为boolean类型或null,否则所有字符串会按 true 处理
tag[作者:Surpassme]如果代码仓库的Tag与给定的Tab值匹配时,则执行某个阶段,示例如下所示:
pipeline{
agent any
stages{
stage("tag demo"){
when{
tag "Surpass-v3.*"
}
steps{
echo "build on tag"
}
}
}
}
tag支持comparator参数,如下所示:
pipeline{
agent any
stages{
stage("tag demo"){
when{
tag pattern:"Surpass-v3.3.1",comparator:"EQUALS"
}
steps{
echo "build on tag"
}
}
}
}
默认值,Ant风格路径表达式,因其是默认值,完整写法如下所示:pipeline{
agent any
stages{
stage("tag demo"){
when{
tag pattern:"Surpass-v3.3.1",comparator:"GLOB"
}
steps{
echo "build on tag"
}
}
}
}
pipeline{
agent any
stages{
stage("tag demo"){
when{
tag pattern:"Surpass-v\\d.*",comparator:"REGEXP"
}
steps{
echo "build on tag"
}
}
}
}
not[作者:Surpassme]当条件不满足时,则执行某个阶段,示例如下所示:
pipeline{
agent any
stages{
stage("tag demo"){
when{
not {
tag pattern:"Surpass-v\\d.*",comparator:"REGEXP"
}
}
steps{
echo "build on tag"
}
}
}
}
[作者:Surpassme]组合条件的主要使用用法如下所示:
allOf[作者:Surpassme]当所有条件都满足时,才执行该阶段,示例如下所示:
pipeline{
agent any
environment{
NAME="Surpass"
}
parameters{
string(name:"name",
defaultValue:"Surpass",
description:"test allOf"
)
}
stages{
stage("allOf demo"){
when{
allOf {
environment name:"NAME",value:"Surpass"
expression {
return params.name == "Surpass"
}
}
}
steps{
echo "build on allOf"
}
}
}
}
anyOf[作者:Surpassme]当任意一个条件都满足时,才执行该阶段,示例如下所示:
pipeline{
agent any
environment{
NAME="Surpass"
}
parameters{
choice(name:"name",
choices:["dev","test","release"],
description:"test anyOf"
)
}
stages{
stage("anyOf demo"){
when{
anyOf {
environment name:"NAME",value:"Surpass"
expression {
return params.name == "test"
}
}
}
steps{
echo "build on anyOf"
}
}
}
}
[作者:Surpassme]Jenkins 采用的是master+agent架构,master负责提供界面,处理HTTP请示和管理构建环境等。具体的构建执行,则由agent负责。基于此,只需要增加agent就可以支持更多的项目同时运行。
[作者:Surpassme]当 agent 数量较多时,为了快速辨别和使用不同的agent,我们就需要对agent添加标签。通过标签可以将多个agent分配到同一个逻辑组中。同一个agent也支持多个标签。标签的命名注意事项如下所示:
标签中不能包含空格、!、&、|、<、>、(、)等特殊字符
添加标签时,可以参考以下几个维度进行增加
添加agent标签的示例如下所示:

[作者:Surpassme]agent 部分描述的是整个pipeline或特定阶段时,使用哪一个agent运行任务。即Jenkins master 会根据agent标签,将具体的任务分配到满足匹配标签的agent上。因此agent必做在pipeline块内的顶部定义,stage块内的定义是可选的。其详细使用如下所示:
anyany 表示任何可用的agent都可以运行任务,示例如下所示:
pipeline{
agent any
// ...
}
agent 定义在pipeline的顶部
pipeline{
agent any // 不能省略
stages{
stage("build"){
agent any // 定义在阶段内部
steps{
echo "build demo ..."
}
}
}
}
agent 定义在stage内部
通过标签指定agent[作者:Surpassme]当需要指定任务运行在CentOS 7中时,可以通过agent来指定标签,示例如下所示:
pipeline{
agent {
label "centos7"
}
stages{
stage("agent label demo"){
steps{
echo "agent label demo"
}
}
}
}
none[作者:Surpassme]如果不想分配agent,则可以使用none,示例如下所示:
pipeline{
agent none
stages{
stage("agent label demo"){
agent{
label "centos7"
}
steps{
echo "agent label demo"
}
}
}
}
这种场景一般常用于希望各个stage运行在不同的agent中
[作者:Surpassme]post部分主要用于在整个pipeline或阶段完成后的一些附加步骤,是可选的。根据pipeline或阶段完成状态,post部分可分成多个条件块,如下所示:
示例如下所示:
pipeline{
agent any
options{
timestamps()
}
stages{
stage("pull code"){
steps{
echo "pull code"
}
post{
failure{
echo "pull code failed,please check"
}
}
}
stage("build"){
steps{
echo "build ..."
}
post{
regression{
echo "build regression"
}
}
}
stage("deploy"){
steps{
echo "deploy"
script{
error(message:"deploy error")
}
}
post{
success{
echo "deploy success"
}
failure{
echo "deploy failure"
}
}
}
}
post{
aborted{
echo "pipeline aborted"
}
unstable{
echo "piepline unstable"
}
failure{
echo "pipeline failure"
}
success{
echo "pipeline success"
}
always{
echo "ignore pipeline status,alway run print this section"
}
}
}
[作者:Surpassme]运行结果如下所示:

原文地址:https://www.jianshu.com/p/55e918edf71f
本文同步在微信订阅号上发布,如各位小伙伴们喜欢我的文章,也可以关注我的微信订阅号:woaitest,或扫描下面的二维码添加关注:

很好奇,就使用rubyonrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提
我脑子里浮现出一些关于一种新编程语言的想法,所以我想我会尝试实现它。一位friend建议我尝试使用Treetop(Rubygem)来创建一个解析器。Treetop的文档很少,我以前从未做过这种事情。我的解析器表现得好像有一个无限循环,但没有堆栈跟踪;事实证明很难追踪到。有人可以指出入门级解析/AST指南的方向吗?我真的需要一些列出规则、常见用法等的东西来使用像Treetop这样的工具。我的语法分析器在GitHub上,以防有人希望帮助我改进它。class{initialize=lambda(name){receiver.name=name}greet=lambda{IO.puts("He
所以我在关注Railscast,我注意到在html.erb文件中,ruby代码有一个微弱的背景高亮效果,以区别于其他代码HTML文档。我知道Ryan使用TextMate。我正在使用SublimeText3。我怎样才能达到同样的效果?谢谢! 最佳答案 为SublimeText安装ERB包。假设您安装了SublimeText包管理器*,只需点击cmd+shift+P即可获得命令菜单,然后键入installpackage并选择PackageControl:InstallPackage获取包管理器菜单。在该菜单中,键入ERB并在看到包时选择
在Ruby类中,我重写了三个方法,并且在每个方法中,我基本上做同样的事情:classExampleClassdefconfirmation_required?is_allowed&&superenddefpostpone_email_change?is_allowed&&superenddefreconfirmation_required?is_allowed&&superendend有更简洁的语法吗?如何缩短代码? 最佳答案 如何使用别名?classExampleClassdefconfirmation_required?is_a
可能已经问过了,但我找不到它。这里有2个常见的情况(对我来说,在编程Rails时......)用ruby编写是令人沮丧的:"astring".match(/abc(.+)abc/)[1]在这种情况下,我得到一个错误,因为字符串不匹配,因此在nil上调用[]运算符。我想找到的是比以下内容更好的替代方法:temp="astring".match(/abc(.+)abc/);temp.nil??nil:temp[1]简而言之,如果不匹配,则简单地返回nil而不会出错第二种情况是这样的:var=something.very.long.and.tedious.to.writevar=some
我正在学习Ruby的基础知识(刚刚开始),我遇到了Hash.[]method.它被引入a=["foo",1,"bar",2]=>["foo",1,"bar",2]Hash[*a]=>{"foo"=>1,"bar"=>2}稍加思索,我发现Hash[*a]等同于Hash.[](*a)或Hash.[]*一个。我的问题是为什么会这样。是什么让您将*a放在方括号内,是否有某种规则可以在何时何地使用“it”?编辑:我的措辞似乎造成了一些困惑。我不是在问数组扩展。我明白了。我的问题基本上是:如果[]是方法名称,为什么可以将参数放在括号内?这看起来几乎——但不完全是——就像说如果你有一个方法Foo.d
导读:随着叮咚买菜业务的发展,不同的业务场景对数据分析提出了不同的需求,他们希望引入一款实时OLAP数据库,构建一个灵活的多维实时查询和分析的平台,统一数据的接入和查询方案,解决各业务线对数据高效实时查询和精细化运营的需求。经过调研选型,最终引入ApacheDoris作为最终的OLAP分析引擎,Doris作为核心的OLAP引擎支持复杂地分析操作、提供多维的数据视图,在叮咚买菜数十个业务场景中广泛应用。作者|叮咚买菜资深数据工程师韩青叮咚买菜创立于2017年5月,是一家专注美好食物的创业公司。叮咚买菜专注吃的事业,为满足更多人“想吃什么”而努力,通过美好食材的供应、美好滋味的开发以及美食品牌的孵
//1.验证返回状态码是否是200pm.test("Statuscodeis200",function(){pm.response.to.have.status(200);});//2.验证返回body内是否含有某个值pm.test("Bodymatchesstring",function(){pm.expect(pm.response.text()).to.include("string_you_want_to_search");});//3.验证某个返回值是否是100pm.test("Yourtestname",function(){varjsonData=pm.response.json
我从Ubuntu服务器上的RVM转移到rbenv。当我使用RVM时,使用bundle没有问题。转移到rbenv后,我在Jenkins的执行shell中收到“找不到命令”错误。我内爆并删除了RVM,并从~/.bashrc'中删除了所有与RVM相关的行。使用后我仍然收到此错误:rvmimploderm~/.rvm-rfrm~/.rvmrcgeminstallbundlerecho'exportPATH="$HOME/.rbenv/bin:$PATH"'>>~/.bashrcecho'eval"$(rbenvinit-)"'>>~/.bashrc.~/.bashrcrbenvversions
前置步骤我们都操作完了,这篇开始介绍jenkins的集成。话不多说,看操作1、登录进入jenkins后会让你选择安装插件,选择第一个默认的就行。安装完成后设置账号密码,重新登录。2、配置JDK和Git都需要执行路径,所以需要先把执行路径找到,先进入服务器的docker容器,2.1JDK的路径root@69eef9ee86cf:/usr/bin#echo$JAVA_HOME/usr/local/openjdk-82.2Git的路径root@69eef9ee86cf:/#whichgit/usr/bin/git3、先配置JDK和Git。点击:ManageJenkins>>GlobalToolCon