持续集成系统Jenkins [Pipeline语法|开发工具|删除workspace方法]

root
233
文章
0
评论
2021年9月6日18:30:35 评论 7567字阅读25分13秒

持续集成系统Jenkins [Pipeline语法|开发工具|删除workspace方法]

Jenkinsfile

Jenkinsfile的是实现Pipeline as Code的核心功能。 该文件用于描述流水线的过程。以下是一个简单的实例:

pipeline{
    //指定运行此流水线的节点
    agent { node { label "build"}}
    
    //管道运行选项
    options {
        skipStagesAfterUnstable()
    }
    //流水线的阶段
    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("流水线取消后,要做的事情")
            }
        
        }
    }
}
  • 使用agent{},指定流水线要运行的节点(可以使用名称或者标签)
  • 指定options{} 定义流水线运行时的一些选项
  • 指定stages{}(stages包含多个stage,stage包含steps。是流水线的每个步骤)
  • 指定post{}(定义好此流水线运行成功或者失败后,根据状态做一些任务)

Pipeline 开发工具

操作:

1.选择任意pipeline类型的作业,

2.点击“流水线语法”即可进入pipeline开发工具页面。

片段生成器

流水线代码片段生成器, 非常好用。在这里可以找到每个插件以及Jenkins内置的方法的使用方法。使用片段生成器可以根据个人需要生成方法,有些方法来源于插件,则需要先安装相关的插件才能使用哦。

通过上面的直接就可以放到pipeline 中的script里使用

pipeline{
    //指定运行此流水线的节点,指定标签的名字
    agent { node { label "build"}}

    //管道运行选项
    options {
        skipStagesAfterUnstable()
    }
    //流水线的阶段
    stages{
        //阶段1 获取代码
        stage("CheckOut"){
            steps{
                script{
                    sh '''
                        mkdir /xx
                        cd /xx
                        '''
                    println("获取代码")
                }
            }
        }
    }
}

运行任务效果

 

声明式语法生成器

可以生成声明式流水线语法的语句块。

全局变量参考

这些是已经安装的Jenkins插件和Jenkins内置的全局变量清单。

                   //打印变量
                    println("${BUILD_NUMBER}")  //局部变量
                    println("${env.BUILD_NUMBER}") //全局变量
                    //currentBuild
                    currentBuild.displayName = 'hwf'    //构建id
                    currentBuild.description = '今天是个好天气' //构建描述信息

Pipeline的核心语法

  • agent 构建节点
  • stages构建阶段
  • post 构建后操作
  • env 构建时变量
  • options 运行时选项
  • parameters 流水线参数
  • triggers 触发器
  • input 流水线交互
  • when 阶段运行控制
  • parallel 阶段并行

声明式流水线的定义, 一个pipeline{}。

pipeline {
     //pipeline 
}

1.agent 构建节点

参数:

  • any: 运行在任一可用节点。
  • none:当pipeline全局指定agent为none,则根据每个stage中定义的agent运行(stage必须指定)。
  • label:在指定的标签的节点运行。(标签=分组)
  • node:支持自定义流水线的工作目录。
## 一
pipeline {
	agent any
}

## 二
pipeline {
	agent { label "label Name" }
}


## 三 自定义节点[ 这种方法试了不行 ]
pipeline {
  agent { 
     node {
        label "labelName",
        customWorkspace "/opt/agent/workspace"
     }
  }
}

 

2.stages构建阶段

  • 关系: stages > stage > steps > script
  • 定义:
    • stages:包含多个stage阶段
    • stage:包含多个steps步骤
    • steps: 包含一组特定的脚本(加上script后就可以实现在声明式脚本中嵌入脚本式语法了)
pipeline {
	agent { label "build" }
  
  stages {
  		stage("build") {
      		steps {
          		echo "hello"
          }
      }
   }
}

扩展: 在阶段中定义agent

## 在阶段中定义agent

pipeline {

  agent none 
  
  stages{
  	stage('Build'){
    	agent { label "build" }
        steps {
            echo "building......"
        }
     }
  }
}

 

3.post 构建后操作

  • 定义: 根据流水线的最终状态匹配后做一些操作。
  • 状态:
    • always: 不管什么状态总是执行
    • success: 仅流水线成功后执行
    • failure: 仅流水线失败后执行
    • aborted: 仅流水线被取消后执行
    • unstable:不稳定状态,单侧失败等等
pipeline {
    
    .....
        
    .....
        
    post {
        always{
            script{
                println("流水线结束后,经常做的事情")
            }
        }
        
        success{
            script{
                println("流水线成功后,要做的事情")
            }
        
        }
        failure{
            script{
                println("流水线失败后,要做的事情")
            }
        }
        
        aborted{
            script{
                println("流水线取消后,要做的事情")
            }
        
        }
    }
}

 

4.env 构建时变量

定义: 通过键值对(k-v)格式定义流水线在运行时的环境变量, 分为流水线级别和阶段级别

流水线级别环境变量参考

pipeline {
    environment {
     	NAME = "zeyang"
        VERSION = "1.1.10"
        ENVTYPE = "DEV"
    }
}

阶段级别环境变量参考

pipeline {
    
    ...
    ...
    stages {
        stage("build"){
            environment {
                
                
                VERSION = "1.1.20"
            }
            steps {
                script {
                    echo "${VERSION}"
                }
            }
        }
    }
}

做实验,配置全局环境变量,和局部环境变量,调用变量

pipeline{
    //指定运行此流水线的节点,指定标签的名字
    agent { node { label "build"}}

    //管道运行选项
    options {
        skipStagesAfterUnstable()
    }
    //定义全局变量
    environment {
        NAME = "hwf"
        VERSION = "1.1.10"
        ENVTYPE = "DEV"
    }
    //流水线的阶段
    stages{
        //阶段1 获取代码
        stage("CheckOut"){
            //定义阶段1的变量
            environment {
                NAME = "hwf01"
                VERSION = "1.1.11"
                ENVTYPE = "DEV1"
            }
            steps{
                script{                    
                    //打印变量
                    println("${NAME}")  //局部变量
                    println("${VERSION}") //局部变量
                    println("${ENVTYPE}") //局部变量
                    println("${env.NAME}")  //全局变量
                    println("${env.VERSION}")  //全局变量
                    println("${env.ENVTYPE}")  //全局变量

                    //currentBuild
                    currentBuild.displayName = 'hwf'    //构建id
                    currentBuild.description = '今天是个好天气' //构建描述信息
                    println("获取代码")
                }
            }
        }
    }
}
        

效果如下:[当环境变量与局部变量名称相等时,局部变量优先级最高]

5.options 运行时选项

## 设置保存最近的记录
options { buildDiscarder(logRotator(numToKeepStr: '1')) }

## 禁止并行构建
options { disableConcurrentBuilds() }


## 跳过默认的代码检出
options { skipDefaultCheckout() }


## 设定流水线的超时时间(可用于阶段级别)
options { timeout(time: 1, unit: 'HOURS') }


## 设定流水线的重试次数(可用于阶段级别)
options { retry(3) }


## 设置日志时间输出(可用于阶段级别),解决任务输出没有时间,重要
options { timestamps() }

参考:

pipeline {
    options {
        disableConcurrentBuilds()
        skipDefaultCheckout()
        timeout(time: 1, unit: 'HOURS')
    }
    
    stages {
        stage("build"){
            options {
                timeout(time: 5, unit: 'MINUTES')
                retry(3)
                timestamps()
            }
        }
    }
}
    
}

FAQ: timestamps 报错, 需要安装插件 Timestamper 。

WorkflowScript: 21: Invalid option type "timestamps". Valid option types: [authorizationMatrix, buildDiscarder, catchError, checkoutToSubdirectory, disableConcurrentBuilds, disableResume, durabilityHint, lock, overrideIndexTriggers, parallelsAlwaysFailFast, preserveStashes, quietPeriod, rateLimitBuilds, retry, script, skipDefaultCheckout, skipStagesAfterUnstable, timeout, waitUntil, warnError, withChecks, withContext, withCredentials, withEnv, wrap, ws] @ line 21, column 3.
   		timestamps()
     ^

6.parameters 流水线参数

  • 定义: 流水线在运行时设置的参数,UI页面的参数。所有的参数都存储在params对象中。
  • 将web ui页面中定义的参数,以代码的方式定义。
  • 参数也是变量,参数里定义的值全局变量没有的,那么这个参数也是一个全局变量
pipeline {
    agent any
    
	parameters { 
        string(name: 'VERSION', defaultValue: '1.1.1', description: '') 
    }
    
    stages {
        stage("Build"){
            steps {
                echo "${params.VERSION}"
            }
        }
    }
}

修改全局变量的方法:

            steps{
                script{
                    //打印变量
                    println("${NAME}")  //局部变量
                    println("${env.NAME}")  //全局变量
                    println("${params.VERSION}") //打印参数
                    env.VERSION = "1.8.6" //修改全局变量的方法
                }
            }

FAQ: 没有找到相关的环境变量, 这个是我们在parameters中引用了流水线中的变量导致的,可能因为加载顺序不同导致的,解决方法是可以在pipeline{} 外部定义变量进行引用。

roovy.lang.MissingPropertyException: No such property: DEPLOY_DESC for class: groovy.lang.Binding
	at groovy.lang.Binding.getVariable(Binding.java:63)

 

triggers 触发器

  • 流水线的触发方式
    • cron 定时触发: triggers { cron('H */7 * * 1-5') } 
    • pollSCM: triggers { pollSCM('H */7 * * 1-5') } 
## upstream

triggers { 
    upstream(upstreamProjects: 'job1,job2', 
             threshold: hudson.model.Result.SUCCESS) 
}

demo:

pipeline {
    agent any
    triggers {
        cron('H */7 * * 1-5')
    }
    stages {
        stage('build') {
            steps {
                echo 'Hello World'
            }
        }
    }
}

input 流水线交互

参数解析

  • message: 提示信息
  • ok: 表单中确认按钮的文本
  • submitter: 提交人,默认所有人可以
  • parameters: 交互时用户选择的参数
stage("Build"){
    //input加到这里就是选择是否运行
    input {
        message '选择部署的环境'
        ok '提交'
        submitter 'hwf'
        parameters {
            choice choices: ['dev', 'test', 'stag', 'prod'], name: 'wnvtype'
        }
    }
    steps{
        script{
            println("运行构建")
            //要是想获取input的值,打印他的环境变量
            println("${wnvtype}")
    }
}

input {
message '选择部署的环境'
ok '提交'
submitter 'hwf'
parameters {
choice choices: ['dev', 'test', 'stag', 'prod'], name: 'Envtype'
}
}

when 阶段运行控制

判断条件

  • 根据环境变量判断
  • 根据表达式判断
  • 根据条件判断(not/allOf/anyOf)
pipeline {
    agent any
    stages {
        stage('Build') {
            steps {
                echo 'build......'
            }
        }
        stage('Deploy') {
            when {
                environment name: 'DEPLOY_TO', value: 'DEV'
            }
            steps {
                echo 'Deploying.......'
            }
        }
    }
}


###  allOf 条件全部成立
 when {
     allOf {
         environment name: 'CAN_DEPLOY', value: 'true'
         environment name: 'DEPLOY_ENV', value: 'dev'
     }
 }


### anyOf 条件其中一个成立
when {
     anyOf {
         environment name: 'CAN_DEPLOY', value: 'true'
         environment name: 'DEPLOY_ENV', value: 'dev'
     }
 }

 

parallel 阶段并行

场景: 自动化测试,多主机并行发布。

pipeline {
    agent any
    stages {
        stage('Parallel Stage') {
            failFast true  //当一个失败了,并行的就不执行了
            parallel {
                stage('windows') {
                    agent {
                        label "master"
                    }
                    steps {
                        echo "windows"
                    }
                }
                stage('linux') {
                    agent {
                        label "build"
                    }
                    steps {
                        echo "linux"
                    }
                }
            }
        }
    }
}

FAQ:如何解决并发构建中的workspace问题?
env.workspace = "/opt/agent/test/${JOB_NAME}-${UUID.randomUUID().toString()}"


pipeline{
	agent{
  	node{
    	label "build"
      customWorkspace "${env.nworkspace}"
    }
  }
 
  stages{
  	stage("build"){
    
    	steps{
      	echo "${env.nworkspace}"
      }
    }
  
  }
}


### 输出
demo-fec54ca7-81a5-452e-91b5-2a187ab3562b

做实验:

env.workspace = "/opt/agent/test/${JOB_NAME}-${UUID.randomUUID().toString()}"

pipeline{
    //指定运行此流水线的节点,指定标签的名字
    agent { node { label "build"}}

    //流水线的阶段
    stages{
        //阶段1 获取代码
        stage("CheckOut"){
            //定义阶段1的变量
            environment {
                NAME = "hwf01"
                VERSION = "1.1.11"
                ENVTYPE = "DEV1"
            }
            steps{
                script{
                    ws("${env.nworkspace}") {
                        sh '''
                        mkdir -p job-${BUILD_ID}
                        echo "${BUILD_ID}" > job-${BUILD_ID}/build.txt
                        '''
                }
            }
        }
}

这样就保证了,每个次执行任务的数据都放在一个不同的目录里,避免了脏数据

[root@jeekins ~]# tree /opt/agent/test/ |grep -v tmp
/opt/agent/test/
├── build-01-a3194cbc-b854-4b0a-a29d-0d2364be5aa4
│   └── job-44
│           └── build.txt
├── build-01-b5a38cf7-02e4-4ac5-a58a-46b44082bf02
│   └── job-45
│           └── build.txt
├── build-01-f23215be-2791-4416-8de7-babe2486654a
│   └── job-46
│          └── build.txt

 

删除workspace方法

  • Workspace Cleanup【删除任务存储目录插件】

post {
        always{
            script{
                println("流水线结束后,经常做的事情")
                cleanWs cleanWhenFailure: false, cleanWhenNotBuilt: false, cleanWhenUnstable: false
            }
        }
}

2.使用命令

    post {
        always{
            script{
                println("流水线结束后,经常做的事情")
                sh "rm -rf ${env.nworkspace} "
            }
        }

        success{
            script{
                println("流水线成功后,要做的事情")
            }

        }

查看文件是否存在

[root@jeekins ~]# ll /opt/agent/test/build-01-d2149936-38c9-4b6e-939d-1f2a8e4812d6
ls: 无法访问/opt/agent/test/build-01-d2149936-38c9-4b6e-939d-1f2a8e4812d6: 没有那个文件或目录

 

 

 

继续阅读
weinxin
我的微信
这是我的微信扫一扫
  • 文本由 发表于 2021年9月6日18:30:35
  • 除非特殊声明,本站文章均为原创,转载请务必保留本文链接
jenkins-邮件通知|gitlab配置邮箱 Jenkins

jenkins-邮件通知|gitlab配置邮箱

jenkins-邮件通知|gitlab配置邮箱 gitlab-配置邮箱地址 默认情况可能每个Gitlab用户没有配置邮箱的, 需要Gitlab用户要配置好邮箱。 点击头像进入 edit profile...
匿名

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: