Jenkins配置Gitlab webhook并通过企业微信自建应用推送发布信息至企业微信

需求说明

公司有很多在开发中的项目,每天都要在测试环境、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

企业ID

AgentId&Secret

创建一个自由风格的项目

创建项目

添加构建参数
添加一个选项参数如下
添加选项参数

添加一个Git parameter参数如下
Git parameter参数

添加一个字符参数如下
字符参数

源码管理中填写如下
源码管理

添加一个触发器
记住这个url
添加触发器

记住这个token
添加触发器

构建环境中选中Add Changelog Information to Environment
构建环境

%3$s@%4$s@%1$s 表示commit 内容@提交用户@提交时间
@符号分割是为了方便在构建后操作中使用shell处理
可以在构建中添加要执行的shell或者其他的,具体按照自己的需要来设置,这里为了演示,仅添加了一个Set build description
Set build description

内容为:构建分支<span style="font-size:16px;color:red;">$GIT_BRANCH</span><span style="font-size:16px;"></span>
添加一个构建后参数Post build task
Post build task

Script框中填写需要执行的shell
shell内容为:

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

配置gitlab

配置Jenkins

构建器中的URL

构建器中的token

添加完成后测试以下,点击test => Push events
测试

出现如下内容表示成功
正常

可以看下Jenkins,如果配置没有错误的话,应该已经构建了一次了
现在来测试一下
随便push一点东西
push

收到企业微信推送信息如下
收到信息

查看Jenkins
Jenkins

回滚

如果发布后需要回滚,直接在Build with Parameters中选择上次的构建tag构建就行

回滚

回滚构建后,同样收到推送的信息
回滚信息

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,417评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,921评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,850评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,945评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,069评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,188评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,239评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,994评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,409评论 1 304
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,735评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,898评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,578评论 4 336
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,205评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,916评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,156评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,722评论 2 363
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,781评论 2 351