jenkins—Pipeline使用测试
安装jenkins
# jar包启动
https://sg.mirror.servanamanaged.com/jenkins/war-stable/2.346.1/jenkins.war
https://download.oracle.com/java/17/latest/jdk-17_linux-x64_bin.tar.gz
[root@vm ~]# tail /etc/profile
...
export JAVA_HOME=/opt/jdk17
export PATH=$PATH:$JAVA_HOME/bin
[root@vm ~]# source /etc/profile
[root@vm ~]# java -version
java version "17.0.10" 2024-01-16 LTS
[root@vm ~]# nohup java -Dhudson.model.DownloadService.noSignatureChecke=true -DJENKINS_HOME=/app/ -jar /app/jenkins.war &
[root@vm ~]# cat /opt/jenkins_home/secrets/initialAdminPassword
# docker 启动
~]# curl -o /etc/yum.repos.d/docker.repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
~]# curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
[root@jenkins ~]# yum -y install docker-ce-19.03.7-3.el7
[root@jenkins ~]# vim /etc/docker/daemon.json
{
"registry-mirrors": [
"https://registry.docker-cn.com",
"http://hub-mirror.c.163.com",
"https://docker.mirrors.ustc.edu.cn"
]
}
[root@jenkins ~]# docker run -d --name jenkins -p 8080:8080 -u root -v /opt/jenkins_home:/var/jenkins_home -v /var/run/docker.sock:/var/run/docker.sock -v /usr/bin/docker:/usr/bin/docker -v /usr/local/maven:/usr/local/maven -v /usr/local/jdk:/usr/local/jdk -v /etc/localtime:/etc/localtime --restart=always jenkins/jenkins:2.328
安装声明式插件Pipeline:Declarative
Jenkinsfile组成
指定节点agent # node workspace
运行选项options
指定阶段stages
指定构建后操作post
创建pipeline流水线
Pipeline script #直接写groovy语法构建编译
Pipeline script from SCM #将上面的构建编译语句写到文件内(Jenkinsfile)并放到代码仓,这里指定文件位置及没名字
样例
string workspace = "/app/jobs/pipeline_test"
pipeline {
//1、指定node节点/workspace
agent any
//2、构建运行选项
options {
timestamps() //日志会有时间
skipDefaultCheckout() //删除隐式checkout scm语句
disableConcurrentBuilds() //禁止并行
timeout(time:1,unit:'HOURS') //流水线超时设置1h
}
// 3、指定stages阶段 (一个或多个)解释:在这里添加了三个阶段
stages {
//下载代码
stage("GetCode"){ //阶段名称
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("代码扫描")
}
}
}
}
}
// 4、指定构建后操作,post 与 stages 是同级
post {
always {
script{
println("always")
}
}
success {
script{
currentBuild.description += "\n 构建成功!"
}
}
failure {
script{
currentBuild.description += "\n 构建失败!"
}
}
aborted {
script{
currentBuild.description += "\n 构建取消!"
}
}
}
}
1.1 agent(代理)
agent 指定了流水线的执行节点。
参数:
any 在任何可用的节点上执行pipeline。
none 没有指定agent的时候默认
label 在指定标签上的节点上运行Pipeline。
node 允许额外的选项。
这两种是一样的
agent { node { label 'labelname' }}
agent { label 'labelname' }
1.2 stages(阶段)
包含一系列一个或多个 stage 指令,建议 stages 至少包含一个 stage 指令用于连续交付过程的每个离散部分,比如构建,测试,和部署。
1.3 post
定义一个或多个steps,这些阶段根据流水线或阶段的完成情况而 运行(取决于流水线中 post部分的位置).post支持以下 post-condition 块中的其中之一: always, changed,failure,success,unstable,和 aborted。这些条件块允许在 post部分的步骤的执行取决于流水线或阶段的完成状态。
always 无论流水线或者阶段的完成状态
changed 只有当流水线或者阶段完成状态与之前不同时。
failure 只有当流水线或者阶段状态为”failure”运行,
success 只有当流水线或者阶段状态为”success”运行。
unstable 只有当流水线或者阶段状态为”unstable”运行。例如:测试失败。
aborted 只有当流水线或者阶段状态为"aborted“运行。例如:手动取消,
1.4 steps(步骤)
step是每个阶段中要执行的每个步骤。
pipeline {
agent any
stages {
stage('Example'){
steps {
echo 'Hello World'
}
}
}
post{
always{
echo 'I will always say Hello again!'
}
}
}
1.5 指令
1.5.1 environment
environment 指令指定一个键值对序列,该序列将被定义为所有步骤的环境变量,或者是特定于阶段的步骤,这取决于 environment 指令在流水线内的位置。
该指令支持一个特殊的方法 credentials(),该方法可用于在Jenkins环境中通过标识符访问预定义的凭证。
对于类型为“Secret Text”"的凭证,credentials()将确保指定的环境变量包含秘密文本内容。
对于类型为“SStandard username and password”的凭证,指定的环境变量指定为username:password,并目两个额外的环境变量将被自动定义:分别为,MYVABNAME USB 和 MYVABNAME PSW
pipeline {
agent any
environment {
CC ='clang'
}
stages {
stage('Example'){
steps {
sh 'printenv'
echo 'Hello World'
println("${env.CC}")
}
}
}
post{
always{
echo 'I will always say Hello again!'
}
}
}
1.5.2 options
options 指令允许从流水线内部配置特定于流水线的选项。流水线提供了许多这样的选项,比如buildDiscarder,但也可以由插件提供,比如timestamps,也可以是参数化构建的自定义参数 ${自定义参数}
buildDiscarder: 为最近的流水线运行的特定数量保存组件和控制台输出
disableConcurrentBuilds:不允许同时执行流水线。可被用来防止同时访问共享资源等overrideIndexTriggers: 允许覆盖分支索引触发器的默认处理。
skipDefaultCheckout: 在 agent 指令中,跳过从源代码控制中检出代码的默认情况skipStagesAfterUnstable:-旦构建状态变得UNSTABLE,跳过该阶段。
checkoutToSubdirectory: 在工作空间的子目录中自动地执行源代码控制检出。
timeout: 设置流水线运行的超时时间,在此之后,Jenkins将中止流水线。
retry: 在失败时,重新尝试整个流水线的指定次数。
timestamps 预测所有由流水线生成的控制台输出,与该流水线发出的时间一致。
1.5.3 parameters
为流水线运行时设置项目相关的参数,参数的使用需pipeline运行一次后生效,再次运行才能调用
生产的参数会体现在参数化构建的web页面上
web上可以做参数化构建设置,pipeline 调用
// string 字符串类型的参数
parameters { string(name: 'DEPLOY_ENV',defaultValue: 'staging',description: '')}
//booleanParam 布尔参数
parameters f booleanParam(name: 'DEBUG_BUILD', defaultValue: true, description: '')
pipeline {
agent any
// string 字符串类型的参数
parameters { string(name: 'DEPLOY_ENV',defaultValue: 'staging',description: '')}
//booleanParam 布尔参数
//parameters { booleanParam(name: 'DEBUG_BUILD', defaultValue: true, description: '')}
environment {
CC ='clang'
}
stages {
stage('Example'){
steps {
println("${DEPLOY_ENV}") //pipeline shang 设置的参数
println("${plug_set}") // web上设置的参数化构建
echo 'Hello World'
println("${env.CC}")
}
}
}
}
1.5.4 触发器
构建触发器
// cron 计划任务定期执行构建,
triggers { cron('H */4 ** 1-5')}
// polISCM 与cron定义类似,但是由jenkins定期检测源码变化。
triggers { pollSCM('H */4 ** 1-5')}
// upstream 接受逗号分隔的工作字符串和阈值。 当字符串中的任何作业以最小阈值结束时,流水线被重新触发。
triggers { upstream(upstreamProjects: 'job1,job2', threshold: hudson.model.Result.SuCcEsS) }
pipeline {
agent any
triggers {
cron('H/2 * * * *') // 没两分钟执行一次
}
stages {
stage('Example') {
steps {
echo 'Hello World'
}
}
}
}
1.5.5 tool
获取通过自动安装或手动放置工具的环境变量。支持maven/idk/gradle。工具的名称必须在系统设置->全局工县配置中定义
pipeline {
agent any
tools {
jdk 'jdk17' // jdk17 与全局配置里的名字保持一致
// jdk 固定命名,Valid tool types: [ant, hudson.tasks.Ant$AntInstallation, git, hudson.plugins.git.GitTool, gradle, hudson.plugins.gradle.GradleInstallation, jdk, hudson.model.JDK, jgit, org.jenkinsci.plugins.gitclient.JGitTool, jgitapache, org.jenkinsci.plugins.gitclient.JGitApacheTool, maven, hudson.tasks.Maven$MavenInstallation]
}
stages {
stage('Example'){
steps {
echo 'Hello World'
script {
JavaHome = tool 'jdk17' // 工具名
println(JavaHome)
}
}
}
}
}
1.5.6 input 输入交互
input用户在执行各个阶段的时候,由人工确认是否继续进行,
message 呈现给用户的提示信息
id 可选,默认为stage名称。
ok 默认表单上的ok文本
submitter 可选的,以逗号分隔的用户列表或允许提交的外部组名。默认允许任何用户
submitterParameter 环境变量的可选名称。如果存在,用 submitter 名称设置。
parameters 提示提交者提供的一个可选的参数列表,
参考生成流水线脚本,自动生成
pipeline {
agent any
stages {
stage('Example') {
input {
message "Should we continue?"
ok "Yes, we should."
submitter "admin"
parameters {
string(name: 'PERSON', defaultValue: 'Mr Jenkins', description: 'Who should I say hello to?')
}
}
steps {
echo "Hello, ${PERSON}, nice to meet you."
}
}
}
}
输入后执行
1.5.7 when
when 指令允许流水线根据给定的条件决定是否应该执行阶段。whn指令必须包含至少一个条件。如果when指令包含多个条件,所有的子条件必须返回Tue,阶段才能执行这与子条件在 allOf 条件下嵌套的情况相同。
内置条件
branch: 当正在构建的分支与模式给定的分支匹配时,执行这个阶段,这只适用于多分支流水线例如:
when { branch 'master' }
environment: 当指定的环境变量是给定的值时,执行这个步骤,例如:
when { environment name: 'DEPLOY_TO', value: 'production' }
expression 当指定的Groovy表达式评估为true时,执行这个阶段, 例如:
when { expression { return params.DEBUG_BUILD } }
not 当嵌套条件是错误时,执行这个阶段,必须包含一个条件,例如:
when { not { branch 'master' } }
allOf 当所有的嵌套条件都正确时,执行这个阶段,必须包含至少一个条件,例如:
when { allOf { branch 'master'; environment name: 'DEPLOY_TO', value: 'production' } }
anyOf 当至少有一个嵌套条件为真时,执行这个阶段,必须包含至少一个条件,例如:
when { anyOf { branch 'master'; branch 'staging' } }
pipeline {
agent any
stages {
stage('Example Build') {
steps {
echo 'Hello World'
}
}
stage('Example Deploy') {
when {
not { branch 'master' } //不是master分支 输出 Deploying
}
steps {
echo 'Deploying'
}
}
}
}
1.5.8 并行parallel
声明式流水线的阶段可以在他们内部声明多隔嵌套阶段,它们将并行执行。注意,一个阶段必须只有一个steps或parallel的阶段。嵌套阶段本身不能包含 进一步的parallel 阶段,但是其他的阶段的行为与任何其他 stage parallel的阶段不能包含 agent 或 tools阶段,因为他们没有相关 steps
另外,通过添加 failFast true 到包含 parallel的 stage 中,当其中一个进程失败时,你可以强制所有的 parallel 阶段都被终止,
// 指定stages阶段(一个或多个)解释:在这里添加了三个阶段
stages {
stage ("parallel") {
when {
branch 'master'
}
parallel{
//构建
stage("Build"){
steps{
timeout(time:20,unit:"MINUTES"){
script{
println('应用打包')
}
}
}
}
//代码扫描
stage("CodeScan"){
steps{timeout(time:30,unit:"MINUTES"){
script{
println(“代码扫描”)
}
}
}
}
}
}
pipeline {
agent any
stages {
stage('Non-Parallel Stage') {
steps {
echo 'This stage will be executed first.'
}
}
stage('Parallel Stage') {
when {
not { branch 'master' }
}
failFast true
parallel {
stage('Branch A') {
agent {
label "for-branch-a"
}
steps {
echo "On Branch A"
}
}
stage('Branch B') {
agent {
label "for-branch-b"
}
steps {
echo "On Branch B"
}
}
}
}
}
}
// 单机演示
pipeline {
agent any
stages {
stage('Non-Parallel Stage') {
steps {
echo 'This stage will be executed first.'
}
}
stage('Parallel Stage') {
when {
not { branch 'master' }
}
failFast true
parallel {
stage('Branch A') {
agent any
steps {
echo "On Branch A"
}
}
stage('Branch B') {
agent any
steps {
echo "On Branch B"
}
}
}
}
}
}
安装blueocean,观察并行效果
1.6 step步骤
1.6.1 script
script 步骤需要 [scripted-pipeline]块并在声明式流水线中执行。对于大多数用例来说,应该声明式流水线中的“脚本”步骤是不必要的,但是它可以提供一个有用的”逃生出口”。非平凡的规模和/或复杂性的script
块应该被转移到 共享库 。
示例:
pipeline {
agent any
stages {
stage('Example') {
steps {
echo 'Hello World'
script {
def browsers = ['chrome', 'firefox']
for (int i = 0; i < browsers.size(); ++i) {
echo "Testing the ${browsers[i]} browser"
}
}
}
}
}
}
JenkinsShareLibrary-概述
src目录类似于标准Java源目录结构。执行流水线时,此目录将添加到类路径中,
vars目录托管脚本文件,这些脚本文件在“管道”中作为变量公开。
resources目录允许1ibraryResource从外部库中使用步骤来加载相关联的非Groovy文件。
// https://github.com/zeyangli/jenkinslib
---------------------------------------------------------------------------------------
// 仓库文件:/src/org/devops/tools.groovy
package org.devops //必加项
//打印内容
def PrintMes(content){
println(content)
}
// jenkinslib/vars/hello.groovy
def call(){
println("hello")
}
// 仓库文件:/vars/hello.groovy
---------------------------------------------------------------------------------------
def call(){
println("hello")
}
---------------------------------------------------------------------------------------
//jenkins配置 Libraries
Dashboard/系统管理/System/ Global Pipeline Libraries //jenkins配置 Libraries 名字、仓库地址、凭证
---------------------------------------------------------------------------------------
// Jenkinsfile
#!groovy
@Library('jenkinslib') _ // 上面jenkins配置的Libraries名字
def tools = new org.devops.tools() // 引用tools.groovy
String workspace = "/opt/jenkins/workspace"
//Pipeline
pipeline {
agent { node { label "master" //指定运行节点的标签或者名称
customWorkspace "${workspace}" //指定运行工作目录(可选)
}
}
options {
timestamps() //日志会有时间
skipDefaultCheckout() //删除隐式checkout scm语句
disableConcurrentBuilds() //禁止并行
timeout(time: 1, unit: 'HOURS') //流水线超时设置1h
}
stages {
//下载代码
stage("GetCode"){ //阶段名称
when { environment name: 'test', value: 'abcd' }
steps{ //步骤
timeout(time:5, unit:"MINUTES"){ //步骤超时时间
script{ //填写运行代码
println('获取代码')
tools.PrintMes("获取代码",'green')
println("${test}")
input id: 'Test', message: '我们是否要继续?', ok: '是,继续吧!', parameters: [choice(choices: ['a', 'b'], description: '', name: 'test1')], submitter: 'lizeyang,admin'
}
}
}
}
stage("01"){
failFast true
parallel {
//构建
stage("Build"){
steps{
timeout(time:20, unit:"MINUTES"){
script{
println('应用打包')
tools.PrintMes("应用打包",'green')
mvnHome = tool "m2"
println(mvnHome)
sh "${mvnHome}/bin/mvn --version"
}
}
}
}
//代码扫描
stage("CodeScan"){
steps{
timeout(time:30, unit:"MINUTES"){
script{
print("代码扫描")
tools.PrintMes("调用tools.groovy的PrintMes") //调用tools.groovy的PrintMes
}
}
}
}
}
}
}
//构建后操作
post {
always {
script{
println("always")
}
}
success {
script{
currentBuild.description = "\n 构建成功!"
}
}
failure {
script{
currentBuild.description = "\n 构建失败!"
}
}
aborted {
script{
currentBuild.description = "\n 构建取消!"
}
}
}
}
jenkins要配置sharelibrary
装AnsiColor插件 任务添加颜色 参考流水线语法 ,xterm方式
// 仓库文件:/src/org/devops/tools.groovy
//格式化输出
def PrintMes(value,color){
colors = ['red' : "\033[40;31m >>>>>>>>>>>${value}<<<<<<<<<<< \033[0m",
'blue' : "\033[47;34m ${value} \033[0m",
'green' : "[1;32m>>>>>>>>>>${value}>>>>>>>>>> [m",
'green1' : "\033[40;32m >>>>>>>>>>>${value}<<<<<<<<<<< \033[0m" ]
ansiColor('xterm') {
println(colors[color])
}
}
// 见上面的代码块
steps{ //步骤
timeout(time:5, unit:"MINUTES"){ //步骤超时时间
script{ //填写运行代码
println('获取代码')
tools.PrintMes("获取代码",'green')
println("${test}")
rm方式
// 仓库文件:/src/org/devops/tools.groovy
//格式化输出
def PrintMes(value,color){
colors = ['red' : "\033[40;31m >>>>>>>>>>>${value}<<<<<<<<<<< \033[0m",
'blue' : "\033[47;34m ${value} \033[0m",
'green' : "[1;32m>>>>>>>>>>${value}>>>>>>>>>> [m",
'green1' : "\033[40;32m >>>>>>>>>>>${value}<<<<<<<<<<< \033[0m" ]
ansiColor('xterm') {
println(colors[color])
}
}
// 见上面的代码块
steps{ //步骤
timeout(time:5, unit:"MINUTES"){ //步骤超时时间
script{ //填写运行代码
println('获取代码')
tools.PrintMes("获取代码",'green')
println("${test}")