jira未清bug介入企业微信通知

背景:jira上测试人员提的bug,对应的开发人员可以收到对应的邮件通知,但是对应的项目其他人员可能不知道目前bug的解决情况,可以将jira上对应的未清bug介入到企业微信,定时推送,实现bug透明化

1. 目录结构如下:

--config:主要配置一些固定的配置:jira地址,jira上bug的链接sql,对应的测试人员跟开发人员信息,对应企业微信群机器人链接等

--outstandingbug:主要处理未清bug的核心逻辑

--run_6_30:主要定义运行的脚本

2. 代码中的内容如下:

config.py代码内容

#jira链接地址
url = "https://jira.xxxxxxx.com/"
# 测试人员还有多少bug需要跟进的链接
url_tests = "https://jira.xxxxx-internal.com/issues/?jql=issuetype%20in%20(BUG%2C%20%E6%95%85%E9%9A%9C)" \
            "%20AND%20status%20in%20(%E6%9C%AA%E5%BC%80%E5%90%AF%2C%20REOPENED%2C%20%E4%BF%AE%E5%A4%8D%E4%B8%AD%" \
            "2C%20%22To%20Do%22%2C%20%E5%A4%84%E7%90%86%E4%B8%AD%2C%20%E8%BF%9B%E8%A1%8C%E4%B8%AD)%20AND%20creator%20" \
            "in%20(currentUser())%20AND%20created%20%3E%3D%20{}%20ORDER%20BY%20priority%20DESC%2C%20updated%" \
            "20DESC".format("2021-08-09")
url_tests_p0_p1 = "https://jira.xxxx-internal.com/issues/?jql=project%20%3D%20LOGISTIC%20AND%20issuetype%20%3D%20BUG%20AND%20status%20in%20(%E6%9C%AA%E5%BC%80%E5%90%AF%2C%20REOPENED%2C%20%E5%A4%84%E7%90%86%E4%B8%AD)%" \
                  "20AND%20priority%20in%20(%E7%B4%A7%E6%80%A5%2C%20%E9%87%8D%E8%A6%81)%20AND%20creator%20in%20" \
                  "(currentUser())%20ORDER%20BY%20priority%20DESC%2C%20updated%20DESC"
# 日期链接(发给开发的)
url_data_time = "https://jira.xxxx-internal.com/issues/?jql=project%20%3D%20LOGISTIC%20AND%20issuetype%20%3D%20BUG%20AND%20status%20in%20(%E6%9C%AA%E5%BC%80%E5%90%AF%2C%20REOPENED%2C%20%E5%A4%84%E7%90%86%E4%B8%AD)%20AND%20created%" \
                "20%3E%3D%20{}%20AND%20assignee%20in%20(currentUser())%20ORDER%20BY%20priority%20DESC%2C%20" \
                "updated%20DESC".format("2021-08-09")
url_minute = "https://jira.xxxxx-internal.com/issues/?jql=project%20%3D%20LOGISTIC%20AND%20issuetype%20%3D%20BUG%20AND%20status%20in%20(%E6%9C%AA%E5%BC%80%E5%90%AF%2C%20REOPENED%2C%20%E5%A4%84%E7%90%86%E4%B8%AD)%20AND%20created%20%3E%3D%20-{}m%20ORDER%20BY%20" \
             "priority%20DESC%2C%20updated%20DESC"
# 测试群机器人链接
dsj_url_test = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
# 正式群机器人链接
dsj_url = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
# dsj_url = dsj_url_test
# 测试总群群机器人链接
dsj_url2 = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
# base jql语句
base_jql = "project = LOGISTIC AND issuetype = BUG AND status in (未开启, REOPENED, 处理中)"
# 具体时间(如:2020-09-09)的jql语句
jql = base_jql + " AND created >= {} ORDER BY priority DESC, updated DESC"
# 非具体时间(如:60分钟)的jql语句
jql1 = base_jql + " AND created >= -{}m ORDER BY priority DESC, updated DESC"
# 非具体时间(如:60分钟)的jql语句(紧急重要(P0P1)的bugs的jql语句)
jql2 = base_jql + " AND priority in (紧急, 重要) AND created >= -{}m ORDER BY priority DESC, updated DESC"
# 解决企业微信艾特具体人员时,艾特不到,对人员进行转换处理
people = {
    "zhangsan": "zahngsan",
    "lisi": "lisi"
}

outstansingbug.py中内容

#登录jira
import json

import requests
from jira import JIRA
from xpinyin import Pinyin

from config import *

def login(username='123', password='123'):
    """
    登录
    :return:
    """
    jira = JIRA(url, auth=(username, password))
    return jira
#因为jira上用户名可能是中文,所以要定义一个将转化成中文的函数
def china_to_py(text="中文"):
    """
    中文转拼音
    :return:str
    """
    p = Pinyin()
    result1 = p.get_pinyin(text)
    s = result1.split('-')
    result3 = ''.join(s[0:])
    return result3
def list_list(list1=[], list2=[]):
    """
    两个list相减,即两个list的差集
    :return: list
    """
    # v = list(set(list1).difference(set(list2)))
    # return v
    for i in list2:
        if i in list1:
            list1.remove(i)
    return list1


def _list_list(list1=[], list2=[]):
    """
    两个list相加,并去重
    :return: list
    """
    list_v = list1 + list2
    return list(set(list_v))
def solve_people(str_v):
    """
    解决企业微信艾特具体人员时,艾特不到,对人员进行转换处理
    :param str_v:字符串目标
    :return: list
    """
    for i, ii in people.items():
        str_v = str(str_v).replace(i, ii)
    return eval(str_v)
#处理复核条件的sql信息
def get_jql(get_time="2021-08-09", yxj=True):
    """
    获取符合条件的jql语句
    :param get_time: 时间参数,支持两种格式,一种是具体年月日,如:2021-09-09,一种是分钟数,如60
    :param yxj: bug优先级,默认为True,即优先级为全部,若False,则优先级为P0P1
    :return: jql语句,str格式
    """
    if len(str(get_time)) > 6:
        sql = jql.format(get_time)
    else:
        if yxj:
            sql = jql1.format(get_time)
        else:
            sql = jql2.format(get_time)
    return sql
#获取符合条件的bug列表

def search_projects_bugs(get_time="2021-08-09", yxj=True):
    """
    默认:2021-08-09至今,类型为bug,状态为:未开启, REOPENED, 修复中, 处理中的所有bug列表
    :return:bug列表(list)
    """
    try:
        v = login().search_issues(get_jql(get_time, yxj), maxResults=600)
    except:
        v = []
    return v
def get_bugs_creator(bug_key, name="china"):
    """
    获取bug对应的测试人员,即bug创建人,默认中文
    key:bug的key
    :return:str
    """
    issue = login().issue(bug_key)
    if name == "china":
        return str(issue.fields.creator)
    else:
        return china_to_py(str(issue.fields.creator))


def get_bugs_creators(bug_id_lists, name="china"):
    """
    根据bug的批量id列表,获取bug对应的测试人员列表,即bug创建人,默认中文
    :return:list
    """
    creators = []
    for i in bug_id_lists:
        creator = get_bugs_creator(i)
        creators.append(creator)
    if name == "china":
        return creators
    else:
        return eval(china_to_py(str(creators)))

#获取bug的开发人员
def get_bugs_developer(bug_key, name="china"):
    """
    获取bug对应的开发解决人,默认中文
    key:bug的key
    :return:
    """
    issue = login().issue(bug_key)
    # 以下代码为解决重名时,企业微信艾特人错误而定制
    if name == "china":
        developer = str(issue.fields.assignee)
        if developer == "张帅":
            if get_bugs_creator(bug_key) == "张璠" or get_bugs_creator(bug_key) == "赵晶":
                developer = "杭州_张帅"
            else:
                developer = "合肥_张帅"
        return developer
    else:
        developer = china_to_py(str(issue.fields.assignee))
        if developer == "zhangshuai":
            if get_bugs_creator(bug_key, name="py") == "zhangfan" or get_bugs_creator(bug_key, name="py") == "zhaojing":
                developer = "z_shuai"
            else:
                developer = "zhang_shuai"
        return developer
def search_projects_bugs(get_time="2021-08-09", yxj=True):
    """
    默认:2021-08-09至今,类型为bug,状态为:未开启, REOPENED, 修复中, 处理中的所有bug列表
    :return:bug列表(list)
    """
    try:
        v = login().search_issues(get_jql(get_time, yxj), maxResults=600)
    except:
        v = []
    return v

def get_project_bugs_creators(tp="china", get_time="2021-08-09", yxj=True):
    """
    2021-08-09至今,收集所有项目未日清bug的所有人,默认中文
    不允许重复,重复的已经过滤了
    :return: list
    """
    try:
        v = get_project_bugs_repeat_creators(tp, get_time, yxj)
        creator_v = list(set(v[0]))
    except:
        creator_v = []
    return creator_v
#获取项目未清bug的所有人默认中文
def get_project_bugs_repeat_creators(tp="china", get_time="2021-08-09", yxj=True):
    """
    2021-08-09至今,收集所有项目未日清bug的所有人,默认中文
    允许人员重复
    :return: tuple
    """
    bug_ids = []
    creators = []
    for i in search_projects_bugs(get_time, yxj):
        bug_ids.append(str(i))
    for i in bug_ids:
        if tp == "china":
            creators.append(get_bugs_developer(i))
        else:
            creators.append(get_bugs_developer(i, "py"))
    return creators, bug_ids
def split_list(l_1):
    """
    分割list列表,目标把拼音人名和手机号码分割成2个list列表
    :return: tuple
    """
    l_2 = []
    for i in l_1:
        if i.isdigit():
            l_1.remove(i)
            l_2.append(i)
    return l_1, l_2
def get_project_bugs_repeat_ceshi_people(tp="china", get_time="2021-08-09", yxj=True):
    """
    2021-08-09至今,收集所有项目未日清bug的测试人员,默认中文
    允许人员重复
    :return: tuple
    """
    bug_ids = []
    creators = []
    for i in search_projects_bugs(get_time, yxj):
        bug_ids.append(str(i))
    for i in bug_ids:
        if tp == "china":
            creators.append(get_bugs_creator(i))
        else:
            creators.append(get_bugs_creator(i, "py"))
    return creators, bug_ids

#针对POP1未清bug文案处理
def push_notice_p0p1(i, ii, n):
    """
    紧急,重要(P0,P1)的通知文本
    :param i:
    :param ii:
    :param n:
    :return:
    """
    if n == 6:
        minute = 60
    else:
        minute = 90
    title_1 = "二、紧急,重要(P0,P1)的bug:"
    text_1 = "1、今日下午5点至今,紧急,重要(P0,P1)的bug有 {} 位开发人员没有修复".format(i)
    text_11 = "1、今日下午5点至今,紧急,重要(P0,P1)的未日清(未修复)bug为0"
    t1 = ",请及时跟进:"
    t2 = ",点个赞👍"
    text_2 = ",".join(ii)
    text_3 = "2、具体bug请点击如下链接:"
    text_4 = url_minute.format(minute)
    if i == 0:
        _text = title_1 + "\n" + text_11 + t2
    else:
        _text = title_1 + "\n" + text_1 + t1 + text_2 + "\n" + text_3 + "\n" + text_4
    return _text

def push_notice_p0p1_statistics_to_tests_6_and_6_30(i):
    """
    下午6点及6:30统计:未日清bug (紧急,重要(P0,P1)) 的最终统计通知文本,发送给测试人员的,目的:需要测试人员进行跟进
    :param i:
    :return:
    """
    title_1 = "一、紧急,重要(P0,P1)的bug对应的测试owner:"
    text_1 = "1、今日下午17:00至今,共 {} 个紧急、重要(P0、p1)bug未日清(未修复)".format(i)
    text_11 = "今日下午17:00至今,紧急、重要(P0、p1)未日清(未修复)bug为0"
    t1 = ",其中需要如下测试owner进行跟进:"
    t2 = ",不需要测试人员跟进!"
    # text_2 = ",".join(ii)
    if i == 0:
        _text = title_1 + "\n" + text_11 + t2
    else:
        _text = title_1 + "\n" + text_1 + t1
    return _text
#发送给开发人员查看的文案
def push_notice_no_p0p1(i, ii, iii):
    """
    未日清bug的通知文本(2021-08-09至今上一个工作日5点前的未日清bug)
    :param i: 未日清的bug数量
    :param ii: 未日清的bug 对应的开发人员数量(已去重)
    :param iii: 对应开发人员列表()已去重
    :return:
    """
    title_1 = "一、未日清的所有bug:"
    # text_1 = "1、截止到目前,未日清的bug有 {} 位开发人员没有修复,请及时跟进:".format(i)
    text_1 = "1、截止到目前(2021-08-09至今),未日清的bug有 {} 个没有修复,涉及 {} 位开发人员,请及时跟进:".format(i, ii)
    text_2 = ",".join(iii)
    text_3 = "2、具体bug请点击如下链接:"
    text_4 = url_data_time
    _text = title_1 + "\n" + text_1 + text_2 + "\n" + text_3 + "\n" + text_4
    return _text
#发送给测试人员跟进的文案
def _push_notice_no_p0p1_statistics_to_tests(i, ii):
    """
    9点钟统计:未日清bug的最终统计通知文本(2021-08-09至今上一个工作日5点前的未日清bug)发送给测试人员的,目的:需要测试人员进行跟进
    :param i:
    :return:
    """
    title_1 = "二、未日清的所有bug对应的测试owner:"
    # 下面注释的是第二天9点的文本
    # text_1 = "1、2021-08-09至昨天(上个工作日,周{})下午17点前:共 {} 个bug未日清(未修复),其中需要如下测试owner进行跟进:". \
    #     format(get_yesterday_weekday(), i)
    # 下面这个是2021-08-09至今的文本
    text_1 = "1、截止到目前(2021-08-09至今),未日清的bug有 {} 个没有修复,涉及 {} 位测试owner,请及时push对应开发GG进行修复:". \
        format(i, ii)
    _text = title_1 + "\n" + text_1
    return _text
def send_projects_xx(send_message, creators_lists, mobile_lists, to_url=dsj_url_test):
    """
    默认发送测试群机器人
    :param send_message:
    :return:
    """
    data = json.dumps({
        "msgtype": "text",
        "text": {
            "content": send_message,  # 发送的消息内容
            "mentioned_list": creators_lists,  # 圈出所有人
            "mentioned_mobile_list": mobile_lists  # 手机号
        }
    })

    # 指定机器人发送消息
    requests.post(to_url, data, auth=('Content-Type', 'application/json'))
def get_today_5dian_to_n_dian_creator(n=6, tp="china"):
    """
    获取今天下午5点至今的未修复bug(P0P1)对应开发人员列表
    :return:tuple
    """
    if n == 6:
        minute = 60
    else:
        minute = 90
    creator_china = get_project_bugs_creators(tp, minute, False)
    creator_py = eval(china_to_py(str(creator_china)))
    creator_py = solve_people(creator_py)
    return creator_china, creator_py
def get_today_5dian_to_n_dian_repeat_creator_and_bug_ids(n=6, tp="china"):
    """
    获取今天下午5点至今的未修复bug(P0P1)对应测试人员列表及bug_id列表
    :return:tuple
    """
    if n == 6:
        minute = 60
    else:
        minute = 90
    creator_china, bug_ids = get_project_bugs_repeat_ceshi_people(tp, minute, False)
    creator_py = eval(china_to_py(str(creator_china)))
    creator_py = solve_people(creator_py)
    return creator_china, creator_py, bug_ids

#执行未清bug的脚本



def run(n=5):
    # creator_china, creator_py = get_2021_08_09_to_now_creator()
    get_2021_08_09_to_now_developer_and_bug_ids = get_project_bugs_repeat_creators()   #获取从2021-08-09到今天所有bug的id跟开发人员
    developer_repeat_china = get_2021_08_09_to_now_developer_and_bug_ids[0]  #获取从2021-08-09到今天所有bug的开发人员
    # 过滤重复的中文姓名
    developer_china = list(set(developer_repeat_china))   #set(developer_repeat_china)将得到的开发人员中的重复元素给去掉
    developer_py = eval(china_to_py(str(developer_china))) #china_to_py(str(developer_china)将对应的中文转换成拼音的函数得到拼音结果
    developer_py = solve_people(developer_py)#solve_people(developer_py)对开发人员进行处理防止出现企业微信艾特不到的情况

    list_bug_id = get_2021_08_09_to_now_developer_and_bug_ids[1]   #获取从2021-08-08到今天所有的bug的id
    list_len = len(list_bug_id)    #获取所有未清bug的数量
    get_bugs_creators_china_repeat = get_bugs_creators(list_bug_id)  #get_bugs_creators(list_bug_id)根据bug的批量id列表,获取bug对应的测试人员列表,即bug创建人,默认中文
    get_bugs_creators_china = list(set(get_bugs_creators_china_repeat)) #将bug对应的测试人员的重复数据给清楚掉
    get_bugs_creators_py_repeat = eval(china_to_py(str(get_bugs_creators_china_repeat))) #将bug对应的测试人员从中文转换成拼音
    get_bugs_creators_py = list(set(get_bugs_creators_py_repeat))#将对应的bug对应的测试人员转换成列表
    #对企业微信中测试人员的bug进行提醒的文案
    text_to_test_1 = ""
    for i in get_bugs_creators_china:
        text_to_test_1 += "{}:{} 个".format(i, get_bugs_creators_china_repeat.count(i)) + "\n"
    text_to_test_2 = "2、具体bug请点击如下链接:" + "\n" + url_tests
    text_to_test_p0p1 = "2、具体bug请点击如下链接:" + "\n" + url_tests_p0_p1
    text_to_test_11 = _push_notice_no_p0p1_statistics_to_tests(list_len, len(
        get_bugs_creators_china)) + "\n" + text_to_test_1 + text_to_test_2
    # 处理测试人员姓名的拼音,防止企业微信艾特不到
    get_bugs_creators_py = solve_people(get_bugs_creators_py)
    l_11, l_22 = split_list(get_bugs_creators_py)

    if developer_china == []:
        text = "构建失败,原因:人员列表为空,即登录失败!"
        print(text)
        send_projects_xx(text, ["zhuyixun"], [""], dsj_url_test)
    else:
        nnn = len(search_projects_bugs())
        push_notice_text_5dian = push_notice_no_p0p1(nnn, len(developer_china), developer_china)
        if n == 5:
            print("5点前的人员developer_py:", developer_py)
            l_1, l_2 = split_list(developer_py)
            send_projects_xx(push_notice_text_5dian, l_1, l_2, dsj_url)
            # 以下是发送给测试人员的
            print("5diande", l_11, l_22)
            send_projects_xx(text_to_test_11, l_11, l_22, dsj_url2)
        else:
            creator_china1, creator_py1 = get_today_5dian_to_n_dian_creator(n)
            _push_notice_text_n_dian = push_notice_p0p1(len(creator_china1), creator_china1, n)
            push_notice_text_n_dian = push_notice_text_5dian + "\n" + _push_notice_text_n_dian
            total_creator = _list_list(creator_py1, developer_py)
            print("5点前的人员:", developer_py)
            print("5点后到现在的P0P1人员:", creator_py1)
            print("total_creator", total_creator)
            l_1, l_2 = split_list(total_creator)
            send_projects_xx(push_notice_text_n_dian, l_1, l_2, dsj_url)
            # 以下是发送给测试人员的# 处理测试人员姓名的拼音,防止企业微信艾特不到
            p0p1creators_china_repeat, p0p1creators_py_repeat, p0p1bug_ids = get_today_5dian_to_n_dian_repeat_creator_and_bug_ids(
                n)
            p0p1creators_china = list(set(p0p1creators_china_repeat))
            p0p1creators_py = list(set(p0p1creators_py_repeat))
            _text_to_test = ""
            for i in p0p1creators_china:
                _text_to_test += "{}:{} 个".format(i, p0p1creators_china_repeat.count(i)) + "\n"

            # 优先级为P0P1的通知
            if len(p0p1bug_ids) == 0:
                text_to_test = push_notice_p0p1_statistics_to_tests_6_and_6_30(len(p0p1bug_ids)) + "\n" + _text_to_test
            else:
                text_to_test = push_notice_p0p1_statistics_to_tests_6_and_6_30(
                    len(p0p1bug_ids)) + "\n" + _text_to_test + text_to_test_p0p1
            # 以下是发送给测试人员的# 处理测试人员姓名的拼音,防止企业微信艾特不到
            get_bugs_creators_py = solve_people(p0p1creators_py)
            l_1, l_2 = split_list(get_bugs_creators_py)
            print("6diandep0p1", l_1, l_2)
            send_projects_xx(text_to_test, l_1, l_2, dsj_url2)
            # 2021-08-09至现在的通知
            print("6diande", l_11, l_22)
            send_projects_xx(text_to_test_11, l_11, l_22, dsj_url2)
if __name__ == '__main__':
    res=login()
    print(res)

run_6_30.py中内容

import sys
sys.path.append('../')
import outstandingbug





def run():
    try:
        outstandingbug.run(6_30)
    except:
        outstandingbug.send_projects_xx("6点30分构建脚本异常", ["xxxx"], [""])


if __name__ == '__main__':
    run()

3. 运行脚本以后对应的测试群里的通知如下:

4.对应的项目群通知如下:

5. 可以将此脚本跟jenkins进行配置实现定时调度

  • 9
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值