持续集成系统jenkins[全局变量|Groovy编程|共享库实践]

root
233
文章
0
评论
2021年9月10日18:05:15 评论 7859字阅读26分11秒

持续集成系统jenkins[全局变量|Groovy编程|共享库实践]

BUILD_NUMBER          //构建号
BUILD_ID              //构建号
BUILD_DISPLAY_NAME    //构建显示名称
JOB_NAME              //项目名称
              
EXECUTOR_NUMBER       //执行器数量
NODE_NAME             //构建节点名称
WORKSPACE             //工作目录
JENKINS_HOME          //Jenkins home
JENKINS_URL           //Jenkins地址
BUILD_URL             //构建地址
JOB_URL               //项目地址

 

println(env)

env.branchName = "develop"
env.commitID = "${UUID.randomUUID().toString()}"
env.commitID = "${env.commitID.split("-")[0]}"
currentBuild.displayName = "#${env.branchName}-${env.commitID}"
currentBuild.description = "Trigger by user jenkins \n branch: master"

pipeline {

    agent { label "build"}

    stages{
        stage("test"){
            steps{
                script{
                    echo "${BUILD_NUMBER}"
                    echo "${BUILD_ID}"
                    //currentBuild.displayName = "#${env.branchName}-${env.commitID}"
                    //currentBuild.description = "Trigger by user jenkins \n branch: master"


                    echo "当前下载代码分支为: ${env.branchName}"
                }
            }
        }
    }
}

 

currentbuild变量

result  currentResult   //构建结果
displayName      //构建名称  #111
description      //构建描述
duration         //持续时间

流水线中变量定义引用

变量的类型:两种类型的变量。
1.Jenkins系统内置变量 (全局变量)
2.Pipeline中定义变量(全局/局部变量)

Jenkins系统内置变量:是Jenkins系统在安装部署后预先定义好的变量。这些变量可以通过Jenkins流水线语法页面看到具体有哪些。这些变量都是全局的可以使用"${env.变量名}"引用。

Pipeline中的变量:

首先你要先理解pipeline可以用groovy语法来编写,而groovy是一门编程语言。所有的编程语言也都有各自的变量定义方式。 这就容易让大家产生疑惑的地方,pipeline中可以有很多种写法。

def name = "devops"
String name = "devops"

以上这两种写法是一样,def可以自动推导出变量类型,而String这种写法是精确这个变量是一个字符串类型的。

如果你在Jenkins图形界面设置了参数化构建,那么这些参数也都变成了Jenkins全局变量,可以使用与Jenkins内置变量相同的引用方式。

如果在某个stage定义的变量默认是局部变量,在后续的stage中可能语法引用,所以如果需要引用最好定义为全局变量。

全局变量的定义方式:
env.name = "devops"

引用方式: "${env.name}"

总之变量是我们在编写Jenkins流水线是经常用到的。无处不在。如果你要定义全局的变量就用env.变量名的方式定义。 变量也不仅仅只有这几种写法,我建议如果想了解更多,可以多看下groovy这门需要的更多语法。

Groovy编程

参考文档:http://docs.groovy-lang.org/docs/latest/html/documentation/#_map_coercion

http://groovy-lang.org/groovy-dev-kit.html

Groovy是一种功能强大,可选类型和动态 语言,支持Java平台。旨在提高开发人员的生产力益于简洁,熟悉且简单易学的语法。可以与任何Java程序顺利集成,并立即为您的应用程序提供强大的功能,包括脚本编写功能,特定领域语言编写,运行时和编译时元编程以及函数式编程。

安装

  • 下载安装包(先安装JDK)
  • 解压安装包 获取安装包bin目录
  • 设置环境变量写入/etc/profile文件

https://groovy.apache.org/download.html

vi /etc/profile
export GROOVY_HOME=/usr/local/groovy-3.0.7/
export PATH=$PATH:$GROOVY_HOME/bin

source /etc/profile
groovysh

 

注释:

  • 单行注释 //
  • 多行注释 /**/

数据类型

字符串string

//字符串表示方式: 单引号、双引号、三单双引号。

//定义一个字符串类型变量name
String name = 'zhangsan'
String name = "zhangsan"

 

//定义一个变量包含多行内容

String zeyang = """ 
       devops
       devops 
       """ 
println(zeyang)

 

//字符串分割操作

String branchName = "release-1.1.1" println(branchName.split("-")[1])
效果:
[release, 1.1.1]

String branchName = "release-1.1.1"
println(branchName.split("-")[0])
效果:
[release]

-1就是从最后一个开始
println(branchName.split("-")[-1])
效果:
[release]

println("${env.JOB_NAME}".split("-")[0])

 

//是否包含release字符串

println(branchName.contains("release"))

 

//字符串的长度

println(branchName.size()) 
println(branchName.length())

 

//使用变量作为值

def message = "hello ${name}"
println(message)
println(message.toString())

 

//获取元素索引值

println(branchName.indexOf("-"))

 

//判断字符串以DEV结尾/test开头

String jobName = "test-service_DEV"
println(jobName.endsWith("DEV"))
println(jobName.startsWith("test"))
true
true

 

//字符串增添操作拼接

String log = "error: xxxxxx aa"
println(log.minus("a"))
println(log - "a")
println(log.plus("aa"))
println(log + "aa")

 

//字符串反转倒叙

String nums = "1234567"
println(nums.reverse())

 

列表list

列表的表示: [] [1,2,3,4]

// list
// 定义一个list
def mylist = [1,2,3,4,4,"devops"]
println(mylist)

// list的元素增删
println(mylist + "jenkins")
println(mylist - "devops")
println(mylist << "java")
def newlist = mylist.add("gitlab")
println(newlist)


// 判断元素是否为空
println(mylist.isEmpty())
// 列表去重
println(mylist.unique())

// 列表反转
println(mylist.reverse())

// 列表排序
println(mylist.sort())

// 判断列表是否包含元素
println(mylist.contains("devops"))

// 列表的长度
println(mylist.size())

//扩展列表定义方式
String[] stus = ["zhangsan", "lisi","wangwu"]
def numList = [1,2,3,4,4,4] as int[]

// 通过索引获取列表元素
println(numList[2])

// 计算列表中元素出现的次数
println(numList.count(4))

 

Scripts not permitted to use staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods count int[] java.lang.Object. Administrators can decide whether to approve or reject this signature.
[Pipeline] End of Pipeline

 

映射map

types = [“maven”:“mvn”] [:]

// 定义map

def mytools = [ "mvn": "/usr/local/maven",
				"gradle": "/usr/local/gradle" ]


// 根据key获取value
println(mytools["mvn"])
println(mytools["gradle"])

// 根据key重新赋值
mytools["mvn"] = "/opt/local/maven"
println(mytools)

mytools.gradle = "/opt/local/gradle"
println(mytools)

// 获取key的value
println(mytools.key("mvn"))
println(mytools.get("mvn"))

// 判断map是否包含某个key或者value
println(mytools.containsKey("gradle"))
println(mytools.containsValue("/usr/local/gradle"))

// 返回map的key 列表
println(mytools.keySet())

// 根据key删除元素
println(mytools.remove("mvn"))
println(mytools)

 

条件语句

if语句

在Jenkinsfile中可用于条件判断。

/*
定义变量参数branchName
如果branchName 等于dev则打印dev,
如果branchName 等于test则打印test,
上面都不匹配则打印skipdeploy
*/

String  branchName = "dev"
if ( branchName == "dev" ){
	println("dev....")

} else if (branchName == "test"){
	println("test....")

} else {
	println("skipdeploy......")
}

 

switch语句

/*
定义参数branchName
匹配 develop  则打印develop ,跳出。
匹配 release  则打印release ,跳出。
默认匹配, 打印 error ,退出。


*/

String branchName = "release"

switch(branchName) {
	case "develop":
	    println("develop .....")
		break
	case "release":
		println("release.....")
		break
	default:
	    println("error。。。。。。")
}

 

for循环语句

// for

// 遍历0-9,打印
for (i=1; i<10; i++ ){
	println(i)
}

// 循环5次
5.times { 
	println("hello")
}

// 遍历 0-4
5.times { i ->
   println(i)
}

// 遍历List
def serverList = ["server-1", "server-2", "server-3"]

for ( i in serverList){
	println(i)
}


// 使用each遍历map
def stus = ["zeyang":"177", "jenkins":"199"]
stus.each { k, v ->
	println(k+"="+v)

}

// 使用for遍历map
for (k in stus.keySet()){
	println(k+"="+stus[k])

}

 

while循环语句

// while 循环
String name = "jenkins"
while (name == "jenkins"){
	println("true....")
	name = "lisi"
}

 

异常处理

/*
如果println(a,b)失败(肯定失败,因为有语法错误)
catch捕获错误,并打印错误。
finally 总是执行。
*/

try {
	println(a,b)
}
catch(Exception e) {            //如果try里错误,捕获异常信息
	println(e)
}
finally {
	println("done")
}

 

函数定义与使用

/*
def关键字 定义函数名为PrintMes, 带有一个参数msg,语句块内容是打印msg参数的值,返回msg值。
将PrintMsg函数的执行结果返回给response变量。
打印response
*/

def PrintMsg(msg){
	println(msg)
	return msg
}

response = PrintMsg("jenkins ok okok!")
println(response)

也是可以在spript 中直接用
PrintMag("xx")

 

Jenkins共享库实践

要先安装git

共享库这并不是一个全新的概念,其实在编程语言Python中,我们可以将Python代码写到一个文件中,当代码数量增加,我们可以将代码打包成模块然后再以import的方式使用此模块中的方法。

在Jenkins中使用Groovy语法,共享库中存储的每个文件都是一个groovy的类每个文件(类)中包含一个或多个方法。每个方法包含groovy语句块

可以在Git等版本控制系统中创建一个项目用于存储共享库。共享流水线有助于减少冗余并保持代码整洁。

属性:

  • 共享库名称
  • 共享库版本
  • 共享库地址
├── src
│   └── org
│       └── devops
│           └── tools.groovy
├── vars
│   └── GetHosts.groovy
│   └── GetCommitId.groovy
│           
└── resources
│   └── org
│       └── devops
│           └── config.json

库结构:

  • src: 类似于java的源码目录,执行流水线时会加载到class路径中。
  • vars: 存放全局变量脚本,小的功能函数。
  • resources: 存放资源文件,类似于配置信息文件。

共享库配置

1. 创建一个共享库

可以直接在github中创建一个公开类型的仓库,仓库名称自定义。公开类型的仓库是为了便于验证,也可以创建私有类型的,但是需要提前配置好仓库的认证凭据。

2. 创建groovy类文件

参考文件: https://github.com/zeyangli/myjenkinslib/blob/main/src/org/devops/jenkinstest.groovy

直接在github仓库的页面操作即可:

 

 

使用共享库

1.gitlab创建组,组里创建项目

1.创建jenkinsfile

在Jenkinsfile中使用@Library('mylib') _ 加载共享库,注意后面符号_用于加载hwf.devops.Tools()就是你gitlab,src里脚本的位置使用类中的方法 `mytools.PrintMsg(msg)` 。

@Library('hwf') _     

def mytools = new hwf.devops.Tools()


pipeline {

	agent { label  "build" }

	stages {
		stage("build"){
			steps{
				script{
					msg = "hello jenkins"
					mytools.PrintMsg(msg)
				}
			}
		}
	}

}

 

2.jenkins里设置共享库

系统设置-->系统配置

  • 这里的共享库的名称要和gitlab定义的项目里jenkinsfile里共享库的名称相同
  • 版本就是分支的名称

gitlab项目里的地址[这个地址这里错了,需要改]

3.打开jenkins任务流水线,进行设置

  • 分支名称和gitlab里面定义的一致
  • 脚本路径里的名称要和你gitlab库里定义的一致

运行流水线查看测试结果

共享库扩展

共享库加载

// 加载mylib共享库
@Library('mylib') _


// 加载mylib共享库的1.0版本
@Library('mylib@1.0') _


// 加载多个共享库, mylib共享库的默认版本, yourlib共享库的2.0版本(分支)
@Library(['mylib', 'yourlib@2.0']) _

 

把pipeline定义在变量里在jenkinsfile里引用变量方法

1.Tools.groovy

hwflib/src/hwf/devops/Tools.groovy
package hwf.devops

//打印信息
def PrintMsg(msg) {
    println(msg)
    return value
}
public String PrintMsg(String value){
	println(value);
	return value
}

 

2.Pipeline.groovy

jenkinslib/vars/Pipeline.groovy
import hwf.devops.Tools

def call(Map args){
    def tools = new Tools()

    pipeline {
        agent { label "build"}

        stages{
            stage("build"){
                steps{
                    script{
                        value = tools.PrintMsg("hwf")
                        println(value)

                        println(args.name)

                    }
                }
            }
        }
    }
}

 

3.jenkinsfile

jenkinslib/jenkinsfile
@Library("hwf@main") _    

demoPipeline(
    name: "hwf"
)

 

 

使用resource/里的文件

用法:

1.resources/xxx.json文件

jenkinslib/resources/config.json
{
    "name": "jin tian"

}

2.vars/Pipeline.groovy

jenkinslib/vars/Pipeline.groovy
import hwf.devops.Tools

def call(Map args){
    def tools = new Tools()

    pipeline {
        agent { label "build"}

        stages{
            stage("build"){
                steps{
                    script{
                         //加载resource里的文件
                        config = libraryResource '/config.json'
                        config = readJSON text: config -"\n"
                        value = tools.PrintMsg("hwf")
                        println(config.name)

                    }
                }
            }
        }
    }
}

 

 

 

 

 

继续阅读
weinxin
我的微信
这是我的微信扫一扫
  • 文本由 发表于 2021年9月10日18:05:15
  • 除非特殊声明,本站文章均为原创,转载请务必保留本文链接
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: