目录

pipeline是什么

具体有什么用

pipeline语法

声明式语法


pipeline是什么

从某种抽象层次上讲,部署流水。是指从版本控制库到用户手中这一过程的自动化表现形,并且可以做到持续交付。

具体有什么用

人话就是,Pipeline可以做到从版本库下载代码,进行编译打包,发送至目标机器,并部署,整个流程就被称为Jenkins的Pipeline。

pipeline语法

分为两种:

  1. 脚本式语法
  2. 声明式语法(Jenkins社区推荐)

Jenkins团队在一开始实现Jenkinspipelin时,Groovy语言被选择作为基础来实现pipeline,所以写pipeline脚本时,就是在写Groovy,被称为脚本式语法

pipeline插件从2.5版开始,同时支持了声明式语法,是一种更简单,更结构化的语法。

声明式语法

pipeline {
    // 表示任何可以执行的节点均可
    // agent any
    agent{ 
        // 通过Manage Jenkins -> Manage Nodes增加节点配置
        // 指定由哪个节点机器执行这个pipeline
        // master默认为安装Jenkins所在的机器
        node{
            label 'master'
            customWorkspace '/home/jenkins/workspace/webflux/' //默认工作空间
        }
    } 
    tools {
        // 检测maven-3.6.3,自动下载,并将其加入PATH变量中
        // maven-3.6.3名称在全局工具配置里的Maven中指定
        maven 'maven-3.6.3'
    }
    options {
        // 重试次数
        retry(4)
        // 超时 HOURS MINUTES SECONDS
        timeout(time: 10; unit: 'SECONDS')
        // 保存最近历史构建记录的数量,只能在pipeline下使用
        buildDiscarder(logRotator(numToKeepStr: '10'))
        // 从版本库下去源码时检出到工作空间的根目录名称
        checkoutToSubdirectory('subdir')
        // 禁止当前pipeline同时多次执行
        disableConcurrentBuilds()
    }
    parameters {
        // booleanParam(name: 'booleanTest', description: '', defaultValue: true)
        // password(name: 'passwordTest', description: '', defaultValue: 'passwordTest')
        // text(name: 'textTest', description: '', defaultValue: '其中\n表示换行')
        
        choice(name: 'publish_host', description: '发布节点', choices: '192.168.1.101\n192.168.1.102\n')
        choice(name: 'branches_version', description: '发布版本', choices: '1.0.1\n1.0.2\n')
        string(name: 'Mail_recipient', description: '通知邮件', defaultValue: '')
    }
    stages {
        stage('回显阶段') {
            steps {
                echo "echo hello"
                // 打印环境变量,sh执行shell命令
                sh "printenv"
            }
            post {
                always {
                    echo "回显阶段执行完成"
                    // 主动报错,终止当前pipeline
                    // error('模拟报错')
                }
            }
        }
        stage {
            steps {
                // 写Groovy代码需要在scropt中,否则报错
                script {
                    def list = ['Java', 'C++']
                    for (int i = 0; i < list.size(); ++i) {
                        // 双引号才可以作插值${}
                        echo "开发语言: ${list[i]}"
                    }
                }
            }
        }
        stage {
            steps {
                script {
                    // Jenkins Pipeline内置步骤

                    // 切换目录
                    dir()
                    // 删除当前目录,无参步骤
                    deleteDir()
                    // 判断文件是否存在
                    fileExists('/tmp/a.jar')
                    // 是否Unix系统
                    isUnix()
                    // 当前目录
                    pwd()
                    // 写文件
                    writeFile file: './test', text: '要写入的文件内容', encoding: 'UTF-8'
                    // 读文件
                    readFile file: './test', encoding: 'UTF-8')

                    // 使用预定义工具(在全局工具配置中配置的工具)
                    def t = tool name: 'maven'
                    echo "${t}" // 打印maven路径

                    // 睡眠5秒
                    sleep time: '5', unit: 'SECONDS'
                }
            }
        }
        // 以下是工程只需交付流程实例
        stage('代码下载') {
            steps {
                // 定位到./code目录下执行后面代码
                dir('code'){
                    echo '代码下载'
                    // 可以在编辑pipeline时的下方点击Pipeline Syntax,接着
                    // 进入片段生成器,选择checkout: Check out from version control,进行生成
                    // 配置版本库使用到账号密码,需要添加凭证,凭证 -> 系统 -> 全局凭证 ->  Add Credentials,选择Username with password
                    checkout([$class: 'SubversionSCM', additionalCredentials: [], excludedCommitMessages: '', excludedRegions: '', excludedRevprop: '', excludedUsers: '', filterChangelog: false, ignoreDirPropChanges: false, includedRegions: '', locations: [[cancelProcessOnExternalsFail: true, credentialsId: 'svn', depthOption: 'infinity', ignoreExternalsOption: true, local: '.', remote: '192.168.1.103/Branches/$branches_version/Src/yiling']], quietOperation: true, workspaceUpdater: [$class: 'UpdateUpdater']])
                }
            }
        }
        stage('编译打包') {
            steps {
                dir('code/yiling-server'){
                    echo '编译打包'
                    // 使用Maven编译
                    sh 'source /etc/profile && mvn clean package -Dmaven.test.skip=true  -Dyiling-version=$branches_version'
                    // 打包成tar.gz文件
                    sh 'cd target/ && tar -czvf yiling-server.tar.gz yiling-server_lib yiling-server.jar conf/bex conf/mapper && cp yiling-server.tar.gz /opt/yiling-jar/yiling-server.$branches_version.tar.gz'
                }
            }
        }
        stage('发布到192.168.1.101环境') {
            // 当publish_host是192.168.1.101时才执行steps
            when { environment name: 'publish_host', value: '192.168.1.101' }
            steps {
                dir('code/yiling-server'){
                    echo '发布到192.168.1.101环境'
                    // 将资源包推送到目标机器的指定路径下
                    // 进入片段生成器,选择sshPublisher: Send build artifacts over SSH,进行生成。
                    // 需要配置ssh,通过Manage Jenkins -> Configure System -> Publish over SSH增加SSH Servers,配置主机ip、port为22,登录用户名和密码即可
                    sshPublisher(publishers: [sshPublisherDesc(configName: '192.168.1.101', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: '', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: 'E:\\yiling-jar\\yiling-server', remoteDirectorySDF: false, removePrefix: 'target/', sourceFiles: 'target/yiling-server.tar.gz')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
                }
            }
        }
        stage('发布到192.168.1.102环境') {
            when { environment name: 'publish_host', value: '192.168.1.102' }
            steps {
                dir('code/yiling-server'){
                    echo '发布到192.168.1.102环境'
                    sshPublisher(publishers: [sshPublisherDesc(configName: '192.168.1.102', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: 'sh /opt/yiling-jar/yiling-server/deploy.sh', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '/opt/yiling-jar/yiling-server', remoteDirectorySDF: false, removePrefix: 'target/', sourceFiles: 'target/yiling-server.tar.gz')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
                }
            }
        }
       stage('192.168.1.101启动服务') {
            when { environment name: 'publish_host', value: '192.168.1.101' }
            agent{
                // 表示这个steps在指定label的从节点执行
                // 通过Manage Jenkins -> Manage Nodes增加从节点配置
                // 并且需要保证从节点与主节点的连通性,需要把jenkins.jar拷贝至从节点,并运行指定命令
                node{
                    label 'Node192.168.1.101'
                }
            }
            steps {
                // 切换目录,执行deploy.bat脚本
                dir('E:\\yiling-jar\\yiling-server') {
                    withEnv(['JENKINS_NODE_COOKIE=dontkillme']) {
                        echo '启动服务'
                        bat "deploy.bat"
                    }
                }
            }
        }
    }
    //构建后操作
    post {
        always {
            echo "things always to run"
        }
        // 终止状态就执行
        aborted {
            echo "things to run only for when the pipeline is aborted"
        }
        success {
            echo "things to run only for when the pipeline is Successful"
        }
        /*
        // 与上次不同就执行
        changed {
            echo "与上次不同就执行"
        }
        */
        failure {
            echo "things to run only for when the pipeline is Failed"
            // 安装Email Extension插件
            // 进入Manage Jenkins→Configure System→Extended E-mail Notificatio配置
            emailext body: '$DEFAULT_CONTENT', subject: '$DEFAULT_SUBJECT', to: '$Mail_recipient'

            // Extended E-mail Notification配置模板
            /*
            Default Subject:
            $PROJECT_NAME - Build # $BUILD_NUMBER - $BUILD_STATUS!

            Maximum Attachment Size: 
            5

            Default Content:
            <!DOCTYPE html>    
            <html>    
            <head>    
            <meta charset="UTF-8">    
            <title>${ENV, var="JOB_NAME"}-第${BUILD_NUMBER}次构建日志</title>    
            </head>    
                
            <body leftmargin="8" marginwidth="0" topmargin="8" marginheight="4"    
                offset="0">    
                <table width="95%" cellpadding="0" cellspacing="0"  style="font-size: 11pt; font-family: Tahoma, Arial, Helvetica, sans-serif">    
                    <tr>    
                        本邮件由系统自动发出,无需回复!<br/>            
                        各位同事,大家好,以下为${PROJECT_NAME }项目构建信息</br> 
                        <td><font color="#CC0000">构建结果 - ${BUILD_STATUS}</font></td>   
                    </tr>    
                    <tr>    
                        <td><br />    
                        <b><font color="#0B610B">构建信息</font></b>    
                        <hr size="2" width="100%" align="center" /></td>    
                    </tr>    
                    <tr>    
                        <td>    
                            <ul>    
                                <li>项目名称 : ${PROJECT_NAME}</li>    
                                <li>构建编号 : 第${BUILD_NUMBER}次构建</li>    
                                <li>触发原因: ${CAUSE}</li>    
                                <li>构建状态: ${BUILD_STATUS}</li>    
                                <li>构建日志: <a href="${BUILD_URL}console">${BUILD_URL}console</a></li>    
                                <li>构建  Url : <a href="${BUILD_URL}">${BUILD_URL}</a></li>    
                                <li>工作目录 : <a href="${PROJECT_URL}ws">${PROJECT_URL}ws</a></li>    
                                <li>项目  Url : <a href="${PROJECT_URL}">${PROJECT_URL}</a></li>    
                            </ul>   
                            
            详细提交: <a href="${PROJECT_URL}changes">${PROJECT_URL}changes</a><br/>

                        </td>    
                    </tr>    
                </table>    
            </body>    
            </html>

            Default Pre-send Script:
            import hudson.model.*;

            */
        }
    }
}