Fork me on GitHub

jenkins pipeline 介绍

pipeline 语法参考 https://jenkins.io/doc/book/pipeline/syntax/

1. jenkinsfile 骨架

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
pipeline {
agent {
// 构建的节点
}

environment {
// 构建时注入的环境变量
}

parameters {
// 参数化构建
}

triggers {
// 构建触发器
}

// 构建阶段
stages {
stage('测试') {
steps {
// 测试阶段步骤
}
}

stage('构建') {
steps {
}
}
}

// 构建后回调,可以在success和failure中通知开发
post {
success {
}

failure {
}
}
}

2. agent

agent,定义构建的节点,也可以在 stage 中指定。默认 none,如果我们在 jenkins 上配置了一个 mac 节点,app 在 mac 节点上构建,那么我们可以如下声明:

1
2
3
4
5
agent {
node {
label: 'mac'
}
}

3. environment

可以在 environment 中注入构建时的环境变量。如我们构建时使用指定路径的 nodejs:

1
2
3
environment {
PATH = "${PATH}:${HOME}/.nvm/versions/node/v8.11.1/bin"
}

除了可以在 environment 中声明环境变量外,还可以在 groovy 脚本中添加或修改。

1
2
3
script {
env.DOCKER_HOST='tcp://192.168.71.86:2376'
}

4. parameters

有时候我们需要参数化构建,如选择构建的环境,也可以通过 jenkinsfile 定义。下面示例提供了两个选择框,可以选择部署的环境和部署类型。需要注意的是,选择框的第一个为默认值。

1
2
3
4
5
parameters {
choice(name: 'DEPLOY_ENV', choices: ['test', 'demo', 'production'], description: '选择部署环境');

choice(name: 'DEPLOY_TYPE', choices: ['部署', '回滚'], description: '选择部署类型');
}

更多输入类型参考 https://jenkins.io/doc/book/pipeline/syntax/#parameters

1
2
3
4
5
6
7
8
9
10
11
12
13
parameters {
string(name: 'PERSON', defaultValue: 'Mr Jenkins', description: 'Who should I say hello to?')

text(name: 'BIOGRAPHY', defaultValue: '', description: 'Enter some information about the person')

booleanParam(name: 'TOGGLE', defaultValue: true, description: 'Toggle this value')

choice(name: 'CHOICE', choices: ['One', 'Two', 'Three'], description: 'Pick something')

password(name: 'PASSWORD', defaultValue: 'SECRET', description: 'Enter a password')

file(name: "FILE", description: "Choose a file to upload")
}

5. triggers

当然,也可以在 jenkinsfile 上定义任务的触发器,内部提供了 cron, pollSCM 和 upstream 三种类型的触发器。

1
2
3
triggers {
cron('H */4 * * 1-5')
}

除了内置触发器外,许多插件也提供了触发器,比如 Generic Webhook Trigger

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
triggers {
GenericTrigger(
genericVariables: [ // 从参数中取值
[key: 'ref', value: '$.ref']
],

causeString: 'Triggered on $ref',

token: 'test_imservice_ci', // 只有 url 中的 token=test_imservice_ci 才会触发

printContributedVariables: true,
printPostContent: true,

regexpFilterText: '$ref',
regexpFilterExpression: 'refs/heads/' + BRANCH_NAME // 当 ref 为当前分支时才构建
// 注: 只在多分支流水线项目中才包含 BRANCH_NAME 字段
)
}

6. stages

stages 中的 stage 会显示在 jenkins 任务主页中的 Stage View 中。每个 stage 可以有很多个 steps,我们可以执行构建命令。

1
2
3
4
5
stage('打印环境变量') {
steps {
sh "printenv"
}
}

如果你不知道支持哪些流水线脚本,可以在任务主页中点击【Pipeline Syntax】进入页面,选择示例步骤,生成流水线脚本。

当然,可以在 steps 中使用 script 支持 groovy 脚本。比如以下脚本,在不同构建环境下设置不同的环境变量。

1
2
3
4
5
6
7
8
9
10
11
12
stage('设置network') {
steps {
script {
if (env.DEPLOY_ENV == 'test') {
env.NETWORK='host'
} else {
env.NETWORK=''
}
}
sh 'printenv'
}
}

7. post

构建完成功或失败后,会触发后置处理

1
2
3
4
5
6
7
8
9
post {
success {
sh 'printenv'
}

failure {
echo 'build error'
}
}

8. 字符串

groovy 有多种字符串定义的方式,只有双引号字符串可以插入参数。

1
2
3
4
5
6
7
8
9
10
11
12
13
'hello, world'

"hello, ${PARAMS}"

'''
hello,
world!
'''

"""
hello,
${PARAMS}
"""

9. 钉钉群通知

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
post {
success {
script {
def markdown = """
#### "${env.JOB_NAME} 部署成功 [${env.BUILD_NUMBER}]"
"""
def json = """
{
"msgtype": "markdown",
"markdown": {
"title": "杭州天气",
"text": "${markdown}"
},
}
"""
sh "curl -H 'Content-Type:application/json' -X POST --data '${json}' ${DINGDING_ROBOT_URL}"
}
}
}

最好能够将上面的 json 拼接抽象成函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
pipeline {
// ...
post {
success {
script {
def json = buildJSON('构建成功', '#### 构建成功...')
sh "curl -H 'Content-Type:application/json' -X POST --data '${json}' ${DINGDING_ROBOT_URL}"
}
}
}
}

def buildJSON(title, markdown) {
return """
{
"msgtype": "markdown",
"markdown":{
"title": "${title}",
"text":"${markdown}"
}
}
"""
}

10. 常见问题

  • 构建异常 failed to unshare namespaces: Cannot allocate memory

    1
    2
    3
    [91mnsenter: failed to unshare namespaces: Cannot allocate memory
    [0m[91mcontainer_linux.go:262: starting container process caused "process_linux.go:247: running exec setns process for init caused \"exit status 34\""
    [0moci runtime error: container_linux.go:262: starting container process caused "process_linux.go:247: running exec setns process for init caused \"exit status 34\""

    解决方案:连接 jenkins 服务器,执行 echo 1 > /proc/sys/vm/drop_caches 释放内存

  • 待更新。。

学习链接:

-------------本文结束感谢您的阅读-------------