共计 4244 个字符,预计需要花费 11 分钟才能阅读完成。
本文是 2020 年的文章,在公司过后的环境写的了,当初大部分公司都有 Devops 效力平台采纳 docker 或者 oss 部署
前言
本篇是之前写的《利用 Gitlab CI/CD 实现主动构建,主动部署》的续篇。咱们晓得 Gitlab 的 Pipeline 中的 Job 执行胜利或者失败之后,对应 Job 状态会扭转为 passedorfailed,当 Job 的状态扭转之后,咱们须要再到 Gitlab CI/CD 的页面下查看 Job 的状态, 去看看有没有打包实现。
实际表明,某些时候咱们的 gitlab 执行 Job 往往须要期待很长且不稳固。导致咱们重复到 CI/CD 的页面看看 Job 是否执行结束。所以咱们须要一个更敌对,高效的 Job 执行实现状态的反馈计划。由此我想到了钉钉告诉机器人。
引入钉钉机器人
其实就是在一个钉钉群引入 webhook 机器人,而后给你提供 token 和 secret,按照指定的格局发动 http 申请就能够了
详情请看:https://ding-doc.dingtalk.com/doc#/serverapi3/iydd5h
官网文档解析很分明,须要留神点就是须要加签这个步骤:
/* 把 timestamp+"\n"+ 密钥当做签名字符串,应用 HmacSHA256 算法计算签名,而后进行 Base64 encode,\n | |
最初再把签名参数再进行 urlEncode,失去最终的签名(须要应用 UTF- 8 字符集)。- 这里用 node 的 crypto 加密模块实现, 大略实现如下 | |
*/ | |
const encryptSign = (secret, content) => { | |
const str = crypto | |
.createHmac("sha256", secret) | |
.update(content) | |
.digest() | |
.toString("base64"); | |
return encodeURIComponent(str); | |
}; | |
const sign = encryptSign(this.secret, timestamp + "\n" + this.secret); |
定制钉钉机器人
钉钉机器人反对多种类型音讯,咱们须要的是一个文本和卡片类型音讯,图片如下。
联合钉钉文档,咱们封装了本人的机器人 dingtalkBot 类, 反对疾速发送文本和卡片音讯。脚本如下:
dingtalkBot.js
/* eslint-disable @typescript-eslint/no-var-requires */ | |
const crypto = require("crypto"); | |
const axios = require("axios"); | |
const encryptSign = (secret, content) => { | |
const str = crypto | |
.createHmac("sha256", secret) | |
.update(content) | |
.digest() | |
.toString("base64"); | |
return encodeURIComponent(str); | |
}; | |
/** | |
* 钉钉机器人 WebHook:用于反对钉钉机器人音讯发送 | |
* | |
* 官网文档:https://ding-doc.dingtalk.com/doc#/serverapi2/qf2nxq | |
*/ | |
class DingtalkBot { | |
/** | |
* 机器人工厂,所有的音讯推送我的项目都会调用 this.webhook 接口进行发送 | |
* | |
* @param {String} options.webhook 残缺的接口地址 | |
* @param {String} options.baseUrl 接口地址 | |
* @param {String} options.accessToken accessToken | |
* @param {String} options.secret secret | |
*/ | |
constructor(options) {options = options || {}; | |
if (!options.webhook && !(options.accessToken && options.baseUrl)) {throw new Error("Lack for arguments!"); | |
} | |
// 优先应用 options.webhook | |
// 次之将由 options.baseUrl 和 options.accessToken 组合成一个 webhook 地址 | |
this.webhook = | |
options.webhook || | |
`${options.baseUrl}?access_token=${options.accessToken}`; | |
this.secret = options.secret; | |
} | |
/** | |
* 发送钉钉音讯 | |
* | |
* @param {Object} content 动员的音讯对象 | |
* @return {Promise} | |
*/ | |
send(content) { | |
let singStr = ""; | |
if (this.secret) {const timestamp = Date.now(); | |
singStr = | |
"×tamp=" + | |
timestamp + | |
"&sign=" + | |
encryptSign(this.secret, timestamp + "\n" + this.secret); | |
} | |
return axios.request(this.webhook + singStr, { | |
method: "POST", | |
headers: {"Content-Type": "application/json",}, | |
data: JSON.stringify(content), | |
}); | |
} | |
/** | |
* 发送纯文本音讯,反对 @群内成员 | |
* | |
* @param {String} content 音讯内容 | |
* @param {Object} at 群内 @成员的手机号 | |
* @return {Promise} | |
*/ | |
text(content, at) {at = at || {}; | |
return this.send({ | |
msgtype: "text", | |
text: {content,}, | |
at, | |
}); | |
} | |
/** | |
* 发送 actionCard(动作卡片) | |
* Ps: 反对多个按钮,反对 Markdown | |
* | |
* @param {String} card.title 题目 | |
* @param {String} card.text 音讯内容 | |
* @param {String} card.btnOrientation 按钮排列的方向(0 竖直,1 横向,默认为 0) | |
* @param {String} card.btn.title 某个按钮题目 | |
* @param {String} card.btn.actionURL 某个按钮链接 | |
* @return {Promise} | |
*/ | |
actionCard(card) { | |
return this.send({ | |
msgtype: "actionCard", | |
actionCard: { | |
title: card.title, | |
text: card.text, | |
btnOrientation: card.btnOrientation || 0, | |
btns: card.btns || [],}, | |
}); | |
} | |
} | |
module.exports = DingtalkBot; |
定制音讯模板
下面的音讯类型咱们晓得,咱们须要一些构建信息(我的项目,分支,环境等),还有须要 @指定的提交人。通过折腾, 咱们晓得 gitlab runner 执行 node 脚本时, process.env 这个变量下蕴含着咱们须要的所有变量,如图所示
下面的截图只是一部分
由此咱们定义如下的 markdown 格局模板
除了卡片音讯之外。咱们须要 @告诉指定提交人。根据钉钉提供的 API,咱们须要提交人的电话号码信息。那咱们裸露提交人的电话号码信息在 node 执行 js 的时候呢。同样通过折腾,咱们能够为我的项目设置环境变量,gitlab runner 执行 Job 时,就会裸露在其中执行环境中,详情看:https://docs.gitlab.com/help/ci/variables/README#variables
例如:
这里设置了 luxuemin 的变量名,变量值为我的号码:xxxxx。
留神: 这里存在映射关系, 变量名为 luxuemin, 是我的 gitlab 平台上的用户名, 应该也是 git 的用户名,如图
配置好映射关系,咱们就能 @指定的提交人了。
const gitlabUserName = process.env.GITLAB_USER_NAME; | |
const phoneNumber = process.env[gitlabUserName]; // 在 gitlab CI/CD 上配置 GITLAB_USER_NAME 映射的电话号码 | |
await robot.text("请查收你的构建信息", {atMobiles: [phoneNumber], | |
isAtAll: false, | |
}); |
发送音讯脚本文件 notify.js
下面的脚本文件还加了一个 Github Today Trending 的小彩蛋(随机举荐一个 github 的今日风行趋势我的项目),和随机一张养眼图片。
如图:
在之前的脚本中应用
依据模仿 jenkins 申请的后果,node 执行下面的脚本之前,携带胜利,失败状态,这里用 status 示意,同时推出 js 脚本是,用 process.exit(status)退出,可参考上面脚本
RES=$( curl -X POST \ | |
--user tao-tao:1169ee9c0493b27d915632c0577fdd66fd \ | |
--data 'json={"parameter":[{"name":"PJ","value":"crm-finance-static"},{"name":"MYENV","value":"'$env'"},{"name":"TAG","value":"'$branch'"}]}' \ | |
--compressed \ | |
'http://xxxx/job/tao.tao/build?delay=0sec' \ | |
) | |
# if ["$RES"]; then {echo 'failed!'; exit 1;} fi | |
if ["$RES"]; then | |
node scripts/notify.js $env $branch --status=1 || {echo 'failed!'; exit 1;} | |
else | |
node scripts/notify.js $env $branch --status=0 && {echo 'succused!'; exit 0;} | |
fi |
最初
目前配置了 crm-finance 引入了这个机器人。后续须要的小伙伴可在本人的我的项目中引入,如果小伙伴想进入 Gitlab&Dingtalk 告诉机器人测试群,可扫码退出哈。热烈欢迎!
原文地址:https://github.com/jackluson/…