1. Lark Notice介绍
Lark Notice Plugin 是一个用于 Jenkins 的构建通知插件,可以将 Jenkins构建过程以及结果通知推送到 Lark、飞书、钉钉 协作平台。 可配置多个的通知时机,包括 构建启动时、构建中断、构建失败、构建成功时、构建不稳定 等。 支持多种不同类型的消息,包括 文本消息、图片消息, 群名片消息、富文本消息、卡片消息; 同时该插件还提供了自定义模板和变量的功能,使您能够根据自己的需求来定制通知消息的内容和格式
2. 安装插件
版本依赖,jenkins-2.414.x
Lark Notice(通过上传文件的方式安装)https://721806280.github.io/lark-notice-plugin-doc/
从 Jenkins 首页开始,点击 系统管理
-> 插件管理
, 找到 Deploy Plugin
选项后输入插件地址后点击 deploy
即可
下载地址,https://nnaigos.oss-cn-hangzhou.aliyuncs.com/lark-notice.hpi
3. 机器人配置
3.2 申请机器人
准备工作,在飞书群新建一个机器人(https://open.feishu.cn/document/client-docs/bot-v3/add-custom-bot)
- 配置关键字
之后保存即可
3.2 配置
打开 Manage Jenkins
页面,找到 Lark Notice
配置项,如下图所示:
点进去
- 测试
- 效果
- 重启jenkins服务
bash
http://url/safeRestart
http://url/safeRestart
4. 线上案例
bash
def git_address = "http://house.freehan.ink/root/springdemo.git"
def git_auth = "02d72dd6-0eab-4261-b0c0-12824e083421"
def tag = "latest"
def harbor_url = "registry.cn-zhangjiakou.aliyuncs.com"
def harbor_project_name = "spring"
def harbor_auth = "1e7ee468-9da7-469b-a43a-56556b56f308"
def start = new Date().format('yyyy-MM-dd HH:mm:ss')
// 通知机器人配置
def lark_robot_id = "55d84e77-d1c5-4b1c-9e0f-ea1630b4e236'" // 飞书机器人ID
podTemplate(label: 'jenkins-slave-java', cloud: 'kubernetes', containers: [
containerTemplate(
name: 'jnlp',
image: "registry.cn-zhangjiakou.aliyuncs.com/hsuing/jenkins-slave-maven:v1",
ttyEnabled: true
),
containerTemplate(
name: 'docker',
image: "registry.cn-zhangjiakou.aliyuncs.com/hsuing/docker:stable",
ttyEnabled: true,
command: 'cat'
)
],
volumes: [
hostPathVolume(mountPath: '/var/run/docker.sock', hostPath:'/var/run/docker.sock'),
],
)
{
node("jenkins-slave-java") {
try {
stage('拉取代码') {
checkout([$class: 'GitSCM', branches: [[name: '*/main']], extensions: [], userRemoteConfigs: [[credentialsId: git_auth, url: git_address]]])
}
//定义全局newTag
def newTag = sh(returnStdout: true,script: 'echo `date +"%Y%m%d%H%M"_``git describe --tags --always`').trim()
stage('编译描述') {
// 自定义设置构建历史显示的名称和描述信息
// 不同的部署方式设置构建历史显示的名称和描述信息方式不一样,根据自己的部署方式自行百度找到设置方法
script {
//设置buildName
wrap([$class: 'BuildUser']) {
//修改Description
buildDescription "${BUILD_USER} > ${project_name} > ${branch}"
}
}
}
stage('代码编译') {
def selectedProjects = project_name.split(',')
selectedProjects.each { currentProjectName ->
def imageName = "${currentProjectName}:${tag}"
//def newTag = sh(returnStdout: true, script: 'echo `date +"%Y%m%d%H%M"_``git describe --tags --always`').trim()
sh "mvn clean package -Dmaven.test.skip=true"
}
}
stage('构建镜像') {
def selectedProjects = project_name.split(',')
container('docker') {
selectedProjects.each { currentProjectName ->
def imageName = "${currentProjectName}:${tag}"
//def newTag = sh(returnStdout: true, script: 'echo `date +"%Y%m%d%H%M"_``git describe --tags --always`').trim()
sh "docker build -t ${imageName} ."
sh "docker tag ${imageName} ${harbor_url}/hsuing/${harbor_project_name}:${newTag}"
withCredentials([usernamePassword(credentialsId: harbor_auth, passwordVariable: 'password', usernameVariable: 'username')]) {
//登录
sh "docker login -u ${username} -p ${password} ${harbor_url}"
//上传镜像
sh "docker push ${harbor_url}/hsuing/${harbor_project_name}:${newTag}"
}
//删除本地镜像
sh "docker rmi -f ${imageName}"
sh "docker rmi -f ${harbor_url}/hsuing/${harbor_project_name}:${newTag}"
}
}
}
stage('部署到k8s平台') {
def selectedProjects = project_name.split(',')
selectedProjects.each { currentProjectName ->
//def newTag = sh(returnStdout: true, script: 'echo `date +"%Y%m%d%H%M"_``git describe --tags --always`').trim()
def deploy_image_name = "${harbor_url}/hsuing/${harbor_project_name}:${newTag}"
sh """
sed -i 's#\$IMAGE_NAME#${deploy_image_name}#' deployment.yaml
sed -i 's#\$APP_NAME#${currentProjectName}#' deployment.yaml
sed -i 's#\$APP_REPLICAS#${replicas}#' deployment.yaml
sed -i 's#\$NAMESPACE#${namespaces}#' deployment.yaml
sed -i 's#\$SPRINGENV#${springProfilesActive}#' deployment.yaml
sed -i 's#\$PODMEMORY#${podsMem}#' deployment.yaml
sed -i 's#\$PODCPU#${podsCpu}#' deployment.yaml
cat deployment.yaml
"""
kubernetesDeploy(kubeconfigId: "55a88b59-fd12-4bf0-ba57-8a664fed2f71", configs: "deployment.yaml")
}
}
stage('发送飞书通知') {
// 获取执行用户
wrap([$class: 'BuildUser']) {
// 发送飞书通知
lark (
robot: "$lark_robot_id",
type: "CARD",
title: "📢 Jenkins 镜像构建成功",
text: [
"📋 **任务名称**:[${JOB_NAME}](${JOB_URL})",
"🔢 **任务编号**:[${BUILD_DISPLAY_NAME}](${BUILD_URL})",
"🌟 **构建状态**: <font color='green'>成功</font>",
"🤩 **镜像版本**: ${newTag}",
"😎 **镜像仓库**: ${harbor_url}/hsuing/${harbor_project_name}",
"🕐 **构建用时**: ${currentBuild.duration} ms",
"👤 **执行者**: ${env.BUILD_USER}",
"<at id=all></at>"
],
buttons: [
[
title: "更改记录",
url: "${BUILD_URL}changes"
],
[
title: "控制台",
type: "danger",
url: "${BUILD_URL}console"
]
]
)
}
}
} catch (Exception e) {
currentBuild.result = 'FAILURE'
error "Pipeline failed: ${e.message}"
}
}
}
def git_address = "http://house.freehan.ink/root/springdemo.git"
def git_auth = "02d72dd6-0eab-4261-b0c0-12824e083421"
def tag = "latest"
def harbor_url = "registry.cn-zhangjiakou.aliyuncs.com"
def harbor_project_name = "spring"
def harbor_auth = "1e7ee468-9da7-469b-a43a-56556b56f308"
def start = new Date().format('yyyy-MM-dd HH:mm:ss')
// 通知机器人配置
def lark_robot_id = "55d84e77-d1c5-4b1c-9e0f-ea1630b4e236'" // 飞书机器人ID
podTemplate(label: 'jenkins-slave-java', cloud: 'kubernetes', containers: [
containerTemplate(
name: 'jnlp',
image: "registry.cn-zhangjiakou.aliyuncs.com/hsuing/jenkins-slave-maven:v1",
ttyEnabled: true
),
containerTemplate(
name: 'docker',
image: "registry.cn-zhangjiakou.aliyuncs.com/hsuing/docker:stable",
ttyEnabled: true,
command: 'cat'
)
],
volumes: [
hostPathVolume(mountPath: '/var/run/docker.sock', hostPath:'/var/run/docker.sock'),
],
)
{
node("jenkins-slave-java") {
try {
stage('拉取代码') {
checkout([$class: 'GitSCM', branches: [[name: '*/main']], extensions: [], userRemoteConfigs: [[credentialsId: git_auth, url: git_address]]])
}
//定义全局newTag
def newTag = sh(returnStdout: true,script: 'echo `date +"%Y%m%d%H%M"_``git describe --tags --always`').trim()
stage('编译描述') {
// 自定义设置构建历史显示的名称和描述信息
// 不同的部署方式设置构建历史显示的名称和描述信息方式不一样,根据自己的部署方式自行百度找到设置方法
script {
//设置buildName
wrap([$class: 'BuildUser']) {
//修改Description
buildDescription "${BUILD_USER} > ${project_name} > ${branch}"
}
}
}
stage('代码编译') {
def selectedProjects = project_name.split(',')
selectedProjects.each { currentProjectName ->
def imageName = "${currentProjectName}:${tag}"
//def newTag = sh(returnStdout: true, script: 'echo `date +"%Y%m%d%H%M"_``git describe --tags --always`').trim()
sh "mvn clean package -Dmaven.test.skip=true"
}
}
stage('构建镜像') {
def selectedProjects = project_name.split(',')
container('docker') {
selectedProjects.each { currentProjectName ->
def imageName = "${currentProjectName}:${tag}"
//def newTag = sh(returnStdout: true, script: 'echo `date +"%Y%m%d%H%M"_``git describe --tags --always`').trim()
sh "docker build -t ${imageName} ."
sh "docker tag ${imageName} ${harbor_url}/hsuing/${harbor_project_name}:${newTag}"
withCredentials([usernamePassword(credentialsId: harbor_auth, passwordVariable: 'password', usernameVariable: 'username')]) {
//登录
sh "docker login -u ${username} -p ${password} ${harbor_url}"
//上传镜像
sh "docker push ${harbor_url}/hsuing/${harbor_project_name}:${newTag}"
}
//删除本地镜像
sh "docker rmi -f ${imageName}"
sh "docker rmi -f ${harbor_url}/hsuing/${harbor_project_name}:${newTag}"
}
}
}
stage('部署到k8s平台') {
def selectedProjects = project_name.split(',')
selectedProjects.each { currentProjectName ->
//def newTag = sh(returnStdout: true, script: 'echo `date +"%Y%m%d%H%M"_``git describe --tags --always`').trim()
def deploy_image_name = "${harbor_url}/hsuing/${harbor_project_name}:${newTag}"
sh """
sed -i 's#\$IMAGE_NAME#${deploy_image_name}#' deployment.yaml
sed -i 's#\$APP_NAME#${currentProjectName}#' deployment.yaml
sed -i 's#\$APP_REPLICAS#${replicas}#' deployment.yaml
sed -i 's#\$NAMESPACE#${namespaces}#' deployment.yaml
sed -i 's#\$SPRINGENV#${springProfilesActive}#' deployment.yaml
sed -i 's#\$PODMEMORY#${podsMem}#' deployment.yaml
sed -i 's#\$PODCPU#${podsCpu}#' deployment.yaml
cat deployment.yaml
"""
kubernetesDeploy(kubeconfigId: "55a88b59-fd12-4bf0-ba57-8a664fed2f71", configs: "deployment.yaml")
}
}
stage('发送飞书通知') {
// 获取执行用户
wrap([$class: 'BuildUser']) {
// 发送飞书通知
lark (
robot: "$lark_robot_id",
type: "CARD",
title: "📢 Jenkins 镜像构建成功",
text: [
"📋 **任务名称**:[${JOB_NAME}](${JOB_URL})",
"🔢 **任务编号**:[${BUILD_DISPLAY_NAME}](${BUILD_URL})",
"🌟 **构建状态**: <font color='green'>成功</font>",
"🤩 **镜像版本**: ${newTag}",
"😎 **镜像仓库**: ${harbor_url}/hsuing/${harbor_project_name}",
"🕐 **构建用时**: ${currentBuild.duration} ms",
"👤 **执行者**: ${env.BUILD_USER}",
"<at id=all></at>"
],
buttons: [
[
title: "更改记录",
url: "${BUILD_URL}changes"
],
[
title: "控制台",
type: "danger",
url: "${BUILD_URL}console"
]
]
)
}
}
} catch (Exception e) {
currentBuild.result = 'FAILURE'
error "Pipeline failed: ${e.message}"
}
}
}
- 效果
- 报警效果