需求说明
公司有很多在开发中的项目,每天都要在测试环境、UAT环境、正式环境多次发布。之前搞了个Jenkins,每次构建的时候都要登录Jenkins输入一下分支并点击构建,构建后发送邮件通知相关人员,但是公司大多数人都不看邮件,于是要弄成推送信息至企业微信,所以就顺便了配置利用gitlab的webhook触发Jenkins构建。
刚开始是准备用企业微信机器人发送信息的,后来觉得企业微信机器人有点局限性,就使用企业微信的自建应用来推送信息。
效果如下:
开发A push代码至develop分支后,Jenkins自动构建,构建成功后推送信息至企业微信
所需插件
Gitlab Hook Plugin
GitLab Plugin
Post build task
Change Log
安装Change Log
插件
Change Log插件为第三方插件,需要额外自己编译
参考大佬的:https://www.jianshu.com/p/f03fc1bf5783
或下载已编译好的
百度云链接:https://pan.baidu.com/s/1SayjomDCw6_YTbaJUfoXPQ
提取码:0t5j
准备好hpi文件后,在系统管理-插件管理-高级中选择上传即可
准备推送信息的python脚本
Jenkins-WKwhcat.py
# encoding: utf-8
import requests
import argparse
import datetime
"""
corp_id 企业ID
corpsecret 应用Secret
agentid 应用ID
"""
class Msgevent(object):
def __init__(self, corp_id, corpsecret, agentid):
self.__corp_id = corp_id
self.__corpsecret = corpsecret
self.__agentid = agentid
@property
def access_token(self):
try:
response = requests.get(
'https://qyapi.weixin.qq.com/cgi-bin/gettoken?',
params={
"corpid": self.__corp_id,
"corpsecret": self.__corpsecret
}
)
if "access_token" in response.json().keys():
return response.json().get("access_token")
except Exception as e:
print(e)
return ["ERROR"]
def sendmsg(self, touser,
toparty,
title="The test title",
site="https://www.lejian.com",
giturl="https://git.lejian.net",
new_tag="jenkins-tag",
build_log="https://jk.lejian.net/",
build_status="build_status",
build_number=0,
build_class="build_class",
build_branch="build_branch",
git_commit="git_commit",
build_user=False,
commit_log=False,
commit_user=False,
commit_date=False):
if build_status == "Successful":
build_status = "<font color='info'>Successful</font>"
if build_class == "Deploy":
build_class = "发布"
elif build_class == "Rollback":
build_class = "回滚"
last_tag = "last_tag"
if isinstance(build_number, int):
last_tag = "jenkins-tag-" + str(build_number - 1)
send_body = {
"msgtype": "markdown",
"agentid": self.__agentid,
"markdown": {
"content": "### {title} {build_class}通知\n"
">**关联站点**: [{site}]({site})\n"
">远程仓库地址: [{giturl}]({giturl})\n"
">**构建时间**: {build_time}\n"
">构建分支: {build_branch}\n"
">构建commit: {git_commit}\n"
">构建日志: [{build_log}console]({build_log}cosole)\n"
">构建状态: <font color='info'>{build_status}</font>\n"
">构建tag: <font color='info'>{new_tag}</font> \n"
">回滚tag: <font color='warning'>{last_tag}</font>".format(title=title,
site=site,
giturl=giturl,
git_commit=git_commit,
new_tag=new_tag,
last_tag=last_tag,
build_time=datetime.datetime.now().strftime(
"%Y-%m-%d %H:%M:%S"),
build_log=build_log,
build_status=build_status,
build_class=build_class,
build_branch=build_branch)
},
"enable_duplicate_check": 0,
"duplicate_check_interval": 1800
}
if touser != "No" and toparty == "No":
send_body["touser"] = touser
if toparty != "No" and touser == "No":
send_body["toparty"] = toparty
if touser != "No" and toparty != "No":
send_body["touser"] = touser
send_body["toparty"] = toparty
if build_user:
send_body.get("markdown")["content"] = send_body.get("markdown").get("content") + "\n>构建用户: %s" % build_user
if commit_log:
send_body.get("markdown")["content"] = send_body.get("markdown").get("content") + "\n>提交记录: %s" % commit_log
if commit_user:
send_body.get("markdown")["content"] = send_body.get("markdown").get("content") + "\n>提交人: %s" % commit_user
if commit_date:
send_body.get("markdown")["content"] = send_body.get("markdown").get("content") + "\n>提交时间: %s" % commit_date
print(send_body)
try:
response = requests.post(
"https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=%s" % self.access_token,
json=send_body
)
if response.json().get("errcode") == 0:
print("发送成功:\n", response.text)
return 0
else:
print("发送失败\n", response.text)
except Exception as error_info:
print("发送信息失败:\n", error_info)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="设置发送信息内容")
parser.add_argument('--corp_id', help="指定企业ID")
parser.add_argument('--corpsecret', help="指定应用corpsecret",)
parser.add_argument('--agentid', help="指定应用ID")
parser.add_argument('--touser', help="指定接收用户")
parser.add_argument('--toparty', help="指定接收信息部门")
parser.add_argument('--title', help="信息标题", default="The test title")
parser.add_argument('--site', help="指定关联站点", default="https://www.baidu.com")
parser.add_argument('--giturl', help="git仓库地址", default="https://example.gitlab.com")
parser.add_argument('--build_user', help="构建人")
parser.add_argument('--new_tag', help="构建标记", default="Jenkins tag")
parser.add_argument('--build_log', help="构建日志")
parser.add_argument('--build_status', help="构建状态", default="build_status")
parser.add_argument('--build_number', help="构建版本号", default="build_number")
parser.add_argument('--build_branch', help="构建分支", default="build_branch")
parser.add_argument('--build_class', help="构建类型", default="build_class")
parser.add_argument('--git_commit', help="构建commit", default="git_commit")
parser.add_argument('--commit_log', help="提交记录",)
parser.add_argument('--commit_user', help="提交人",)
parser.add_argument('--commit_date', help="提交时间",)
args = parser.parse_args()
if args.corp_id is None or \
args.corpsecret is None or \
args.agentid is None or \
args.touser is None or \
args.toparty is None:
print("请指定以下信息"+
"\n--corp_id 指定企业ID" +
"\n--corpsecret 指定应用corpsecret" +
"\n--agentid 指定应用ID" +
"\n--touser 接收消息用户" +
"\n--toparty 接收消息部门ID")
exit(2)
try:
int(args.build_number)
except Exception as e:
print(e)
exit(200)
jenkins_msg = Msgevent(args.corp_id, args.corpsecret, args.agentid)
jenkins_msg.sendmsg(touser=args.touser,
toparty=args.toparty,
title=args.title,
site=args.site,
giturl=args.giturl,
build_user=args.build_user,
new_tag=args.new_tag,
build_log=args.build_log,
build_status=args.build_status,
build_branch=args.build_branch,
build_class=args.build_class,
build_number=int(args.build_number),
git_commit=args.git_commit,
commit_date=args.commit_date,
commit_log=args.commit_log,
commit_user=args.commit_user)
把以下python脚本内容复制到jenkins服务器上,服务器上的Python需要安装requests模块
企业微信创建自建应用并记录下
企业ID
自建应用的AgentId和Secret
创建一个自由风格的项目
添加构建参数
添加一个选项参数如下
添加一个Git parameter参数如下
添加一个字符参数如下
源码管理中填写如下
添加一个触发器
记住这个url
记住这个token
构建环境中选中
Add Changelog Information to Environment
%3$s@%4$s@%1$s
表示commit 内容
@提交用户
@提交时间
用
@
符号分割是为了方便在构建后操作中使用shell处理可以在构建中添加要执行的shell或者其他的,具体按照自己的需要来设置,这里为了演示,仅添加了一个
Set build description
内容为:
构建分支<span style="font-size:16px;color:red;">$GIT_BRANCH</span><span style="font-size:16px;"></span>
添加一个构建后参数Post build task
Script
框中填写需要执行的shellshell内容为:
COMMIT_LOG=`echo ${SCM_CHANGELOG} |awk -F'@' '{print $1}'`
COMMIT_USER=`echo ${SCM_CHANGELOG} |awk -F'@' '{print $3}'`
COMMIT_DATE=`echo ${SCM_CHANGELOG} |awk -F'@' '{print $2}'`
python /opt/.jenkins/scripts/jenkins-wkwechat.py \
--corp_id="企业ID" \
--corpsecret="企业微信自自建应用的Secret" \
--agentid="企业微信自建应用的AgentId" \
--touser="zhangsan" \
--toparty="15" \
--title="${JOB_NAME}" \
--site="${site}" \
--giturl="${GIT_URL}" \
--build_log="${BUILD_URL}" \
--build_status="Successful" \
--new_tag="jenkins-tag-${BUILD_NUMBER}" \
--build_number="${BUILD_NUMBER}" \
--build_class="${build_class}" \
--build_branch="${GIT_BRANCH}" \
--git_commit="${GIT_COMMIT}" \
--build_user="${BUILD_USER}" \
--commit_log="${COMMIT_LOG}" \
--commit_user="${COMMIT_USER}" \
--commit_date="${COMMIT_DATE}"
--corp_id
"企业ID"
--corpsecret
"企业微信自自建应用的Secret"
--agenti
"企业微信自建应用的AgentId"
--touser
表示执行接收消息的用户,填写企业微信中用户的ID,如果是多个的话用|
分割,如:
--touser="zhangsan|lisi"
--toparty
表示接收消息的部门,填写部门ID,多个的话与用户一样
--toparty="11|15|23"
勾选Run script only if all previous steps were successful
注意
这里有一个问题,我在使用的时候无法判断是成功还是失败了,所以我这里才勾选了Run script only if all previous steps were successful
,就是说当只有构建成功的时候才执行脚本,就是当一个开发push代码后,如果收到信息就表示发布成功了,但是失败的时候怎么发送信息呢?如果有大佬可以解惑请留言
配置完成后点击保存
配置gitlab
登录gitlab,找到对应的项目,选择Settings中的Integrations
添加完成后测试以下,点击test => Push events
出现如下内容表示成功
可以看下Jenkins,如果配置没有错误的话,应该已经构建了一次了
现在来测试一下
随便push一点东西
收到企业微信推送信息如下
查看Jenkins
回滚
如果发布后需要回滚,直接在Build with Parameters中选择上次的构建tag构建就行
回滚构建后,同样收到推送的信息