如何在JIRA中批量删除评论?

如何在JIRA中批量删除评论?,jira,jira-rest-api,Jira,Jira Rest Api,我们有几个JIRA问题,其中有1000多条重复的、伪造的、类似垃圾邮件的评论。如何快速删除它们 背景: 我们在active directory(Exchange)中禁用了一个用户,但没有禁用JIRA,因此JIRA一直试图通过电子邮件向他们发送更新。电子邮件服务器发出了一条回退消息,JIRA尽职尽责地将其记录到任务中,这导致它发送另一个更新,并产生了一个反馈循环 这些消息具有以下格式: Delivery has failed to these recipients or groups: mail@

我们有几个JIRA问题,其中有1000多条重复的、伪造的、类似垃圾邮件的评论。如何快速删除它们

背景:

我们在active directory(Exchange)中禁用了一个用户,但没有禁用JIRA,因此JIRA一直试图通过电子邮件向他们发送更新。电子邮件服务器发出了一条回退消息,JIRA尽职尽责地将其记录到任务中,这导致它发送另一个更新,并产生了一个反馈循环

这些消息具有以下格式:

Delivery has failed to these recipients or groups:
mail@example.com<mail@example.com>
The e-mail address you entered couldn't be found. Please check the recipient's e-mail address and try to resend the message. If the problem continues, please contact your helpdesk.
Diagnostic information for administrators:
Generating server: emailserver.example.com
user@example.com
#550 5.1.1 RESOLVER.ADR.RecipNotFound; not found ##
Original message headers:
Received: from jiraserver.example.com (10.0.0.999) by emailserver.example.com (10.0.0.999)
with Microsoft SMTP Server id nn.n.nnn.n; Mon, 13 Jun 2016 15:57:04 -0500
Date: Mon, 13 Jun 2016 15:57:03 -0500
向以下收件人或组传递失败:
mail@example.com
找不到您输入的电子邮件地址。请检查收件人的电子邮件地址并尝试重新发送邮件。如果问题仍然存在,请联系您的帮助台。
管理员的诊断信息:
生成服务器:emailserver.example.com
user@example.com
#550 5.1.1分解器ADR.RecipNotFound;找不到##
原始邮件标题:
接收:通过emailserver.example.com(10.0.0.999)从jiraserver.example.com(10.0.0.999)接收
使用Microsoft SMTP服务器id nn.n.nnn.n;2016年6月13日星期一15:57:04-0500
日期:2016年6月13日星期一15:57:03-0500
没有发现一种不使用购买的插件的简单方法,例如“入侵”数据库,这是我们想要避免的

注:

我们提出了一个解决方案,并在这里发布以供分享。

通过Chrome JavaScript控制台使用

背景:

我们不想为我们希望的孤立事件编写完整的应用程序。我们最初计划使用PowerShell的。然而,认证被证明是一个挑战。API支持,尽管它是唯一的,但我们没有在内部服务器上使用它。此外,我们最初的测试导致了401个错误(可能是由于一个bug)

但是,API还支持基于cookie的身份验证,因此只要您从具有有效JIRA会话的浏览器生成请求,它就可以正常工作。我们选择了这种方法

解决方案详细信息:

首先,查找并查看相关评论和问题ID:

SELECT * FROM jira..jiraaction WHERE actiontype = 'comment' AND actionbody LIKE '%RESOLVER.ADR.RecipNotFound%';
根据JIRA数据的大小,这可能是一个缓慢的查询。它似乎在
issueid
上编制了索引,因此如果您知道,请指定它。另外,向该查询添加其他条件,使其仅表示要删除的注释

下面的解决方案是针对单个问题的注释编写的,但是通过一些额外的JavaScript可以扩展以支持多个问题

我们需要在Chrome JavaScript控制台中使用的注释ID列表。一种有用的格式是逗号分隔的字符串列表,可以按如下方式创建:

SELECT '"' + CONVERT(VARCHAR(50),ID) + '", ' FROM jira..jiraaction WHERE actiontype = 'comment' AND actionbody LIKE '%RESOLVER.ADR.RecipNotFound%' AND issueid = @issueid FOR XML PATH('')
(这不一定是解决此问题的最佳方法,但它很简单,并可用于此目的。)

现在,打开一个新的浏览器会话并对您的JIRA实例进行身份验证。我们使用了Chrome,但任何带有JavaScript控制台的浏览器都应该这样做

获取该查询生成的字符串,并将其放入JavaScript控制台中的语句中,如下所示:

CommentIDs = [StringFromSQL];
CommentIDs = ["1234", "2345"];
您将需要手动修剪尾随逗号(或调整上述查询以完成此操作)。它将如下所示:

CommentIDs = [StringFromSQL];
CommentIDs = ["1234", "2345"];
运行该命令时,您将创建一个包含所有注释ID的JavaScript数组

现在我们来看看这项技术的要点。我们将循环该数组的内容,并使用XMLHttpRequest(通常缩写为XHR)对RESTAPI进行新的AJAX调用。(还有一个例子。)

您必须用相关的问题ID替换“11111”。您可以对多个问题ID重复此操作,也可以构建多维数组和fancier循环

这不雅观。它没有任何错误处理,但您可以使用Chrome JavaScript API监控进度


我会使用jira python脚本或ScriptRunner groovy脚本。即使是一次性批量更新,因为它更容易测试,并且不需要数据库访问


很高兴它对你有用

我创建了一个python脚本来删除特定Jira问题的所有注释。 它使用来自Jira的API

'''
This script removes all comments from a specified jira issue

Please provide Jira-Issue-Key/Id, Jira-URL, Username, PAssword in the variables below.
'''

import sys
import json
import requests
import urllib3

# Jira Issue Key or Id where comments are deleted from
JIRA_ISSUE_KEY = 'TST-123'

# URL to Jira
URL_JIRA = 'https://jira.contoso.com'

# Username with enough rights to delete comments
JIRA_USERNAME = 'admin'
# Password to Jira User
JIRA_PASSWORD = 'S9ev6ZpQ4sy2VFH2_bjKKQAYRUlDfW7ujNnrIq9Lbn5w'

''' ----- ----- Do not change anything below ----- ----- '''

# Ignore SSL problem (certificate) - self signed
urllib3.disable_warnings()

# get issue comments:
# https://developer.atlassian.com/cloud/jira/platform/rest/#api-api-2-issue-issueIdOrKey-comment-get
URL_GET_COMMENT = '{0}/rest/api/latest/issue/{1}/comment'.format(URL_JIRA, JIRA_ISSUE_KEY)

# delete issue comment:
# https://developer.atlassian.com/cloud/jira/platform/rest/#api-api-2-issue-issueIdOrKey-comment-id-delete
URL_DELETE_COMMENT = '{0}/rest/api/2/issue/{1}/comment/{2}'

def user_yesno():
    ''' Asks user for input yes or no, responds with boolean '''
    allowed_response_yes = {'yes', 'y'}
    allowed_response_no = {'no', 'n'}

    user_response = input().lower()
    if user_response in allowed_response_yes:
        return True
    elif user_response in allowed_response_no:
        return False
    else:
        sys.stdout.write("Please respond with 'yes' or 'no'")
        return False

# get jira comments
RESPONSE = requests.get(URL_GET_COMMENT, verify=False, auth=(JIRA_USERNAME, JIRA_PASSWORD))

# check if http response is OK (200)
if RESPONSE.status_code != 200:
    print('Exit-101: Could not connect to api [HTTP-Error: {0}]'.format(RESPONSE.status_code))
    sys.exit(101)

# parse response to json
JSON_RESPONSE = json.loads(RESPONSE.text)

# get user confirmation to delete all comments for issue
print('You want to delete {0} comments for issue {1}? (yes/no)' \
    .format(len(JSON_RESPONSE['comments']), JIRA_ISSUE_KEY))
if user_yesno():
    for jira_comment in JSON_RESPONSE['comments']:
        print('Deleting Jira comment {0}'.format(jira_comment['id']))

        # send delete request
        RESPONSE = requests.delete(
            URL_DELETE_COMMENT.format(URL_JIRA, JIRA_ISSUE_KEY, jira_comment['id']),
            verify=False, auth=(JIRA_USERNAME, JIRA_PASSWORD))

        # check if http response is No Content (204)
        if RESPONSE.status_code != 204:
            print('Exit-102: Could not connect to api [HTTP-Error: {0}; {1}]' \
            .format(RESPONSE.status_code, RESPONSE.text))
            sys.exit(102)

else:
    print('User abort script...')
源代码管理: