Several minor changes

This commit is contained in:
Zimmerberger Markus
2022-07-13 08:06:31 +02:00
parent e03f3aae52
commit 55b4fc9fd8
3 changed files with 230 additions and 43 deletions
+59 -43
View File
@@ -10,9 +10,12 @@ import logging
def get_assignee(type): def get_assignee(type):
if type == 'Dev Backend': if type == 'Dev Backend':
return 'rab9001' #return 'rab9001'
elif type == 'Dev Frontend':
return 'reu9001' return 'reu9001'
elif type == 'Dev Frontend':
# consider verwaltungsfrontend or bürgerfrontend
return 'thh9001'
# return 'reu9001'
elif type[:14] == 'Test-Anpassung': elif type[:14] == 'Test-Anpassung':
return 'ada9001' return 'ada9001'
@@ -24,16 +27,21 @@ def create_subtask(issue, parent, type, subtask_sp):
if len(subtask) == 0: if len(subtask) == 0:
#right = (comment_line.find(':')+2)-len(comment_line) #right = (comment_line.find(':')+2)-len(comment_line)
#subtask_sp = float(comment_line[right:]) #subtask_sp = float(comment_line[right:])
# issuetype of testcase-creation/modification should be 'Test'
# if type == 'Test-Anpassung':
issue_type = 'Sub-task'
assignee = get_assignee(type) assignee = get_assignee(type)
issue_dict = { issue_dict = {
'project': {'id': 12501}, 'project': {'id': 12501},
'summary': "[{}] {}".format(type, escaped), 'summary': "[{}] {}".format(type, escaped),
'description': issue.fields.description, 'description': issue.fields.description,
'issuetype': {'name': 'Sub-task'}, 'issuetype': {'name': issue_type},
'priority': {'name': issue.fields.priority.name},
'parent': {'key': parent}, 'parent': {'key': parent},
# todo - json 'labels': issue.fields.labels,
#'components': [{'name': issue.fields.components}], #'customfield_10022' - Story Points
#'labels': [{'name': issue.fields.labels}],
'timetracking': {'originalEstimate': "{}d".format(subtask_sp)}, 'timetracking': {'originalEstimate': "{}d".format(subtask_sp)},
'assignee': {'name': assignee} 'assignee': {'name': assignee}
} }
@@ -44,6 +52,7 @@ def create_subtask(issue, parent, type, subtask_sp):
for component in issue.fields.components: for component in issue.fields.components:
existingComponents.append({"name" : component.name}) existingComponents.append({"name" : component.name})
new_issue.update(fields={"components": existingComponents}) new_issue.update(fields={"components": existingComponents})
#new_issue.update(priority={"name": issue.fields.priority.name})
logging.info('Created Sub-Task {}'.format(new_issue)) logging.info('Created Sub-Task {}'.format(new_issue))
else: else:
@@ -57,15 +66,18 @@ logging.basicConfig(filename='sub_task_generator.log',
host = "https://jira.wien.gv.at/" host = "https://jira.wien.gv.at/"
pat = "OTAyMTM3MjY0MjE0Ovz6bu0ti1TlEdSegmmiWiJ2wGeD" pat = "OTAyMTM3MjY0MjE0Ovz6bu0ti1TlEdSegmmiWiJ2wGeD"
sprint = 46
headers = JIRA.DEFAULT_OPTIONS["headers"].copy() headers = JIRA.DEFAULT_OPTIONS["headers"].copy()
headers["Authorization"] = f"Bearer {pat}" headers["Authorization"] = f"Bearer {pat}"
jira_server = JIRA(server=host, options={"headers": headers}) jira_server = JIRA(server=host, options={"headers": headers})
#issues_Jql = jira_server.search_issues('filter=19527') #, expand='changelog') # use filter or single issue
issues_Jql = jira_server.search_issues('labels in (Refinement11012022) AND type not in (Bug) AND status not in (Done) and ("Story Points" is EMPTY or "Story Points" = 0)') #, expand='changelog') issues_Jql = jira_server.search_issues('filter=20406') #, expand='changelog')
#issues_Jql = jira_server.search_issues('key in (WRGWR-1558)') #, expand='changelog')
#issues_Jql = jira_server.search_issues('labels in (Refinement11012022) AND type not in (Bug) AND status not in (Done) and ("Story Points" is EMPTY or "Story Points" = 0)') #, expand='changelog')
logging.info('Creating sub-tasks out of estimation of pre-planning sprint {}'.format(38)) logging.info('Creating sub-tasks out of estimation of pre-planning sprint {}'.format(sprint))
xsp = lambda s: s or 0 xsp = lambda s: s or 0
issue: Issue issue: Issue
@@ -73,47 +85,51 @@ for issue in issues_Jql:
logging.info('Working on {}'.format(issue)) logging.info('Working on {}'.format(issue))
sp_sum = 0 sp_sum = 0
# sp = 0 # only Issues with empty (or 0) story-points
# if hasattr(issue.fields, 'customfield_10022'): sp = 0
# sp = xsp(issue.fields.customfield_10022) if hasattr(issue.fields, 'customfield_10022'):
# sp_sum += sp sp = xsp(issue.fields.customfield_10022)
single_issue = jira_server.issue(issue.key) if sp != 0:
comments = single_issue.fields.comment.comments logging.info('Ignoring issue {} as there are Story-Points already omitted'.format(issue))
else:
single_issue = jira_server.issue(issue.key)
comments = single_issue.fields.comment.comments
# Find all comments made by me on this issue. # Find all comments made by me on this issue.
for comment in comments: for comment in comments:
comment_lines = comment.body.splitlines() comment_lines = comment.body.splitlines()
if len(comment_lines) == 5: if len(comment_lines) == 5:
for comment_line in comment_lines: if comment_lines[0][:5] == "Dev B":
if comment_line != "": for comment_line in comment_lines:
# pos = comment_lines[2].find('NN') if comment_line != "":
comment_line_parts = comment_line.split(':') # pos = comment_lines[2].find('NN')
comment_line_parts = comment_line.split(':')
# if 1. Test* != NN create a sub-task (if not existing) # if 1. Test* != NN create a sub-task (if not existing)
if len(comment_line_parts) == 2: if len(comment_line_parts) == 2:
if comment_line_parts[1] != u'\xa0': # empty string if comment_line_parts[1] != u'\xa0': # empty string
if comment_line_parts[1][-2:] != 'NN': # NN means NotNecessary if comment_line_parts[1][-2:] != 'NN': # NN means NotNecessary
subtask_ph = float(comment_line_parts[1]) * 0.5 subtask_ph = float(comment_line_parts[1]) * 0.5
if comment_line_parts[0][:15] != "Test-Ausführung": if comment_line_parts[0][:15] != "Test-Ausführung":
create_subtask(issue, create_subtask(issue,
issue.key, issue.key,
comment_line_parts[0], comment_line_parts[0],
subtask_ph) subtask_ph)
sp_sum += subtask_ph / 0.5 sp_sum += subtask_ph / 0.5
# find corresponding sub-task # find corresponding sub-task
# issuelinks.inwardIssue # issuelinks.inwardIssue
try: try:
issue.update(fields={'customfield_10022': sp_sum}) issue.update(fields={'customfield_10022': sp_sum})
logging.info("Estimated story-points changed to Sum(Sub-Tasks story-points): {}".format(sp_sum, sp_sum)) logging.info("Estimated story-points changed to Sum(Sub-Tasks story-points): {}".format(sp_sum, sp_sum))
except exceptions.JIRAError: except exceptions.JIRAError:
logging.error("Issue {} has no (visible) Story Points-attribute".format(issue.key)) logging.error("Issue {} has no (visible) Story Points-attribute".format(issue.key))
finally: finally:
logging.info('Done {}'.format(issue.key)) logging.info('Done {}'.format(issue.key))
#print('{}: {}, SP: {}'.format(issue.key, issue.fields.summary, sp)) #print('{}: {}, SP: {}'.format(issue.key, issue.fields.summary, sp))
+73
View File
@@ -0,0 +1,73 @@
# find all subtasks of a story and keep description in sync
# zisco 2022-05-03 07:25
from tkinter.tix import INTEGER
from tokenize import Number
from types import ClassMethodDescriptorType
from jira import JIRA, Issue, Comment, exceptions
import re
import csv
import xlsxwriter
import logging
import pymsteams
import asyncio
import os
# set https_proxy
os.environ['https_proxy'] = "http://uaproxy.wien.gv.at:3128"
logging.basicConfig(filename='sub_task_generator.log',
filemode='a',
format='%(asctime)s - %(levelname)s: %(message)s',
level=logging.INFO,
encoding='utf-8')
host = "https://jira.wien.gv.at/"
pat = "OTAyMTM3MjY0MjE0Ovz6bu0ti1TlEdSegmmiWiJ2wGeD"
headers = JIRA.DEFAULT_OPTIONS["headers"].copy()
headers["Authorization"] = f"Bearer {pat}"
jira_server = JIRA(server=host, options={"headers": headers})
# use filter or single issue
issues_Jql = jira_server.search_issues('filter=20266') #, expand='changelog')
#issues_Jql = jira_server.search_issues('key in (WRGWR-905)') #, expand='changelog')
#issues_Jql = jira_server.search_issues('labels in (Refinement11012022) AND type not in (Bug) AND status not in (Done) and ("Story Points" is EMPTY or "Story Points" = 0)') #, expand='changelog')
logging.info('Actualize story-state out of sub-task state')
issue: Issue
parent_issue: Issue
stateListSubTask = ['Done','Closed']
stateListStory = ['Ready for Testing', 'Test', 'In Review', 'Done', 'Reopened']
for issue in issues_Jql:
logging.info('Working on {}'.format(issue))
# get all subtasks
allSubTasksDone = True
for subtask in issue.fields.subtasks:
if (subtask.fields.status.name not in stateListSubTask) and (allSubTasksDone):
# issue.update(notify=False, description=parent_issue.fields.description)
# logging.info('Updated sub-task description with story description')
allSubTasksDone = False
break
# send info to teams as well
# TODO
if allSubTasksDone and (issue.fields.status.name not in stateListStory):
logging.info('Story {} is in wrong state'.format(issue.key))
loop = asyncio.get_event_loop()
# the async_connectorcard object is used instead of the normal one.
myTeamsMessage = pymsteams.async_connectorcard("https://atos365.webhook.office.com/webhookb2/f107169d-26b9-46ff-a973-b7aa1f37e552@33440fc6-b7c7-412c-bb73-0e70b0198d5a/IncomingWebhook/6cf64f8f6f1b40e198c1a981921afed1/181686a4-0d13-4990-a87a-e4814c1abc55")
myTeamsMessage.title("JIRA Sub-Task Syncer")
myTeamsMessage.text('Story {} is in wrong state'.format(issue.key))
myTeamsMessage.color("#F9EC26")
# to send the message, pass to the event loop
loop.run_until_complete(myTeamsMessage.send())
+98
View File
@@ -0,0 +1,98 @@
# find all subtasks of a story and keep description in sync
# zisco 2022-05-03 07:25
from tkinter.tix import INTEGER
from tokenize import Number
from types import ClassMethodDescriptorType
from jira import JIRA, Issue, Comment, exceptions
import re
import csv
import xlsxwriter
import logging
import pymsteams
import asyncio
import os
def update_subtask(issue, parent):
issue_dict = {
'project': {'id': 12501},
'summary': "[{}] {}".format(type, escaped),
'description': issue.fields.description,
'issuetype': {'name': issue_type},
'priority': {'name': issue.fields.priority.name},
'parent': {'key': parent},
'labels': issue.fields.labels,
#'customfield_10022' - Story Points
'timetracking': {'originalEstimate': "{}d".format(subtask_sp)},
'assignee': {'name': assignee}
}
new_issue = jira_server.create_issue(fields=issue_dict)
# consider components
existingComponents = []
for component in issue.fields.components:
existingComponents.append({"name" : component.name})
new_issue.update(fields={"components": existingComponents})
#new_issue.update(priority={"name": issue.fields.priority.name})
logging.info('Created Sub-Task {}'.format(new_issue))
# set https_proxy
os.environ['https_proxy'] = "http://uaproxy.wien.gv.at:3128"
logging.basicConfig(filename='sub_task_generator.log',
filemode='a',
format='%(asctime)s - %(levelname)s: %(message)s',
level=logging.INFO,
encoding='utf-8')
host = "https://jira.wien.gv.at/"
pat = "OTAyMTM3MjY0MjE0Ovz6bu0ti1TlEdSegmmiWiJ2wGeD"
headers = JIRA.DEFAULT_OPTIONS["headers"].copy()
headers["Authorization"] = f"Bearer {pat}"
jira_server = JIRA(server=host, options={"headers": headers})
# use filter or single issue
issues_Jql = jira_server.search_issues('filter=20262') #, expand='changelog')
#issues_Jql = jira_server.search_issues('key in (WRGWR-905)') #, expand='changelog')
#issues_Jql = jira_server.search_issues('labels in (Refinement11012022) AND type not in (Bug) AND status not in (Done) and ("Story Points" is EMPTY or "Story Points" = 0)') #, expand='changelog')
logging.info('Keep sub-task description in sync with story description')
issue: Issue
parent_issue: Issue
chng=0
for issue in issues_Jql:
logging.info('Working on {}'.format(issue))
# get parent-issue
parent = issue.fields.parent
parent_issue = jira_server.issue(parent.key)
if parent_issue.fields.description != issue.fields.description:
issue.update(notify=False, description=parent_issue.fields.description)
logging.info('Updated sub-task description with story description')
chng += 1
# send info to teams as well
# TODO
# no changes detected
# You must create the connectorcard object with the Microsoft Webhook URL
if chng == 0:
loop = asyncio.get_event_loop()
# the async_connectorcard object is used instead of the normal one.
myTeamsMessage = pymsteams.async_connectorcard("https://atos365.webhook.office.com/webhookb2/f107169d-26b9-46ff-a973-b7aa1f37e552@33440fc6-b7c7-412c-bb73-0e70b0198d5a/IncomingWebhook/6cf64f8f6f1b40e198c1a981921afed1/181686a4-0d13-4990-a87a-e4814c1abc55")
myTeamsMessage.title("JIRA Sub-Task Syncer")
myTeamsMessage.text("No changes in description detected")
myTeamsMessage.color("#F9EC26")
myTeamsMessage.printme()
# to send the message, pass to the event loop
loop.run_until_complete(myTeamsMessage.send())