Jenkins 2 版本后核心的功能就是 Pipeline,我们可以通过 Jenkinsfile 来完成流水线的定义。前提是我们需要掌握一定的流水线编写语法和技巧。通过掌握核心语法完成流水线的配置。适配 Pipeline as Code 理念。
在本场 Chat 中,会讲到如下内容:
- 开始编写 Jenkinsfile
- 流水线核心语法
- Jenkins 共享库应用
- Groovy 基础语法
适合人群: 所有对 Jenkins 感兴趣的同学们!
1. 开始编写 Jenkinsfile您好,还在疑惑什么是流水线吗? 本章我们将告诉您如何运行一条流水线 赶快学习吧!
目录- 为什么使用 pipeline?
- pipeline 定义
- pipeline 演示
- 验证流水线效果
本质上,jenkins 是一个自动化引擎,它支持许多自动模式。流水线向 Jenkins 添加了一组强大的工具,支持用例、简单的持续集成到全面的持续交付流水线。 通过对一系列的发布任务建立标准的模板,用户可以利用更多流水线的特性,比如:
代码化: 流水线是在代码中实现的,通常会存放到源代码控制,使团队具有编辑、审查和更新他们项目的交付流水线的能力。
耐用性:流水线可以从 Jenkins 的 master 节点重启后继续运行。
可暂停的:流水线可以由人功输入或批准继续执行流水线。
解决复杂发布: 支持复杂的交付流程。例如循环、并行执行。
可扩展性: 支持扩展 DSL 和其他插件集成。
构建一个可扩展是 Jenkins 的核心价值,流水线可以通过 ShareLibrary 的方式来扩展。
pipeline 定义关于 Jenkins 流水线的运行我们可以抽象一下,例如:可以把流水线(pipeline)想象成 13 号线地铁,把流水线的阶段(stage)想象成地铁的每一个站点,把流水线脚本(jenkinsfile)想象成地铁线路图。这就是流水线的多样性,每条线路都有不同的站点。
现在地铁(Jenkins)已经有了,我们需要设计地铁的运行线路图(Jenkinsfile),在线路图中指定要经过的站点(stages)。这下你是否已经知道我们要运行一条流水线,需要先做什么呢? --编写 jenkinsfile
Pipeline
- Jenkins 的 Pipeline 通过 Jenkinsfile 进行描述(类似于 Dockerfile)
- Jenkinsfile 是 Jenkins 的特性(pipeline as code)
- Pipeline 是 Jenkins 的核心功能,提供一组可扩展的工具。
- 通过 Pipeline 的 DSL 语法可以完成从简单到复杂的交付流水线实现。
Jenkinsfile
- Jenkinsfile 使用两种语法进行编写,分别是声明式和脚本式。
- 声明式和脚本式的流水线从根本上是不同的。
- 声明式是 jenkins 流水线更友好的特性。
- 脚本式的流水线语法,提供更丰富的语法特性。
- 声明式流水线使编写和读取流水线代码更容易设计。
来我们一起看下这里的配置,看下 Jenkinsfile 的组成及每个部分的功能含义。
- 使用 agent{},指定 node 节点/workspace(定义好此流水线在某节点运行)
- 指定 options{}运行选项(定义好此流水线运行时的一些选项,例如输出日志的时间)
- 指定 stages{}(stages 包含多个 stage,stage 包含 steps。是流水线的每个步骤)
- 指定 post{}(定义好此流水线运行成功或者失败后,根据状态做一些任务)
pipeline{ //指定运行此流水线的节点 agent { node { label "build"}} //流水线的阶段 stages{ //阶段 1 获取代码 stage("CheckOut"){ steps{ script{ println("获取代码") } } } stage("Build"){ steps{ script{ println("运行构建") } } } } post { always{ script{ println("流水线结束后,经常做的事情") } } success{ script{ println("流水线成功后,要做的事情") } } failure{ script{ println("流水线失败后,要做的事情") } } aborted{ script{ println("流水线取消后,要做的事情") } } }}
验证流水线效果
查看 Jenkins 构建日志(正确效果)
通过 BlueOcean 查看(如果没有 BlueOcean 图标,需要自行在插件中心安装插件)
到此一个简单的 Jenkinfile 完成了! 后面我们来详细分析每个步骤的作用。
2.Jenkins 流水线语法您好,本模块主要学习声明式流水线的核心语法,掌握核心语法便于编写 Jenkinsfile 😀
目录- 声明式流水线
- agent 代理
- post 运行后处理
- stages 阶段
- environment 环境变量
- options 运行选项
- parameters 参数
- trigger 触发器
- tool 构建工具
- input 交互输入
- when 条件判断
- parallel 并行
- script 脚本标签
声明式 Pipleine 是官方推荐的语法,声明式语法更加简洁。所有的声明式 Pipeline 都必须包含一个 pipeline 块中,比如:
pipeline { //run}
在声明式 Pipeline 中的基本语句和表达式遵循 Groovy 的语法。但是有以下例外:
- 流水线顶层必须是一个块,特别是 pipeline{}。
- 不需要分号作为分割符,是按照行分割的。
- 语句块只能由阶段、指令、步骤、赋值语句组成。例如: input 被视为 input()。
agent
指定了流水线的执行节点。
agent { node { label 'labelname' }}aget { label ' labelname '}
参数:
- any 在任何可用的节点上执行 pipeline。none 没有指定 agent 的时候默认。
- label 在指定标签上的节点上运行 Pipeline。 node 允许额外的选项(自定义 workspace)。
当流水线完成后根据完成的状态做一些任务。例如:构建失败后邮件通知
post { always { echo 'I will always say Hello again!' } failure{ email : xxxx@dxx.com }}
常用的状态:
- always 无论流水线或者阶段的完成状态。
- changed 只有当流水线或者阶段完成状态与之前不同时。
- failure 只有当流水线或者阶段状态为"failure"运行。
- success 只有当流水线或者阶段状态为"success"运行。
- unstable 只有当流水线或者阶段状态为"unstable"运行。例如:测试失败。
- aborted 只有当流水线或者阶段状态为"aborted "运行。例如:手动取消。
stages
是流水线的整个运行阶段,包含一个或多个 stage
, 建议 stages
至少包含一个 stage
。
stages { stage('Example') { steps { echo 'Hello World' } }}
environment 环境变量
定义流水线环境变量,可以定义在全局变量或者步骤中的局部变量。这取决于 environment 指令在流水线内的位置。
agent any//全局变量environment { activeEnv = 'dev'}stages { stage('Example') { //局部变量 environment { AN_ACCESS_KEY = credentials('my-prefined-secret-text') } steps { sh 'printenv' } }}
options 运行选项
定义流水线运行时的配置选项,流水线提供了许多选项, 比如 buildDiscarder,但也可以由插件提供, 比如 timestamps。
agent anyoptions { timeout(time: 1, unit: 'HOURS') }stages { stage('Example') { steps { echo 'Hello World' } }}
其他部分参数:
- buildDiscarder: 为最近的流水线运行的特定数量保存组件和控制台输出。
- disableConcurrentBuilds: 不允许同时执行流水线。 可被用来防止同时访问共享资源等。
- overrideIndexTriggers: 允许覆盖分支索引触发器的默认处理。
- skipDefaultCheckout: 在 agent 指令中,跳过从源代码控制中检出代码的默认情况。
- skipStagesAfterUnstable: 一旦构建状态变得 UNSTABLE,跳过该阶段。
- checkoutToSubdirectory: 在工作空间的子目录中自动地执行源代码控制检出。
- timeout: 设置流水线运行的超时时间, 在此之后,Jenkins 将中止流水线。
- retry: 在失败时, 重新尝试整个流水线的指定次数。
- timestamps 预测所有由流水线生成的控制台输出,与该流水线发出的时间一致。
为流水线运行时设置项目相关的参数,就不用在 UI 界面上定义了,比较方便。
//string 字符串类型的参数, 例如:parameters { string(name: 'DEPLOY_ENV', defaultValue: 'staging', description: '') }//booleanParam 布尔参数, 例如:parameters { booleanParam(name: 'DEBUG_BUILD', defaultValue: true, description: '') }
agent anyparameters { string(name: 'PERSON', defaultValue: 'Mr Jenkins', description: 'Who should I say hello to?')}stages { stage('Example') { steps { echo "Hello ${params.PERSON}" } }}
trigger 触发器
构建触发器
//cron 计划任务定期执行构建。triggers { cron('H */4 * * 1-5') }//pollSCM 与 cron 定义类似,但是由 jenkins 定期检测源码变化。triggers { pollSCM('H */4 * * 1-5') }agent anytriggers { cron('H */4 * * 1-5')}stages { stage('Example') { steps { echo 'Hello World' } }}
tool 构建工具
构建工具 maven、ant、gradle,获取通过自动安装或手动放置工具的环境变量。支持 maven/jdk/gradle。工具的名称必须在系统设置->全局工具配置中定义。
agent anytools { maven 'apache-maven-3.0.1' }stages { stage('Example') { steps { sh 'mvn --version' } }}
input 交互输入
input 用户在执行各个阶段的时候,由人工确认是否继续进行。
agent anystages { stage('Example') { input { message "Should we continue?" ok "Yes, we should." submitter "alice,bob" parameters { string(name: 'PERSON', defaultValue: 'Mr Jenkins', description: 'Who should I say hello to?') } } steps { echo "Hello, ${PERSON}, nice to meet you." } }}
参数解释:
- message 呈现给用户的提示信息。
- id 可选,默认为 stage 名称。
- ok 默认表单上的 ok 文本。
- submitter 可选的,以逗号分隔的用户列表或允许提交的外部组名。默认允许任何用户。
- submitterParameter 环境变量的可选名称。如果存在,用 submitter 名称设置。
- parameters 提示提交者提供的一个可选的参数列表。
when 指令允许流水线根据给定的条件决定是否应该执行阶段。 when 指令必须包含至少一个条件。
//branch: 当正在构建的分支与模式给定的分支匹配时,执行这个阶段,这只适用于多分支流水线例如:when { branch 'master' }//environment: 当指定的环境变量是给定的值时,执行这个步骤,例如:when { environment name: 'DEPLOY_TO', value: 'production' }//expression 当指定的 Groovy 表达式评估为 true 时,执行这个阶段, 例如:when { expression { return params.DEBUG_BUILD } }//not 当嵌套条件是错误时,执行这个阶段,必须包含一个条件,例如:when { not { branch 'master' } }//allOf 当所有的嵌套条件都正确时,执行这个阶段,必须包含至少一个条件,例如:when { allOf { branch 'master'; environment name: 'DEPLOY_TO', value: 'production' } }//anyOf 当至少有一个嵌套条件为真时,执行这个阶段,必须包含至少一个条件,例如:when { anyOf { branch 'master'; branch 'staging' } }stage('Example Deploy') { when { branch 'production' environment name: 'DEPLOY_TO', value: 'production' } steps { echo 'Deploying' }}
parallel 并行
声明式流水线的阶段可以在他们内部声明多隔嵌套阶段, 它们将并行执行。 注意,一个阶段必须只有一个 steps 或 parallel 的阶段。 嵌套阶段本身不能包含 进一步的 parallel 阶段, 但是其他的阶段的行为与任何其他 stageparallel 的阶段不能包含 agent 或 tools 阶段, 因为他们没有相关 steps。
stage('Parallel Stage') { when { branch 'master' } failFast true parallel { stage('Branch A') { agent { label "for-branch-a" } steps { echo "On Branch A" } } stage('Branch B') { agent { label "for-branch-b" } steps { echo "On Branch B" } } }}
failFast true 当其中一个进程失败时,强制所有的 parallel 阶段都被终止。
script 脚本标签可以通过此标签嵌入脚本式语法。
stage("Build"){ steps{ script{ println("运行构建") } }}
3. Jenkins 共享库应用
您好,本模块主要学习 Jenkins 共享库的配置,目的是能够让大家编写更加灵活强大的流水线😀
目录- 概述
- 共享库内容
- 创建共享库
- 使用共享库
共享库这并不是一个全新的概念,其实具有编程能力的同学应该清楚一些。例如在编程语言 Python 中,我们可以将 Python 代码写到一个文件中,当代码数量增加,我们可以将代码打包成模块然后再以 import 的方式使用此模块中的方法。
在 Jenkins 中使用 Groovy 语法,共享库中存储的每个文件都是一个 groovy 的类,每个文件(类)中包含一个或多个方法。每个方法包含 groovy 语句块。
我把共享库代码上传到了 github,大家可以参考demo 共享库
共享库内容这是一个 demo 演示的共享库,大家可以看到仓库的结构与内容。这个仓库中包含了很多类,例如:我将 kubernetes 中的 API 方法封装在了 kubernetes.groovy 文件中,便于后面引用。在此你只需要知道共享库的结构,具体该如何创建共享库后面会讲述😀
── docs│ └── README.mdREADME.md├── src│ └── org│ └── devops│ └── tools.groovy└── vars
src 目录主要存放我们要编写的 groovy 类,执行流水线时,此目录将添加到 class_path 中。vars 目录主要存放脚本文件,这些脚本文件在流水线中作为变量公开。resources 目录允许从外部库中使用步骤来加载相关联的非 Groovy 文件。
创建共享库新建文件src/org/devops/tools.groovy
, 在此我将这个文件定义为扩展工具类,主要放一些扩展方法。
例如:在构建日志中查看流水线详细日志会很乱,我们可以在日志中将重点步骤通过不同的颜色高亮显示,便于排错。 我们开始写这样的一个方法PrintMes()
,包含两个参数,输出内容value
和内容的颜色color
。
注意: 我们需要安装 插件AnsiColor
,这样才能使用 ansiColor()方法,可以在片段生成器
查看更多的用法。
package org.devops//格式化输出def PrintMes(value,color){ colors = ['red' : "\033[40;31m >>>>>>>>>>>${value}${value}>>>>>>>>>>[m", 'green1' : "\033[40;32m >>>>>>>>>>>${value}
关注
打赏