Several minor changes
This commit is contained in:
+29
-13
@@ -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,11 +85,14 @@ 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)
|
||||||
|
|
||||||
|
if sp != 0:
|
||||||
|
logging.info('Ignoring issue {} as there are Story-Points already omitted'.format(issue))
|
||||||
|
else:
|
||||||
single_issue = jira_server.issue(issue.key)
|
single_issue = jira_server.issue(issue.key)
|
||||||
comments = single_issue.fields.comment.comments
|
comments = single_issue.fields.comment.comments
|
||||||
|
|
||||||
@@ -86,6 +101,7 @@ for issue in issues_Jql:
|
|||||||
comment_lines = comment.body.splitlines()
|
comment_lines = comment.body.splitlines()
|
||||||
|
|
||||||
if len(comment_lines) == 5:
|
if len(comment_lines) == 5:
|
||||||
|
if comment_lines[0][:5] == "Dev B":
|
||||||
for comment_line in comment_lines:
|
for comment_line in comment_lines:
|
||||||
if comment_line != "":
|
if comment_line != "":
|
||||||
# pos = comment_lines[2].find('NN')
|
# pos = comment_lines[2].find('NN')
|
||||||
|
|||||||
@@ -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())
|
||||||
@@ -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())
|
||||||
Reference in New Issue
Block a user