GitLAB & Jenkins
目录
实践:基于Jenkins提交流水线(测试成功)-2023.4.25
目的:掌握通过触发器将GitLab和Jenkins集成,实现提交流水线。
1、触发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:
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中的请求参数
curl http://192.168.1.200:8080/generic-webhook-trigger/invoke?runopts=gitlab
Token: 给URL添加一个触发的认证
curl http://192.168.1.200:8080/generic-webhook-trigger/invoke?token=devops-service
打印调试信息到日志中
触发条件过滤:仅满足条件才能触发此作业
创建测试项目
- 创建一个叫做
devops-demo-service
的jenkins作业(这里的作业名称和gitlab里的项目名称推荐保持一致)
- 要加一个唯一的token,不然会触发所有token一样的项目
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2ZFLY8ZF-1682425393155)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/image-20230423062932520.png)]
- 把这2个选项勾选上
- 此时在postman里测试触发
触发url http://172.29.9.101:8080/generic-webhook-trigger/invoke?token=devops-demo-service
这里记得要加一个basic auth
:
可以看到触发成功了。
- 演示将postman中的请求转换curl方式。
curl --location --request POST 'http://172.29.9.101:8080/generic-webhook-trigger/invoke?token=devops-demo-service' \
--header 'Authorization: Basic YWRtaW46YWRtaW4='
可以看到,也是能构建成功的。
解析GET/POST请求数据
传参注意,第一个参数使用?号连接, 后面的参数使用&符号连接。
?token=demo-pipeline-service&user=jenkins&a=1&b=2
解析GET数据
- 客户端发送Get请求, 带有两个参数
version
和username
。
http://172.29.9.101:8080/generic-webhook-trigger/invoke?token=devops-demo-service&version=1.1.1&username=jenkins
- Jenkins 配置Generic hook,获取请求参数
version
和username
(参数名称要一致)
- 验证测试(Jenkins日志中能够打印出获取的值,则正常)
哎,这里怎么没显示一些变量呢??
这里简单写一个pipeline把。
可以看到效果了。
- 通过jenkinsfile读取传递的参数,再次触发
currentBuild.displayName = "${version}"
println("${version}")
println("${username}")
pipeline {
agent any
stages {
stage('Hello') {
steps {
echo 'Hello World'
}
}
}
}
再次postman触发,观察效果:(符合预期)
解析HEADER参数数据
- 客户端发送请求(什么请求都可以,这里的header与请求类型无关), 带有两个参数 devops和 tool-name。
- Jenkins 配置Generic hook,获取请求参数devops和 tool-name 。
- 通过jenkinsfile读取传递的参数
注意,这里的pipeline代码如果打印tool-name
变量的话,会报错的
这里要使用下划线来替换横杠:
再次触发,就正常了,符合预期。
解析POST数据
- 客户端发送POST请求, 参数存储在body体中(参考POSTMAN中的样例)
- Jenkins 配置触发器来获取Post参数。
删除之前测试的header参数,request参数。
$
代表/,获取所有数据
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nYZuhkun-1682425393160)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/image-20230423075557421.png)]
获取name字段
- Jenkinsfile中使用参数
触发:
验证:
扩展流水线解析JSON数据
- 安装插件:
Pipeline Utility Steps
- readJSON: 处理json数据
currentBuild.displayName = "${name}"
println("${Data}")
NewData = readJSON text: "${Data}"
envName = NewData["envName"]
appsName = NewData["apps"]["name"]
pipeline {
agent any
stages {
stage('Hello') {
steps {
script {
println("${envName}")
println("${appsName}")
}
}
}
}
}
再次构建:
验证:(符合预期)
Rebuilder
插件使用
可以直接携带原触发参数进行触发,不用重复触发(不用在重复的提交代码了)。
进入某一次构建后,可以点击rebuild。
2、获取触发参数
1.触发器配置
Jenkins开启trigger
目的: 开启trigger后,就可以实现其他系统通过一个指定的URL进行自动触发构建了;
新建一个文件夹存放对应GitLab仓库组中的流水线。这里建议用仓库组的名称作为文件夹的名称devops03
;
用Gitlab项目名称与流水线命名; devops03-demo-service
项目;
- 开启Generic webhook;
- 配置触发Token,例如:作业名称
devops03-demo-service
(这个token是流水线触发需要传递的); - 生成的触发URL;
http://192.168.1.200:8080/generic-webhook-trigger/invoke?token=devops03-demo-service
(此时,已经生成了触发URL,接着可以使用Curl或者Postman进行触发测试了!)
自己本次的这部分配置已经配置完成了。
- 这里还原下,删除之前的变量,这里只保留Data。
- 修改下pipeline代码
println("${Data}")
NewData = readJSON text: "${Data}"
// envName = NewData["envName"]
// appsName = NewData["apps"]["name"]
println("${NewData}")
pipeline {
agent any
stages {
stage('Hello') {
steps {
script {
println("${NewData}")
}
}
}
}
}
配置GitLab WebHook
进入GitLab项目设置, 进入 webhook
配置页面;
-
配置要触发的URL,即Jenkins触发器接口URL;
-
选择发生哪种GitLab事件后触发此Webhook;例如:Push提交代码、Tag创建标签等等;
-
在gitlab的项目里配置好webhook
http://172.29.9.101:8080/generic-webhook-trigger/invoke?token=devops-demo-service
事件:
-
Push 提交事件
-
Tag Push 创建事件
-
MergeRequest 合并事件
-
Issue 问题创建更新事件
-
测试模拟触发
模拟事件触发,点击test按钮选择push事件,此时去看下Jenkins是否成功被触发。
这里稍微测试下:
点击Test
触发成功则提示: Hook executed successfully: HTTP 200, 此时可以看下Jenkins是否已经触发了一次构建;
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的了。(多看几遍,多练习几遍)
2.提交流水线优化
过滤新建分支和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上新创建一个分支
可以看到,gitlab上新创建一个分支后,就会触发jenkins流水线,这不是我们所期望的,因此下面将进一步优化。
- 在jenlins侧如何过滤出一些构建:
before如果是40个0的话,那么可能是创建分支;
after如果是40个0的话,那么可能是合并分支;
- 这里先编辑jenkins上流水线的触发过滤条件
通过正则表达式配置触发条件:Expression ^push\s(?!0{40}).{40}\s(?!0{40}).{40}$
Text $object_kind $before $after
。 push请求只有after和before的值都不是40个0的时候触发构建(为40个0的情况是删除分支或者新建分支)
\s是空格
配置完成后,保存。
gitlab上再新建分支,观察是否会触发jenkins?
可以看到gitlab上已经成功触发了,但是被jenkins过滤掉了,符合预期。😘
如何支持多个分支触发构建?
方法1:创建多个gitlab webhook, 设置不同的分支,最终指向同一个jenkins 作业;
方法2:过滤
gitlab上设置,只允许feature
开头的分支才可以进行触发:
编辑gitlab上的webhook配置:
3、自动触发Pipeline
- 这里写下代码
获取项目地址:
获取分支名:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Zds29h2j-1682425393170)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/image-20230423214640427.png)]
下载代码:
利用片段生成器生成代码:
创建gitlab-root凭据:
生成代码:
checkout([$class: 'GitSCM', branches: [[name: 'main']], extensions: [], userRemoteConfigs: [[credentialsId: 'gitlab-root', url: 'srcUrl']]])
继续编写代码:
println("${Data}")
NewData = readJSON text: "${Data}"
// envName = NewData["envName"]
// appsName = NewData["apps"]["name"]
println("${NewData}")
// Get git repo url 项目地址
srcUrl = NewData["project"]["git_http_url"]
// Get git repo branch
branchName = NewData["ref"] - "refs/heads/"
// current build desc
currentBuild.displayName = "${branchName}"
currentBuild.description = "src: ${srcUrl}"
pipeline {
agent any
stages {
stage('CheckOut') {
steps {
script {
println("Checkout: ${srcUrl} ${branchName}")
checkout([$class: 'GitSCM',
branches: [[name: "${branchName}"]],
extensions: [],
userRemoteConfigs: [[credentialsId: 'gitlab-root', url: "${srcUrl}"]]])
sh 'ls -l'
}
}
}
}
}
将写好的代码保存到jekins里。
- 在gitlab任意分支做个提交:
我们先拉取下代码:
在feature-dev-01
编辑README.md文件并推送。
Win@DESKTOP-VUMV922 MINGW64 ~/Desktop/demo (feature-dev-01)
$ cat README.md
情出自愿-事过无悔
Win@DESKTOP-VUMV922 MINGW64 ~/Desktop/demo (feature-dev-01)
$ echo 佳 >> README.md
Win@DESKTOP-VUMV922 MINGW64 ~/Desktop/demo (feature-dev-01)
$ git add .
warning: in the working copy of 'README.md', LF will be replaced by CRLF the next time Git touches it
Win@DESKTOP-VUMV922 MINGW64 ~/Desktop/demo (feature-dev-01)
$ git commit -m "佳"
[feature-dev-01 683b378] 佳
1 file changed, 1 insertion(+)
Win@DESKTOP-VUMV922 MINGW64 ~/Desktop/demo (feature-dev-01)
$ git push origin feature-dev-01
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 8 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 287 bytes | 287.00 KiB/s, done.
Total 3 (delta 1), reused 0 (delta 0), pack-reused 0
remote:
remote: To create a merge request for feature-dev-01, visit:
remote: http://172.29.9.101:8076/devops6/devops-demo-service/-/merge_requests/new?merge_request%5Bsource_branch%5D=feature-dev-01
remote:
To http://172.29.9.101:8076/devops6/devops-demo-service.git
7cf5639..683b378 feature-dev-01 -> feature-dev-01
Win@DESKTOP-VUMV922 MINGW64 ~/Desktop/demo (feature-dev-01)
$
- 此时可以看到jenkins里的流水线被触发了
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aqRmpjvu-1682425393171)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/image-20230424063019832.png)]
- 这里再在新建一个分支,用于测试,看是否会触发jebnkins流水线
Win@DESKTOP-VUMV922 MINGW64 ~/Desktop/demo (feature-dev-01)
$ git checkout -b feature-003
Switched to a new branch 'feature-003'
Win@DESKTOP-VUMV922 MINGW64 ~/Desktop/demo (feature-003)
$ ls
HELP.md README.md mvnw* mvnw.cmd pom.xml src/
Win@DESKTOP-VUMV922 MINGW64 ~/Desktop/demo (feature-003)
$ echo "i am very hurt" > README.md
Win@DESKTOP-VUMV922 MINGW64 ~/Desktop/demo (feature-003)
$ git add .
warning: in the working copy of 'README.md', LF will be replaced by CRLF the next time Git touches it
Win@DESKTOP-VUMV922 MINGW64 ~/Desktop/demo (feature-003)
$ git commit -m "hurt"
[feature-003 1de466b] hurt
1 file changed, 1 insertion(+), 2 deletions(-)
Win@DESKTOP-VUMV922 MINGW64 ~/Desktop/demo (feature-003)
$ git push origin feature-003
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 8 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 262 bytes | 262.00 KiB/s, done.
Total 3 (delta 1), reused 0 (delta 0), pack-reused 0
remote:
remote: To create a merge request for feature-003, visit:
remote: http://172.29.9.101:8076/devops6/devops-demo-service/-/merge_requests/new?merge_request%5Bsource_branch%5D=feature-003
remote:
To http://172.29.9.101:8076/devops6/devops-demo-service.git
* [new branch] feature-003 -> feature-003
Win@DESKTOP-VUMV922 MINGW64 ~/Desktop/demo (feature-003)
$
可以看到,jenkins流水线被触发了。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uKeDH3jU-1682425393172)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/image-20230424063427563.png)]
🍀 之前代码
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
}
- 进一步更新代码
此时,想要commitId的前8位该如何取呢?
这样处理就好:
println("${Data}")
NewData = readJSON text: "${Data}"
// envName = NewData["envName"]
// appsName = NewData["apps"]["name"]
println("${NewData}")
// Get git repo url 项目地址
srcUrl = NewData["project"]["git_http_url"]
// Get git repo branch
branchName = NewData["ref"] - "refs/heads/"
// Get short commit id 想要commitId的前8位
env.commitId = NewData["checkout_sha"][0..7]
// current build desc
currentBuild.displayName = "${branchName}:${env.commitId}"
currentBuild.description = "src: ${srcUrl}"
pipeline {
agent any
stages {
stage('CheckOut') {
steps {
script {
println("Checkout: ${srcUrl} ${branchName}")
checkout([$class: 'GitSCM',
branches: [[name: "${branchName}"]],
extensions: [],
userRemoteConfigs: [[credentialsId: 'gitlab-root', url: "${srcUrl}"]]])
sh 'ls -l'
}
}
}
}
}
触发测试:(符合预期)
4、手动触发流水线
很简单的,就是在jenkins项目里添加一些选项参数,把这些变量写死在选项参数里就好。
自动触发和手动触发的可以并存的,例如写一些If ……else,但是不推荐。
手动触发:例如有一些版本分支,这些分支名是会变的,因此不是很方便;但是如果不想每次提交都触发流水线,而是等到一个小版本后再触发,这个用手动触发也是可以的哦。
//修改描述信息
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"
}
}
}
}
}
这里做下测试:
- jenkins上创建项目
gitlab-jenkins-service-manual
,配置好选项参数。
- 编写pipeline代码
//修改描述信息
currentBuild.description = "BranchName: ${env.branchName}"
currentBuild.displayName = "${env.branchName}"
pipeline {
agent { label "build01"}
stages {
stage('CheckOut') {
steps {
script {
println("Checkout: ${projectUrl} ${branchName}")
checkout([$class: 'GitSCM',
branches: [[name: "${branchName}"]],
extensions: [],
userRemoteConfigs: [[credentialsId: 'gitlab-root', url: "${projectUrl}"]]])
sh 'ls -l'
}
}
}
stage('Build'){
steps{
script{
println("mvn clean package -DskipTests")
}
}
}
stage('test'){
steps{
script{
println("mvn test")
}
}
}
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZWq1xNg3-1682425393173)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/image-20230425065947246.png)]
- 准备好一个gitlab项目就好。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0jdHoDId-1682425393173)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/image-20230425070037754.png)]
- 测试(符合预期)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4dfgOONl-1682425393173)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/image-20230425065814820.png)]
5、Jenkins消息通知
添加邮箱
邮箱是标配吧。(钉钉机器人也是可以的)
- 默认情况可能每个Gitlab用户没有配置邮箱的, 需要Gitlab用户要配置好邮箱。
- 点击头像进入 edit profile
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oU6PqOcc-1682425393174)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/tstmp_20230424123355.png)]
添加自己邮箱:
这里需要登录到自己的邮箱去确认下:
方法1:或者按如下方式直接配置好自己的gitlab邮箱为qq邮箱:(强制更改) 本次是强制更改的。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-j1VidOF8-1682425393174)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/image-20230424204730808.png)]
点击Edit
:
这里配置好自己的邮箱,点击保存:
可以看到这里的邮箱被确认了:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CTNLrvSR-1682425393175)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/image-20230424205009192.png)]
方法2:在自己的邮箱里确认。
- 奇怪,我这里怎么163、qq邮箱都收不到确认邮件呢??😥
- 经过百度,发现是在gitlab里的配置文件要做下配置的:
[root@devops ~]#docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
11a54a1f4a2a gitlab/gitlab-ce:14.9.3-ce.0 "/assets/wrapper" 6 days ago Up 28 hours (healthy) 0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp, 0.0.0.0:2222->22/tcp devops_tutorial_gitlab
f3f039aa667a jenkins/jenkins:2.332.2-centos7-jdk8 "/sbin/tini -- /usr/…" 4 weeks ago Up 24 hours 0.0.0.0:8080->8080/tcp, :::8080->8080/tcp, 0.0.0.0:50000->50000/tcp, :::50000->50000/tcp jenkins
[root@devops ~]#docker exec -it devops_tutorial_gitlab bash
root@11a54a1f4a2a:/# vi /etc/gitlab/gitlab.rb
#搜索smtp
gitlab_rails['smtp_enable'] = true
gitlab_rails['smtp_address'] = "smtp.163.com"
gitlab_rails['smtp_port'] = 465
gitlab_rails['smtp_user_name'] = "onexlforyou@163.com"
gitlab_rails['smtp_password'] = "NVSMOUfffAxxxccEMXAB"
gitlab_rails['smtp_domain'] = "163.com"
gitlab_rails['smtp_authentication'] = "login"
gitlab_rails['smtp_enable_starttls_auto'] = true
gitlab_rails['smtp_tls'] = true
gitlab_rails['gitlab_email_from'] = 'onexlforyou@163.com'
root@11a54a1f4a2a:/# gitlab-ctl reconfigure
- 此时,发下就可以正常识别到自己的邮箱了:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SZ6LEB58-1682425393176)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/image-20220512231531784.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QZxrlTV3-1682425393176)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/image-20220512231618636.png)]
- 参考链接:
http://t.zoukankan.com/zgz345-p-9122146.html
- 在这个页面配置好邮箱地址,最好这几个email都配置上吧…最后
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yTiQhTTT-1682425393177)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/image-20230424205222529.png)]
- 这里在gitlab上提交一次代码,确认post请求里的数据体是否含
user_email信息
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-G0nCvZFA-1682425393177)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/image-20230424205446256.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-31XOyYPn-1682425393177)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/image-20230424205511731.png)]
可以看到,这里的user_email
数据是有了。
安装Email Extension
插件
- Jenkins需要配置邮件通知,安装插件
Email Extension
安装后重启Jenkins。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ItnszpQZ-1682425393178)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/tstmp_20230424205619.png)]
- 然后进入系统管理->
系统设置
, 先配置下全局的admin的邮箱地址。(最后配置下不然可能会出错的)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Pm9S1M6c-1682425393178)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/image-20230424205904038.png)]
拿到邮箱授权码
- 登入邮箱拿到授权码
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Hj46fHWs-1682425393178)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/tstmp_20230424210549.png)]
zpnchpffffgggvnfgfeqwggzhgecef
发送短信之后获取授权码
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uMNFQ6Ov-1682425393178)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/tstmp_20230424210610.png)]
配置Email Extension
- ->
Extended E-email Notification
。设置邮件系统配置信息。
这里我使用的是QQ邮箱,填写SMTP服务器地址smtp.qq.com
和端口 465
注意要开启SSL,密码为授权码。
这里写下自己的qq的授权码凭证:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yq5sxTb9-1682425393179)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/image-20230424211243147.png)]
- 换个选项注意下: 不选择
HTML
就是普通的文本,HTML
可以支持html网页,更加美观。这里选择HTML
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5hAAXK4j-1682425393179)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/image-20230424211401396.png)]
编写代码
- pipeline as code , 进入片段生成器,生成邮件通知代码。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AmNU2xzm-1682425393179)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/tstmp_20230424211508.png)]
emailext body: 'hello world!....jenkins', subject: 'test.....', to: '2560350642@qq.com'
然后我们将此段代码加入到Jenkins pipeline 中运行, 可以看到效果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-88VOg56c-1682425393179)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/tstmp_20230424211545.png)]
- jenkins as code 将email 写成一个函数。这个通知信息是一个html格式的。
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
}
- 这里继续编写下代码
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uyXhJU4i-1682425393179)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/image-20230424212344209.png)]
println("${Data}")
NewData = readJSON text: "${Data}"
// envName = NewData["envName"]
// appsName = NewData["apps"]["name"]
println("${NewData}")
// Get git repo url 项目地址
srcUrl = NewData["project"]["git_http_url"]
// Get git repo branch
branchName = NewData["ref"] - "refs/heads/"
// Get git user email
userEmail = NewData["user_email"]
// current build desc
currentBuild.displayName = "${branchName}"
currentBuild.description = "src: ${srcUrl}"
pipeline {
agent any
stages {
stage('CheckOut') {
steps {
script {
println("Checkout: ${srcUrl} ${branchName}")
checkout([$class: 'GitSCM',
branches: [[name: "${branchName}"]],
extensions: [],
userRemoteConfigs: [[credentialsId: 'gitlab-root', url: "${srcUrl}"]]])
sh 'ls -l'
}
}
}
}
post {
always{
script{
EmailUser(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
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zMluC30w-1682425393180)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/image-20230424220307725.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EdJCbw0P-1682425393180)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/image-20230424220258311.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Y1cjr9Vu-1682425393180)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/image-20230424220237905.png)]
触发测试
- 提交下代码,触发下
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Me3WP333-1682425393180)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/image-20230424212630637.png)]
- 自己的测试现象(符合预期)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aoccgQGI-1682425393180)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/image-20230424214039852.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fM9J30cm-1682425393180)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/image-20230424214104233.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kE3BBZoj-1682425393181)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/image-20230424214122673.png)]
解决默认图片显示异常问题
- 可以看到这里的人图片显示异常,这里我们使用oss路径来存储图片就可以了。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rLK47nvC-1682425393181)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/image-20230424220342128.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZwsrlHfV-1682425393181)(https://bucket-hg.oss-cn-shanghai.aliyuncs.com/img/image-20230425161711144.png)]
本次最新代码(测试成功)
//打印jenkins的Generic Webhook Trigger接收到的数据,默认为字符串
println("${Data}")
//格式化webhook接收的数据为json格式
NewData = readJSON text: "${Data}" //$表示全量数据
// envName = NewData["envName"]
// appsName = NewData["apps"]["name"]
println("${NewData}")
// Get git repo url 项目地址
srcUrl = NewData["project"]["git_http_url"]
// Get git repo branch 提交分支
branchName = NewData["ref"] - "refs/heads/"
// Get git user email
userEmail = NewData["user_email"]
// Get short commit id 想要commitId的前8位 commit ID
env.commitId = NewData["checkout_sha"][0..7]
//env.commitId = NewData["checkout_sha"]
// 提交人
env.commitUser = NewData["user_username"]
//这里为什么要使用env.定义变量呢? 因为全局变量保险些,便于后面所有阶段间的引用;
// current build desc
currentBuild.displayName = "${branchName}:${env.commitId}"
currentBuild.description = "src: ${srcUrl}"
pipeline {
agent any
stages {
stage('CheckOut') {
steps {
script {
println("Checkout: ${srcUrl} ${branchName}")
checkout([$class: 'GitSCM',
branches: [[name: "${branchName}"]],
extensions: [],
userRemoteConfigs: [[credentialsId: 'gitlab-root', url: "${srcUrl}"]]])
sh 'ls -l'
}
}
}
// 代码构建
stage("Build"){
steps{
script{
echo "build"
}
}
}
//单元测试
stage("UnitTest"){
steps{
script{
echo "unit test"
}
}
}
//部署
stage("deploy"){
steps {
script{
echo "deploy"
}
}
}
}
post {
always{
script{
EmailUser(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="https://s1.ax1x.com/2023/04/25/p9usju8.jpg">
<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
}