1 Pipeline
1.1 Pipeline定义
Pipeline是通过Jenkinsfile描述的流水线,安装声明式插件Pipeline:Declarative
Jenkensfile的组成:
指定node节点/workspace
指定运行选项
指定stages阶段
指定构建后操作
1.2 Pipeline语法
1.2.1 agent指定node节点/workspace
可选参数:
any表示任何可用的节点上执行pipeline
none为agent的默认值
label表示在指定节点上运行
node表示允许额外的选项
agent {
node {
label "master" // 指定运行节点的标签或名称
customWorkspace "${workspace}" // 指定运行的工作目录(可选)
}
}
1.2.2 options指定运行选项
options指令允许从流水线内部配置特定的流水线选项,也可以由插件提供:
buildDiscarder:为最近的流水线运行的特定数量保存组件和控制台输出
disableConcurrentBuilds:不允许同时执行流水线,可防止同时访问共享资源
overriderIndexTriggers:允许覆盖分支索引触发器的默认处理
timeout:设置超时时间
retry:失败后重新尝试的次数
skipStagesAfterUnstable:一旦构建状态变为UNSTABLE,就跳过该阶段
options {
timestamps() // 在日志中打印时间
skipDefaultCheckout() // 删除隐式的checkout scm 语句
disableCouncurrentBuilds() // 禁止并行
timeout(time:1, unit:'HOURS') // 流水线超时设置为1H
}
1.2.3 stages指定stages阶段
包含了一个或多个stage指令,用于连接交付过程中每个离散的部分
stages{
stage("PullCode") { // 阶段名称
steps { // 步骤
timeout(time:5, unit:'MINUTES') { // 指定步骤的超时时间
script { // 指定运行的脚本
println("获取代码")
}
}
}
}
stage("Build") { // 阶段名称
steps { // 步骤
timeout(time:20, unit:'MINUTES') { // 指定步骤的超时时间
script { // 指定运行的脚本
println("应用打包")
}
}
}
}
stage("CodeScan") { // 阶段名称
steps { // 步骤
timeout(time:30, unit:'MINUTES') { // 指定步骤的超时时间
script { // 指定运行的脚本
println("代码扫描")
}
}
}
}
}
1.2.4 post指定构建后操作
post-condition块:
always{}:总是执行
success{}:成功后执行
failure{}:失败后执行
aborted{}:取消后执行
changed{}:当流水线或阶段完成状态和之前不同时执行
unstable{}:当流水线或阶段状态为unstable时执行
post {
always {
println("总是执行")
}
success {
script {
// currentBuild是一个全局变量
// description是构建描述
currentBuild.description += "\n 构建成功!"
}
}
failure {
script {
currentBuild.description += "\n 构建失败!"
}
}
aborted {
script {
currentBuild.description += "\n 构建取消!"
}
}
}
1.2.5 enviroment环境变量
用于指定一个键值对序列,用于定义所有/特定阶段步骤的环境变量,取决于environment定义的位置。支持credentials()方法,用于通过标识符访问jenkins预定义的凭证。相当于定义一个变量,可以在后续使用
pipeline {
agent any
enviroment {
CC = 'clang'
}
stages {
stage("example") {
enviroment {
ACC_KEY = credentails("my-secret-text")
}
steps {
sh 'printenv'
}
}
}
}
1.2.6 parameter参数
为流水线运行时设置项目相关的参数
parameters {
string(name: 'DEPLOY_ENV', defaultValue: 'staging', description: '')
booleanParam(name: 'DEBUG_BUILD', defaultValue: true, descrptio: '')
}
1.2.7 trigger触发器
构建触发器:
cron计划任务定期执行构建:triggers{cron(‘H */4 * * 1-5’)}
pollSCM与cron类型,由jenkins定期检测源码变化:triggers{pollSCM(‘H */4 * * 1-5’)}
upstream接受都好分割的工作字符串和阈值,当字符串中任何作业以最小阈值结束时,流水线被重新触发
1.2.8 input人工确认
input由人工确认是否继续进行
message:呈现给用户的提示信息
id可选默认为stage名称
ok默认表单的ok文本
submitter:可选,逗号分隔的用户列表或允许提交的外部组名,默认允许任何用户
parameter:提示提交者提供一个可选的参数列表
示例:
pipeline {
agent any
stages {
stage('SayHello') {
input {
message "Should we continue"
ok "Yes, we should"
submitter "xd1998"
parameters {
string(name: "PERSON", defaultValue: "JXD", description: "Who are you?")
}
}
steps {
echo "Hello ${PERSON}"
}
}
}
}
1.2.9 when语法
放置在stage中,条件为true,stage执行。
branch:构建的分支和给定的分支匹配则执行,适用于多分支流水线:when {branch ‘master’}
environment:指定环境变量是给定值执行:when {environment name: ‘DEPLOY_TO’, value:‘prooduction’}
expression:当指定的Groovy表达式评估为true时才执行:when {expression {return params.DEBUG_BUILD}}
when语法根据参数值跳过执行的阶段
not:当嵌套条件为false时执行:when {not {branch ‘master’}}
allOf:当所有嵌套条件都为true才执行:when {allOf {branch ‘master’; environment name: 'DEPLOY_TO, value: 'production}}
anyOf:当至少有一个嵌套条件为true时执行
pipeline {
agent any
parameters {
string(name: "PERSON", defaultValue: "JXD", description: "Who are you?")
}
stages{
stage('SayHello') {
input {
message "Should we continue"
ok "Yes, we should"
submitter "xd1998"
}
steps {
echo "Hello ${PERSON}"
}
}
stage("PullCode") { // 阶段名称
steps { // 步骤
timeout(time:5, unit:'MINUTES') { // 指定步骤的超时时间
script { // 指定运行的脚本
println("获取代码")
}
}
}
}
stage("Build") { // 阶段名称
steps { // 步骤
timeout(time:20, unit:'MINUTES') { // 指定步骤的超时时间
script { // 指定运行的脚本
println("应用打包")
}
}
}
}
stage("CodeScan") { // 阶段名称
when {
environment name: "PERSON",
value: 'JXD'
}
steps { // 步骤
timeout(time:30, unit:'MINUTES') { // 指定步骤的超时时间
script { // 指定运行的脚本
println("代码扫描")
}
}
}
}
}
}
2 Jenkins Share Library
src目录类似于标准的Java src目录结构,执行流水线时,将这个目录添加到类路径,vars目录托管脚本文件,这些脚本文件在管道中作为变量公开。resource目录允许libraryResource从外部库使用步骤来加载相关联的非Groovy文件。
(root)
- src # Groovy源文件
| -org
| -foo
| -Bar.groovy # org.foo.Bar 类
- vars
| -foo.groovy # 全局的foo变量
| -foo.txt # foo变量的help
- resources # 源文件(外部库)
| -org
| -foo
| -bar.json # org.foo.Bar的静态helper数据
2.1 创建自己的共享库
在github中新建仓库,在src/org/devops下创建文件,定义共享方法
package org.devops
// 打印内容
def PrintMes(content) {
println(content)
}
2.2 在Jenkins中配置共享库
先设置共享库的名称,后续在pipeline中通过@Library或者Library{}指定共享库。根据github的分支名称指定默认的版本
设置共享库中的源码管理
2.3 在流水线中使用共享库
#!groovy
@Library('jenkinslib') _
def tools = new org.devops.tools()
String workspace = "/opt/jenkins/workspace"
pipeline {
agent {
node {
label "master"
customWorkspace "${workspace}"
}
}
parameters {
string(name: "PERSON", defaultValue: "JXD", description: "Who are you?")
}
stages{
stage('SayHello') {
input {
message "Should we continue"
ok "Yes, we should"
submitter "xd1998"
}
steps {
echo "Hello ${PERSON}"
}
}
stage("PullCode") { // 阶段名称
steps { // 步骤
timeout(time:5, unit:'MINUTES') { // 指定步骤的超时时间
script { // 指定运行的脚本
println("获取代码")
}
}
}
}
stage("Build") { // 阶段名称
steps { // 步骤
timeout(time:20, unit:'MINUTES') { // 指定步骤的超时时间
script { // 指定运行的脚本
println("应用打包")
}
}
}
}
stage("CodeScan") { // 阶段名称
when {
environment name: "PERSON",
value: 'JXD'
}
steps { // 步骤
timeout(time:30, unit:'MINUTES') { // 指定步骤的超时时间
script { // 指定运行的脚本
println("代码扫描")
tools.PrintMes('this is mylib')
}
}
}
}
}
}
3 Groovy
Groovy是功能强大可选类型的动态语言,支持Java平台,可以与Java集成,提供脚本编写、特定领域语言编写、运行时和编译时元编程及函数式编程。
3.1 安装Groovy
下载Groovy安装包
解压安装包
获取bin目录
将bin写入/etc/profile文件
export GROOVY_HOME=/opt/groovy
export PATH=$PATH:$GROOVY_HOME/bin
生效:source /etc/profile
启动Groovy IDE:groovyconsole
3.2 Groovy基础
数据类型String常用方法:
contains()是否包含特定内容
size() length()字符串长度
toString()转为string类型
indexOf()元素索引
endWith()是否指定字符结尾
minus() plus() 增加去掉字符串
reverse() 反向排序
substring(1,2)取子字符串
toUpperCase() toLowerCase() 大小写转换
split() 切分字符串
单引号引用普通字符串,双引号相当于模板字符串可以使用${}引用变量
数据类型List常用方法:
- – += -= 增删元素
add() 添加元素
isEmpty() 判空
intersect() disjoint() 取交集、判断是否有交际
flatten() 扁平化列表
unique() 去重
reverse() sort() 反转 排序
count() 个数
join() 连接
sum() min() max() 求和、最值
contains() 包含特定元素
remove() removeAll()
each() 遍历
定义函数
def PrintMessage(message) {
println(message)
}
补充:常用的Pipeline DSL
readJSON
checkout
publishHTML
input
credentials
httpRequest
email
4 Jenkins工具集成
4.1 Maven集成
集成Maven、Gradle、Ant过程类似:下载压缩包,解压缩,找到bin目录,配置环境变量,让环境变量生效。在全局工具配置中配置home的位置(如果没找到配置的地方就安装插件),在pipeline中定义一个变量等于tool + “name” ,后续使用变量即可。
在github中新增jenkinsfile
pipeline {
agent {
node {
label "master"
}
}
stages {
stage("build") {
steps {
script {
mvnHome = tool "maven3.6.3"
sh "${mvnHome}/bin/mvn -v"
}
}
}
}
}
从SCM中配置流水线
执行流水线,执行成功
4.2 NPM集成
安装node
在全局工具配置中配置home的位置
遇到一个报错:/usr/bin/env: node: No such file or directory,解决方法:添加软连接ln -s /usr/local/NODEJS_HOME/bin/node /usr/bin/node
4.3 使用共享库整合构建工具
4.4 Ansible集成
安装ansible
配置ssh
配置servers
将Ansible添加到流水线中
#!groovy
@Library('jenkinslib') _
def build = new org.devops.build()
def deploy = new org.devops.deploy()
String buildShell = "${env.buildShell}"
String buildType = "${env.buildType}"
String deployHosts = "${env.deployHosts}"
pipeline {
agent {
node {
label "master"
}
}
stages {
stage("build") {
steps {
script {
build.Build(buildType, buildShell)
deploy.AnsibleDeploy("${deployHosts}", "-m ping")
}
}
}
}
}
引入的共享库:@Library('jenkinslib') _
package org.devops
def AnsibleDeploy(hosts, func) {
sh "ansible ${func} ${hosts}"
}