devops系列三:windows下Jenkins-pipeline

前言

之前使用jenkins构建了自由风格软件项目,此文主要聊聊流水线项目(pipeline)构建

Pipeline简介

1.概念

Jenkins Pipeline是一套插件,支持将连续输送Pipeline实施和整合到Jenkins。Pipeline提供了一组可扩展的工具,用于通过PipelineDSL为代码创建简单到复杂的传送Pipeline

简单来说就是Pipeline是一套插件,可以将原本独立运行单个或多个节点的任务连接起来,完成单个任务难以完成的复杂流程编排和可视化

2.使用Pipeline的好处

  • 代码:Pipeline以代码的形式实现,通常被检入源代码控制,使团队能够编辑,审查和迭代其传送流程。
  • 耐用:Pipeline可以在计划和计划外重新启动Jenkins管理时同时存在。
  • Pausable:Pipeline可以选择停止并等待人工输入或批准,然后再继续Pipeline运行。
  • 多功能:Pipeline支持复杂的现实世界连续交付要求,包括并行分叉/连接,循环和执行工作的能力。
  • 可扩展:Pipeline插件支持其DSL的自定义扩展 以及与其他插件集成的多个选项。

3.如何创建Jenkins Pipeline

Pipeline 脚本是由 Groovy 语言实现的,但是我们没必要单独去学习 Groovy

Pipeline 支持两种语法:Declarative(申明式)和 Scripted Pipeline(脚本式)语法

Pipeline 也有两种创建方法:可以直接在 Jenkins 的 Web UI 界面中输入脚本;也可以通过创建一 个 Jenkinsfile 脚本文件放入项目源码库中(一般我们都推荐在 Jenkins 中直接从源代码控制(SCM) 中直接载入 Jenkinsfile Pipeline 这种方法)。

Pipeline入门

1.申明式

image

image

pipeline {
    agent any

    stages {
        stage('Hello') {
            steps {
                echo 'Hello World'
            }
        }
    }
}

agent 表示Jenkins应该为Pipeline的这一部分分配一个执行者和工作区。

stages 代表整个流水线的所有执行阶段,通常stages只有一个,里面包含多个stage

stage 描述了这条Pipeline的一个阶段,一般分为拉取代码、编译、构建、部署等阶段

steps表示一个阶段内执行的逻辑

如下为一个简单的流水线

pipeline {
    agent any
    stages {
        stage('拉取代码') {
            steps {
                	echo '拉取代码'
                }
            }
            stage('编译构建') {
                steps {
                	echo '编译构建'
                }
            }
            stage('项目部署') {
                steps {
                	echo '项目部署'
                }
        }
    }
}

保存点击构建

image

2.脚本式

image

修改为Scripted Pipeline出现如下示例

node {
    def mvnHome
    stage('Preparation') { // for display purposes
        // Get some code from a GitHub repository
        git 'https://github.com/jglick/simple-maven-project-with-tests.git'
        // Get the Maven tool.
        // ** NOTE: This 'M3' Maven tool must be configured
        // **       in the global configuration.
        mvnHome = tool 'M3'
    }
    stage('Build') {
        // Run the maven build
        withEnv(["MVN_HOME=$mvnHome"]) {
            if (isUnix()) {
                sh '"$MVN_HOME/bin/mvn" -Dmaven.test.failure.ignore clean package'
            } else {
                bat(/"%MVN_HOME%\bin\mvn" -Dmaven.test.failure.ignore clean package/)
            }
        }
    }
    stage('Results') {
        junit '**/target/surefire-reports/TEST-*.xml'
        archiveArtifacts 'target/*.jar'
    }
}

Node:节点,一个 Node 就是一个 Jenkins 节点,Master 或者 Agent,是执行 Step 的具体运行 环境,后续讲到Jenkins的Master-Slave架构的时候用到。

Stage:阶段,一个 Pipeline 可以划分为若干个 Stage,每个 Stage 代表一组操作,比如: Build、Test、Deploy,Stage 是一个逻辑分组的概念。

Step:步骤,Step 是最基本的操作单元,可以是打印一句话,也可以是构建一个 Docker 镜像, 由各类 Jenkins 插件提供,比如命令:sh ‘make’,就相当于我们平时 shell 终端中执行 make 命令 一样。

备注:申明式脚本式针对脚本式语法的升级,理论上脚本式能做的申明式都能做,申明式也能调用脚本,所以主要学习申明式的语法

3.脚本生成器

image

在创建流水线的时候可以点击流水线语法,来通过脚本生成器生成脚本

image

如拉取代码

image

image

点击生成

checkout([$class: 'SubversionSCM', additionalCredentials: [], excludedCommitMessages: '', excludedRegions: '', excludedRevprop: '', excludedUsers: '', filterChangelog: false, ignoreDirPropChanges: false, includedRegions: '', locations: [[cancelProcessOnExternalsFail: true, credentialsId: 'xxx', depthOption: 'infinity', ignoreExternalsOption: true, local: '.', remote: 'http://xxx.xxx.xxx.xxx:666/svn/Mxxx/xxxxk']], quietOperation: true, workspaceUpdater: [$class: 'UpdateUpdater']])

如编译的话可以使用,之前配置过工具

image

然后部署可以执行以下脚本

image

然后就拼凑出了我们项目使用的脚本

Pipeline语法

声明Pipeline

声明性Pipeline是Jenkins Pipeline 的一个相对较新的补充, 它在Pipeline子系统之上提出了一种更为简化和有意义的语法。

所有有效的声明性Pipeline必须包含在一个pipeline块内

声明性Pipeline中有效的基本语句和表达式遵循与Groovy语法相同的规则 ,但有以下例外:

  • Pipeline的顶层必须是块,具体来说是:pipeline
  • 没有分号作为语句分隔符。每个声明必须在自己的一行
  • 块只能包含章节, 指令,步骤或赋值语句。
  • 属性引用语句被视为无参数方法调用。所以例如,输入被视为input()

Sections

声明性Pipeline中的部分通常包含一个或多个指令或步骤

agent

agent部分指定整个Pipeline或特定阶段将在Jenkins环境中执行的位置,具体取决于该agent 部分的放置位置。该部分必须在pipeline块内的顶层定义 ,但阶段级使用是可选的。

需要
参数 如下面所描述的
允许 在顶级pipeline块和每个stage块中。

参数:

any

在任何可用的代理上执行Pipeline。例如:agent any

none

当在pipeline块的顶层应用时,将不会为整个Pipeline运行分配全局代理,并且每个stage部分将需要包含其自己的agent部分。例如:agent none

label

使用提供的标签在Jenkins环境中可用的代理上执行Pipeline或阶段性执行。例如:agent { label 'my-defined-label' }

node

agent { node { label 'labelName' } }行为相同 agent { label 'labelName' },但node允许其他选项(如customWorkspace)。

docker

执行Pipeline,或阶段执行,用给定的容器将被动态地供应一个节点预先配置成接受基于Docker-based Pipelines,或匹配的任选定义的节点上 label的参数。 docker还可以接受一个args可能包含直接传递给docker run调用的参数的参数。例如:agent { docker 'maven:3-alpine' }

dockerfile

使用从Dockerfile源存储库中包含的容器构建容器来执行Pipeline或阶段性执行 。为了使用此选项,Jenkinsfile必须从多分支Pipeline或“Pipeline从SCM”加载。通常这是Dockerfile源库的根源:agent { dockerfile true }。如果Dockerfile在另一个目录中建立,请使用以下dir选项:agent { dockerfile { dir 'someSubDir' } }。您可以docker build ...使用该additionalBuildArgs选项将其他参数传递给命令,如agent { dockerfile { additionalBuildArgs '--build-arg foo=bar' } }

customWorkspace

一个字符串。运行Pipeline或个人stageagent 是这个自定义的工作空间内的应用,而不是默认的。它可以是相对路径,在这种情况下,自定义工作区将位于节点上的工作空间根目录下,也可以是绝对路径

reuseNode

一个布尔值,默认为false。如果为true,则在同一工作空间中,而不是完全在新节点上运行Pipeline顶层指定的节点上的容器。

此选项适用于dockerdockerfile,并且仅在agent个人使用时才有效果stage

post

该post部分定义将在Pipeline运行或阶段结束时运行的操作。一些条件后的块的内支持post:部分 always,changed,failure,success,unstable,和aborted。这些块允许在Pipeline运行或阶段结束时执行步骤,具体取决于Pipeline的状态。

需要 没有
参数 没有
允许 在顶级pipeline块和每个stage块中。
条件
  • always

    运行,无论Pipeline运行的完成状态如何。

  • changed

    只有当前Pipeline运行的状态与先前完成的Pipeline的状态不同时,才能运行。

  • failure

    仅当当前Pipeline处于“失败”状态时才运行,通常在Web UI中用红色指示表示。

  • success

    仅当当前Pipeline具有“成功”状态时才运行,通常在具有蓝色或绿色指示的Web UI中表示。

  • unstable

    只有当前Pipeline具有“不稳定”状态,通常由测试失败,代码违例等引起,才能运行。通常在具有黄色指示的Web UI中表示。

  • aborted

    只有当前Pipeline处于“中止”状态时,才会运行,通常是由于Pipeline被手动中止。通常在具有灰色指示的Web UI中表示。

stages

包含一个或多个阶段指令的序列,该stages部分是Pipeline描述的大部分“工作”的位置。建议stages至少包含至少一个阶段指令,用于连续交付过程的每个离散部分,如构建,测试和部署。

需要
参数 没有
允许 只有一次,在pipeline块内。

steps

该steps部分定义了 在给定指令中执行的一系列一个或多个步骤stage。

需要
参数 没有
允许 在每个stage块内。

environment

该environment指令指定一系列键值对,这些对值将被定义为所有步骤的环境变量或阶段特定步骤,具体取决于environment指令位于Pipeline中的位置。

该指令支持一种特殊的帮助方法credentials(),可以通过其在Jenkins环境中的标识符来访问预定义的凭据。对于类型为“Secret Text”的凭据,该 credentials()方法将确保指定的环境变量包含Secret Text内容。对于“标准用户名和密码”类型的凭证,指定的环境变量将被设置为, username:password并且将自动定义两个附加的环境变量:MYVARNAME_USR和MYVARNAME_PSW相应的。

需要 没有
参数 没有
允许 pipeline块内或stage指令内。

options

该options指令允许在Pipeline本身内配置Pipeline专用选项。Pipeline提供了许多这些选项,例如buildDiscarder,但它们也可能由插件提供,例如 timestamps。

需要 没有
参数 没有
允许 只有一次,在pipeline块内。
  • buildDiscarder

    持久化工件和控制台输出,用于最近Pipeline运行的具体数量。例如:options { buildDiscarder(logRotator(numToKeepStr: '1')) }

  • disableConcurrentBuilds

    不允许并行执行Pipeline。可用于防止同时访问共享资源等。例如:options { disableConcurrentBuilds() }

  • skipDefaultCheckout

    agent指令中默认跳过来自源代码控制的代码。例如:options { skipDefaultCheckout() }

  • skipStagesAfterUnstable

    一旦构建状态进入了“不稳定”状态,就跳过阶段。例如:options { skipStagesAfterUnstable() }

  • timeout

    设置Pipeline运行的超时时间,之后Jenkins应该中止Pipeline。例如:options { timeout(time: 1, unit: 'HOURS') }

  • retry

    失败后,重试整个Pipeline指定的次数。例如:options { retry(3) }

  • timestamps

    预处理由Pipeline生成的所有控制台输出运行时间与发射线的时间。例如:options { timestamps() }

parameters

该parameters指令提供用户在触发Pipeline时应提供的参数列表。这些用户指定的参数的值通过该params对象可用于Pipeline步骤

需要 没有
参数 没有
允许 只有一次,在pipeline块内。
可用参数
  • string

    字符串类型的参数,例如: parameters { string(name: 'DEPLOY_ENV', defaultValue: 'staging', description: '') }

  • booleanParam

    一个布尔参数,例如: parameters { booleanParam(name: 'DEBUG_BUILD', defaultValue: true, description: '') }

triggers

该triggers指令定义了Pipeline应重新触发的自动化方式。对于与源代码集成的Pipeline,如GitHub或BitBucket,triggers可能不需要基于webhook的集成可能已经存在。目前只有两个可用的触发器是cron和pollSCM。

需要 没有
参数 没有
允许 只有一次,在pipeline块内。
  • cron

    接受一个cron风格的字符串来定义Pipeline应重新触发的常规间隔,例如: triggers { cron('H 4/* 0 0 1-5') }

  • pollSCM

    接受一个cron风格的字符串来定义Jenkins应该检查新的源更改的常规间隔。如果存在新的更改,则Pipeline将被重新触发。例如:triggers { pollSCM('H 4/* 0 0 1-5') }

stage

该stage指令在该stages部分中,应包含步骤部分,可选agent部分或其他特定于阶段的指令。实际上,Pipeline完成的所有实际工作都将包含在一个或多个stage指令中。

需要 最后一个
参数 一个强制参数,一个用于舞台名称的字符串。
允许 stages部分内。

tools

定义自动安装和放置工具的部分PATH。如果agent none指定,这将被忽略。

需要 没有
参数 没有
允许 pipeline块或stage块内。

工具名称必须在Jenkins 管理Jenkins全局工具配置中配置

when

该when指令允许Pipeline根据给定的条件确定是否执行该阶段。该when指令必须至少包含一个条件。如果when指令包含多个条件,则所有子条件必须为舞台执行返回true。这与子条件嵌套在一个allOf条件中相同(见下面的例子)。

更复杂的条件结构可使用嵌套条件建:not,allOf或anyOf。嵌套条件可以嵌套到任意深度。

需要 没有
参数 没有
允许 stage指令内
内置条件
  • branch

    当正在构建的分支与给出的分支模式匹配时执行阶段,例如:when { branch 'master' }。请注意,这仅适用于多分支Pipeline。

  • environment

    当指定的环境变量设置为给定值时执行阶段,例如: when { environment name: 'DEPLOY_TO', value: 'production' }

  • expression

    当指定的Groovy表达式求值为true时执行阶段,例如: when { expression { return params.DEBUG_BUILD } }

  • not

    当嵌套条件为false时执行阶段。必须包含一个条件。例如:when { not { branch 'master' } }

  • allOf

    当所有嵌套条件都为真时,执行舞台。必须至少包含一个条件。例如:when { allOf { branch 'master'; environment name: 'DEPLOY_TO', value: 'production' } }

  • anyOf

    当至少一个嵌套条件为真时执行舞台。必须至少包含一个条件。例如:when { anyOf { branch 'master'; branch 'staging' } }

实践

接着我尝试拼装了一下我的需求是这样的,定义三个过程checkout,build,publish,定义多选框勾选,可以自定义勾选选择步骤

1.通过脚本生成器生成参数 此处需要安装多选控件 Extended Choice Parameter

image

image

生成脚本

parameters {
  extendedChoice defaultValue: 'build', description: '自定义过程', multiSelectDelimiter: ',', name: 'zhao56', quoteValue: false, saveJSONParameterToFile: false, type: 'PT_CHECKBOX', value: 'checkout,build,publish', visibleItemCount: 3
}

2.发现有模糊匹配的语法(=~可以用于正则匹配)

(params.zhao56 =~ '.*checkout.*').matches()

最终拼成了下方的的内容

pipeline {
    agent any
    parameters {
        extendedChoice defaultValue: 'publish', description: '自定义过程', descriptionPropertyValue: '', multiSelectDelimiter: ',', name: 'zhao56', quoteValue: false, saveJSONParameterToFile: false, type: 'PT_CHECKBOX', value: 'checkout,build,publish', visibleItemCount: 3
        }
    stages {
        
        stage('checkout') {
            when { expression {(params.zhao56 =~ '.*checkout.*').matches() }}
            steps {
                echo "checkout"
            }
        }
        stage('build') {
            when { expression {(params.zhao56 =~ '.*build.*').matches() }}
            steps {
                echo 'build'
            }
        }
        stage('publish') {
            when { expression {(params.zhao56 =~ '.*publish.*').matches() }}
            steps {
                echo 'publish'
            }
        }
    }
}

3.效果

image

全部构建

image

部分构建

image

image

posted @ 2021-06-16 14:37  zhao56  阅读(1708)  评论(0编辑  收藏  举报