GitLab&Jenkins

01-触发Jenkins构建

插件名称: Generic Webhook Trigger

重启后,进入一个Pipeline项目设置,已经可以选择这个触发器了....

插件文档https://plugins.jenkins.io/generic-webhook-trigger/

Jenkins作业配置触发器

启动Generic Webhook触发器后, 相当于给Jenkins加了一个新的接口http://JENKINS_URL/generic-webhook-trigger/invoke)。

调用的时候:这里要把 JENKINS_URL****换成自己真实的Jenkins 服务器地址,有端口就加上端口,是域名就写域名。下面是一个参考的URL:

bash 复制代码
http://192.168.1.200:8080/generic-webhook-trigger/invoke

Post content parameters: 获取调用接口传进来的数据

JsonPath语法文档: https://github.com/json-path/JsonPath

Header parameters: 获取Header中的参数

Request parameters: 获取URL中的请求参数

bash 复制代码
curl http://192.168.1.200:8080/generic-webhook-trigger/invoke?runopts=gitlab

Token: 给URL添加一个触发的认证

bash 复制代码
curl http://192.168.1.200:8080/generic-webhook-trigger/invoke?token=devops-service

打印调试信息到日志中

触发条件过滤:仅满足条件才能触发此作业

实践:demo

解析GET/POST请求数据

传参注意,第一个参数使用?号连接, 后面的参数使用&符号连接。

bash 复制代码
?token=demo-pipeline-service&user=jenkins&a=1&b=2

演示将postman中的请求转换curl方式。

bash 复制代码
[root@zeyang-nuc-service ~]# curl --location --request GET 'http://192.168.1.200:8080/generic-webhook-trigger/invoke?token=demo-pipeline-service'
{"jobs":{"demo-pipeline-service":{"regexpFilterExpression":"","triggered":true,"resolvedVariables":{},"regexpFilterText":"","id":209,"url":"queue/item/209/"}},"message":"Triggered jobs."}[root@zeyang-nuc-service ~]#

解析GET数据

  • 客户端发送Get请求, 带有两个参数 versionusername
bash 复制代码
http://192.168.1.200:8080/generic-webhook-trigger/invoke?token=demo-pipeline-service&version=1.1.1&username=jenkins
  • Jenkins 配置Generic hook,获取请求参数versionusername参数名称要一致
  • 验证测试(Jenkins日志中能够打印出获取的值,则正常
  • 通过jenkinsfile读取传递的参数
bash 复制代码
println("${username}")
println("${version}")

解析HEADER参数数据

  • 客户端发送请求(什么请求都可以,这里的header与请求类型无关), 带有两个参数 header_name 和 header_id 。
bash 复制代码
curl --location --request GET 'http://192.168.1.200:8080/generic-webhook-trigger/invoke?token=demo-pipeline-service' \
--header 'header_name: jenkins' \
--header 'header_id: 100'
  • Jenkins 配置Generic hook,获取请求参数header_nameheader_id
  • 通过jenkinsfile读取传递的参数
bash 复制代码
println("${header_id}")
println("${header_name}")
println(header_id)
println(header_name)

String headerName = "${header_id}"
println(headerName)


//pipeline {  
//}

解析POST数据

  • 客户端发送POST请求, 参数存储在body体中(参考POSTMAN中的样例
bash 复制代码
curl --location --request POST 'http://192.168.1.200:8080/generic-webhook-trigger/invoke?token=demo-pipeline-service' \
--header 'Content-Type: application/json' \
--data-raw '{
    "name": "zhangsan",
    "id": "123",
    "group1": {
        "name": "jenkins",
        "id" : "001",
        "age": "40"
    }
}'
  • Jenkins 配置触发器来获取Post参数。

获取所有数据

获取username字段

获取group1Name字段

  • Jenkinsfile中使用参数
bash 复制代码
println("所有body数据 --> ${allData}")
println('最外层name ---> $.name' + "${userName}")
println('第二层name ---> $.group1.name' + "${group1Name}")

扩展流水线解析JSON数据

安装插件: Pipeline Utility Steps

readJSON: 处理json数据

bash 复制代码
println("所有body数据 --> ${allData}")

def webHookData = readJSON  text: "${allData}"

String userName = webHookData["name"]
String userName2 = webHookData.name

String group1Name = webHookData["group1"]["name"]
String group1Name2 = webHookData.group1.name

println('最外层name ---> $.name' + "${userName}")
println('最外层name ---> $.name' + "${userName2}")

println('第二层name ---> $.group1.name' + "${group1Name}")
println('第二层name ---> $.group1.name' + "${group1Name2}")

Rebuilder 插件使用

可以直接携带原触发参数进行触发,不用重复触发(不用在重复的提交代码了)。

进入某一次构建后,可以点击rebuild。

02-获取触发参数

触发器配置

Jenkins开启trigger

目的: 开启trigger后,就可以实现其他系统通过一个指定的URL进行自动触发构建了;

新建一个文件夹存放对应GitLab仓库组中的流水线。这里建议用仓库组的名称作为文件夹的名称devops03;

用Gitlab项目名称与流水线命名; devops03-demo-service项目;

  • 开启Generic webhook;
  • 配置触发Token,例如:作业名称devops03-demo-service (这个token是流水线触发需要传递的);
  • 生成的触发URL;
bash 复制代码
http://192.168.1.200:8080/generic-webhook-trigger/invoke?token=devops03-demo-service

(此时,已经生成了触发URL,接着可以使用Curl或者Postman进行触发测试了!)

配置GitLab WebHook

进入GitLab项目设置, 进入 webhook配置页面;

  • 配置要触发的URL,即Jenkins触发器接口URL;
  • 选择发生哪种GitLab事件后触发此Webhook;例如:Push提交代码、Tag创建标签等等;

事件:

  • Push 提交事件
  • Tag Push 创建事件
  • MergeRequest 合并事件
  • Issue 问题创建更新事件
  • 测试模拟触发

模拟事件触发,点击test按钮选择push事件,此时去看下Jenkins是否成功被触发。

触发成功则提示: Hook executed successfully: HTTP 200, 此时可以看下Jenkins是否已经触发了一次构建;

如果出现此FAQ: Url is blocked: Requests to the local network are not allowed

解决方法:进入admin管理页面设置 > network

找到"Outbound requests"勾选允许请求webhooks和服务。(更改后,重启触发即可)

Webhook问题排查调试

进入webhook添加页面的最下方,点击你所创建的webhook的 Edit按钮 ;

webhook历史记录: 此记录可以判断,当前动作提交是否产生了webhook。

点击 View details 可以看到此webhook发送给对端Jenkins的数据信息,和请求状态。

  • 200: 表示触发Jenkins请求成功;
  • Resend Request: 重新发送请求;(此处便于排查调试错误)
  • RequestBody: GitLab传递给Jenkins的数据信息;

假如请求由于xxx原因导致没有触发jenkins构建, 可以在这里点击 Resend Request 按钮进行重新发送请求,而不是再次提交代码。

如果Jenkins触发成功了之后,我们可以在Jenkins的构建日志中查看效果。 这些数据就是gitlab post传递过来的。

到此:你基本上已经知道了Gitlab如何触发Jenkins的了。(多看几遍,多练习几遍)

提交流水线优化

过滤新建分支和tag的触发

你可能发现问题了,新建一个分支或者标签也会出现构建 ,这个构建是没有意义的。我们需要排除掉。没错,jenkins 的 Generic webHook 也是支持的。

参考官方的说明:https://github.com/jenkinsci/generic-webhook-trigger-plugin/blob/master/src/test/resources/org/jenkinsci/plugins/gwt/bdd/gitlab/gitlab-push-ignore-create-remove-branch.feature

添加三个变量,获取当前的提交信息 $object_kind $before $after

此步骤一定要注意下参数名和值后面的空格,要去掉

通过正则表达式配置触发条件:Expression ^push\s(?!0{40}).{40}\s(?!0{40}).{40}$ Text $object_kind $before $after。 push请求只有after和before的值都不是40个0的时候触发构建(为40个0的情况是删除分支或者新建分支)

如何支持多个分支触发构建?

创建多个gitlab webhook, 设置不同的分支,最终指向同一个jenkins 作业;

03-自动触发Pipeline

bash 复制代码
webhookData = readJSON text: "${webhook_data}"


//分支名称
env.branchName = webhookData["ref"] - "refs/heads/"
env.projectUrl = webhookData["project"]["git_http_url"]
env.userEmail = webhookData["user_email"]

//修改描述信息
currentBuild.description = "BranchName: ${env.branchName}"
currentBuild.displayName = "${env.branchName}"


pipeline {
    agent { label "build01"}

    stages {
        stage('Checkout') {
            steps {
                script{

                    //checkout 
                    checkout([$class: 'GitSCM', 
                              branches: [[name: "${env.branchName}"]], 
                              extensions: [], 
                              userRemoteConfigs: [[
                                  credentialsId: 'd7e4e500-e5c6-4673-ae4b-d43bf4ff5d19', 
                                  url: "${env.projectUrl}"]]])

                }
            }
        }


        stage('Build'){
            steps{
                script{
                    sh "mvn clean package -DskipTests"
                }
            }
        }


        stage('test'){
            steps{
                script{
                    sh "mvn test"
                }
            }
        }
    }

    post {
        always{
            script{
                EmailUser("${env.userEmail}",currentBuild.currentResult)
            }
        }
    }
}


def EmailUser(userEmail,status){
    emailext body: """
            <!DOCTYPE html> 
            <html> 
            <head> 
            <meta charset="UTF-8"> 
            </head> 
            <body leftmargin="8" marginwidth="0" topmargin="8" marginheight="4" offset="0"> 
                <img src="http://192.168.1.200:8080/static/0eef74bf/images/headshot.png">
                <table width="95%" cellpadding="0" cellspacing="0" style="font-size: 11pt; font-family: Tahoma, Arial, Helvetica, sans-serif">   
                    <tr> 
                        <td><br /> 
                            <b><font color="#0B610B">构建信息</font></b> 
                        </td> 
                    </tr> 
                    <tr> 
                        <td> 
                            <ul> 
                                <li>项目名称:${JOB_NAME}</li>         
                                <li>构建编号:${BUILD_ID}</li> 
                                <li>构建状态: ${status} </li>                         
                                <li>项目地址:<a href="${BUILD_URL}">${BUILD_URL}</a></li>    
                                <li>构建日志:<a href="${BUILD_URL}console">${BUILD_URL}console</a></li> 
                            </ul> 
                        </td> 
                    </tr> 
                    <tr>  
                </table> 
            </body> 
            </html>  """,
            subject: "Jenkins-${JOB_NAME}项目构建信息 ",
            to: userEmail

}

04-手动触发流水线

bash 复制代码
//修改描述信息
currentBuild.description = "BranchName: ${env.branchName}"
currentBuild.displayName = "${env.branchName}"


pipeline {
    agent { label "build01"}

    stages {
        stage('Checkout') {
            steps {
                script{

                    //checkout 
                    checkout([$class: 'GitSCM', 
                              branches: [[name: "${env.branchName}"]], 
                              extensions: [], 
                              userRemoteConfigs: [[
                                  credentialsId: 'd7e4e500-e5c6-4673-ae4b-d43bf4ff5d19', 
                                  url: "${env.projectUrl}"]]])

                }
            }
        }


        stage('Build'){
            steps{
                script{
                    sh "mvn clean package -DskipTests"
                }
            }
        }


        stage('test'){
            steps{
                script{
                    sh "mvn test"
                }
            }
        }
    }
}

05-Jenkins消息通知

默认情况可能每个Gitlab用户没有配置邮箱的, 需要Gitlab用户要配置好邮箱。 点击头像进入 edit profile

在这个页面配置好邮箱地址,最好这几个email都配置上吧......最后

Jenkins需要配置邮件通知,安装插件Email Extension安装后重启Jenkins。

然后进入系统管理-> 系统设置 , 先配置下全局的admin的邮箱地址。(最后配置下不然可能会出错的)

->Extended E-email Notification。设置邮件系统配置信息。

登入邮箱拿到授权码

发送短信之后获取授权码

这里我使用的是QQ邮箱,填写SMTP服务器地址smtp.qq.com 和端口 465注意要开启SSL,密码为授权码。

换个选项注意下: 不选择 HTML 就是普通的文本, HTML 可以支持html网页,更加美观。这里选择 HTML

pipeline as code , 进入片段生成器,生成邮件通知代码。

bash 复制代码
emailext body: 'hello world!....jenkins', subject: 'test.....', to: '2560350642@qq.com'

然后我们将此段代码加入到Jenkins pipeline 中运行, 可以看到效果:

jenkins as code 将email 写成一个函数。这个通知信息是一个html格式的。

bash 复制代码
def EmailUser(userEmail,status){
 	emailext body: """
            <!DOCTYPE html> 
            <html> 
            <head> 
            <meta charset="UTF-8"> 
            </head> 
            <body leftmargin="8" marginwidth="0" topmargin="8" marginheight="4" offset="0"> 
                <img src="http://192.168.1.200:8080/static/0eef74bf/images/headshot.png">
                <table width="95%" cellpadding="0" cellspacing="0" style="font-size: 11pt; font-family: Tahoma, Arial, Helvetica, sans-serif">   
                    <tr> 
                        <td><br /> 
                            <b><font color="#0B610B">构建信息</font></b> 
                        </td> 
                    </tr> 
                    <tr> 
                        <td> 
                            <ul> 
                                <li>项目名称:${JOB_NAME}</li>         
                                <li>构建编号:${BUILD_ID}</li> 
                                <li>构建状态: ${status} </li>                         
                                <li>项目地址:<a href="${BUILD_URL}">${BUILD_URL}</a></li>    
                                <li>构建日志:<a href="${BUILD_URL}console">${BUILD_URL}console</a></li> 
                            </ul> 
                        </td> 
                    </tr> 
                    <tr>  
                </table> 
            </body> 
            </html>  """,
            subject: "Jenkins-${JOB_NAME}项目构建信息 ",
            to: userEmail

}

最后收到的邮件效果:

相关推荐
i建模3 小时前
在 Rocky Linux 上安装轻量级的 XFCE 桌面
linux·运维·服务器
Data_Journal3 小时前
Scrapy vs. Crawlee —— 哪个更好?!
运维·人工智能·爬虫·媒体·社媒营销
YMWM_4 小时前
不同局域网下登录ubuntu主机
linux·运维·ubuntu
zmjjdank1ng4 小时前
restart与reload的区别
linux·运维
Suchadar4 小时前
Docker常用命令
运维·docker·容器
你才是臭弟弟4 小时前
MinIo开发环境配置方案(Docker版本)
运维·docker·容器
Bruk.Liu4 小时前
Gitea Actions 的概念及基础使用
运维·ci/cd·持续集成
yanlou2334 小时前
[C++/Linux HTTP项目] HTTP服务器基于muduo高性能服务器搭载【深入详解】
运维·服务器·http·muduo库·http高性能服务器
杨江4 小时前
frp macbook 的18789到 公网服务器上,访问报错:disconnected (1008): unauthorized:
运维
天空属于哈夫克34 小时前
企微第三方 RPA API:非官方接口与官方接口的差异解析及选型建议
运维·服务器