Jenkins - Groovy

1 - Groovy简介

Groovy是面向对象的、基于JVM的轻量级动态类型脚本语言。
语法与Java 语法非常相似,但同时又拥有灵活的动态特性,并且支持闭包和高阶函数。
Groovy 支持类型自动推导,因此不需要指定变量的类型。
在一些工具DSL, Gradle或是与Java的混合编程中用到,Jenkins中也大量用到,用于编写配置文件、实现构建、测试和部署自动化

Tutorial

2 - 在Windows10上配置Groovy环境

2.1 安装JDK

下载OpenJDK的zip 包并解压到指定目录

新建环境变量JAVA_HOME,变量值为zip包解压后的路径
JDK8: 添加%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin到环境变量PATH
JDK17: 添加%JAVA_HOME%\bin到环境变量PATH
在命令行执行java -versionjavac -version验证,能够获得版本号,无报错信息则证明配置完成。

2.2 安装Groovy SDK

下载Groovy SDK的zip包并解压到指定目录

配置groovy的环境变量GROOVY_PATH,变量值为zip包解压后的路径
添加%GROOVY_HOME%\bin到环境变量PATH
在命令行执行groovy -version,能够获得版本号,无报错信息则证明配置完成。

2.3 Groovy自带的编辑器

在命令行下执行groovyconsole命令会启动自带的编辑器,适合学习和简单场景

2.4 VS Code与Groovy

先安装code-groovy插件 code-groovy:Better groovy support for VSCode

再安装Code Runner插件 Code Runner:Run code snippet or code file for multiple languages and custom command

其他插件

  • Jenkins Pipeline Linter Connector --- validates Jenkinsfiles by sending them to the Pipeline Linter of a Jenkins server
  • JenkinsFile Support --- This extension adds syntax highlighting support for Jenkinsfile's
  • Groovy Lint, Format and Fix --- Lint, format and auto-fix groovy and Jenkinsfile
  • Jenkins Doc --- Provides Jenkins documentation and autocompletion on Jenkinsfile and Groovy files

2.5 使用Intellij IDEA安装groovy插件进行groovy开发

https://www.jetbrains.com/help/idea/groovy.html
例如,

  1. 新建一个Project,选择Groovy,指定Project SDK和Groovy library
  2. 指定项目名,然后选择src目录, 右键新建一个Groovy文件,选择Groovy Script并指定文件名
  3. 在Groovy Script文件填写pritnln "Hello Groovy", CTRL + SHIFT + F10运行。

3 - 编写与验证

3.1 Jenkins Web Pipeline

简单的Jenkinsfile,可以在 Jenkins Web Pipeline 页面里编写(自带语法检查)

3.2 pipeline-syntax

Snippet Generator: https://<Jenkins server url>/pipeline-syntax/

3.3 本地格式化和验证Jenkinsfile

为了避免开发Jenkins流水线开发时出现语法错误,可以通过VS code的插件来进行检查。
Validate your Jenkinsfile from within VS Code: https://jenkins.io/blog/2018/11/07/Validate-Jenkinsfile/
可以将Visual Studio Code与Jenkins Pipeline Linter Connector插件一起使用,在VS Code中本地格式化和验证Jenkinsfile。

需要在设置中指定插件的参数

- jenkins.pipeline.linter.connector.url 
- jenkins.pipeline.linter.connector.user
- jenkins.pipeline.linter.connector.pass 
- jenkins.pipeline.linter.connector.crumbUrl 

注意:

  • 请确认Jenkins启用了“CSRF Protection”(Manage Jenkins -> Manage Configure Global Security 页面)
  • 实际上是利用Jenkins API进行语法格式校验,并不能保证pipeline内容完全可用

示例:
https://jenkins.ap.manulife.com/blueocean/

运行插件: 右键 -> Command Palette -> Validate Jenkinsfile 或 执行快捷键 Shift + Alt + V

4 - 语法示例

更多groovy内容:http://www.groovy-lang.org/documentation.html


name = 'DevOps'  //pipeline外部定义变量
tools = ['Jenkins', 'GitLab', 'Maven', 'Sonar']
user_info = ['id':100, 'name':'cicd', 'group':'Admin']
users_group = [
['id':101, 'name':'dev', 'group':'user'],
['id':102, 'name':'test', 'group':'user']
]

pipeline {
    agent {
        label 'master'
    }
    stages {
        stage('常见数据类型') {
            steps {
                script {
                    println('字符串类型:用单引号或双引号括起来的字符串')
                    println('布尔类型: true、false')
                    println('集合类型: List、Map、Set')
                }
            }
        }
        stage('字符串处理') {
            steps {
                script {
                    println("String: ${name}")  //打印变量
                    job_name = 'devops-app_CI'  //本阶段内定义的变量只在本阶段生效
                    part_name = job_name.split('-')[0]  //split()方法按照分隔符进行字符串分割
                    println(part_name)
                    println(job_name.contains('CI'))  //contains()方法判断字符串是否包含特定字符
                    println("Size: ${job_name.size()}")  //size()方法计算字符串的长度
                    println("Length: ${job_name.length()}")  //length()方法计算字符串的长度
                    println("ends with 'CI': ${job_name.endsWith('CI')}")  //endsWith()方法判断字符串是否以特定字符结尾
                }
            }
        }
        stage('列表处理') {
            steps {
                script {
                    println("List: ${tools}")
                    println(tools + 'K8s')  //向List添加元素
                    tools.add('Docker')  //add()添加元素
                    println(tools - 'Sonar')//从List移除元素
                    println("List: ${tools}")
                    println(tools.contains('Jenkins'))  //contains()判断元素是否存在
                    println("${tools[0]},${tools[-1]}")  //通过索引获取第一个和最后一个元素
                }
            }
        }
        stage('Map处理') {
            steps {
                script {
                    println("Map: ${user_info}")
                    println(user_info['id'])  //打印key对应的值
                    println(user_info['name'])
                    println(user_info.containsKey('name'))  //判断是否包含指定的key
                    println(user_info.containsValue(100))  //判断是否包含指定的value
                    println(user_info.keySet())  //打印key的集合
                    user_info['name'] = 'JenkinsX'  //重新赋值
                    println(user_info)
                    user_info.remove('group')  //删除指定的key
                    println(user_info)
                }
            }
        }
        stage('控制语句') {
            steps {
                script {
                    if (name == 'DevOps') {
                        println('name is DevOps')
                    } else if (name == 'AI') {
                        println('name is AI')
                    } else {
                        println('error...')
                    }
                }
                script {
                    switch(name) {
                        case 'AI': println('name is AI')
                        break
                        case 'DevOps': println('name is DevOps')
                        break
                        default: println('error...')
                        break
                    }
                }
                script {
                    for (i in tools) {
                        println(i)
                    }
                }              
            }
        }
        stage('函数') {
            steps {
                script {
                    user_name = GetUserNameByID(101)
                    println(user_name)
                }
            }
        }
    }
}

def GetUserNameByID(int id) {
    for (i in users_group) {
        if (i['id'] == id) {
            return i['name']
        }
    }
}

5 - 参考信息

6 - Tips

1 - Groovy代码的格式化方法

  • VScode:设置文件类型绑定,将.groovy后缀文件识别为.js,然后“格式化文档”, 可以格式化缩进
  • IntelliJ IDEA:支持Groovy的代码补全、语法和错误高亮、代格式化与检查、重构与调试

指定文件类型绑定
https://code.visualstudio.com/docs/languages/overview#_adding-a-file-extension-to-a-language

posted @ 2020-07-10 23:48  Anliven  阅读(1816)  评论(0编辑  收藏  举报