Several enhancements

This commit is contained in:
Zimmerberger Markus
2025-06-05 10:57:12 +02:00
parent e4c03dad6b
commit f8cdc8deda
2 changed files with 133 additions and 38 deletions
+69
View File
@@ -0,0 +1,69 @@
# find comments with estimations out of pre-planning
# zisco 2021-09-30 19:50
# TODO: Consider later created sub-tasks
from multiprocessing.sharedctypes import Value
from types import ClassMethodDescriptorType
from jira import JIRA, Issue, Comment, exceptions
import re
import csv
import xlsxwriter
import logging
import yaml
from bisect import bisect_left
from datetime import date
logging.basicConfig(filename='sub_task_generator.log',
filemode='a',
format='%(asctime)s - %(levelname)s: %(message)s',
level=logging.INFO,
encoding='utf-8')
with open("config.yaml", encoding='utf8') as f:
cfg = yaml.load(f, Loader=yaml.FullLoader)
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=31528') #, expand='changelog')
logging.info(f"Modify 'DoD SA' sub-tasks with link to Dev sub-tasks")
issue: Issue
for issue in issues_Jql:
logging.info('Working on {}'.format(issue))
# else:
# single_issue = jira_server.issue(issue.key)
# find corresponding Dev sub-tasks
#escaped = issue.fields.summary.replace('"', r'\"')
#escaped = escaped.replace('[DoD SA]', '').strip()
escaped = issue.fields.summary.replace('[DoD SA]', '').strip()
logging.info(f'summary ~ \"{escaped}\"')
description = issue.fields.description
links_section = '\r\n||Dev-Links||Typ||'
position = description.find(links_section)
if position != -1:
# clear list
description = description[:position + len(links_section)].strip()
else:
description += links_section
for type in ['Backend','Frontend']:
subtask = jira_server.search_issues(f'summary ~ \"Dev {type} {escaped}\"')
if subtask:
# adapt DoD SA-desc
description += "\r\n|" + subtask[0].key + f'|{type}|'
try:
issue.update(fields={'description': description})
except Exception as e:
logging.info(e)
logging.info(f'Link to {type} for {issue} created')
+51 -25
View File
@@ -32,41 +32,53 @@ def take_closest(myList, myNumber):
def get_assignee(type, issue):
# isBuergerfrontend = False
if (type == 'Dev Backend' or type.startswith('Dev Unit') or type == 'DoD SA/DEV'):
if (type == 'Dev Backend' or type.startswith('Dev Unit')):
# use assignee of story
return 'rab9001'
return cfg['def_assignees']['backend'] #'rab9001'
#return issue.fields.assignee.name
elif type == 'Dev Frontend':
# for component in issue.fields.components:
# isBuergerfrontend = component.name == "Bürgerfrontend"
# if isBuergerfrontend:
return 'thh9001'
return cfg['def_assignees']['frontend'] #'thh9001'
elif type == 'Dev Citizen-Frontend':
return 'reu9001'
return cfg['def_assignees']['cit_frontend'] #'reu9001'
elif type.startswith('Test-Anpassung') or type == 'DoD Test':
if issue.key.startswith('WRGWR-'):
return 'ada9001'
return cfg['def_assignees']['wgwr_test'] #'ada9001'
elif issue.key.startswith('BAUWB-'):
return cfg['def_assignees']['bauwb_test'] #'osm9005'
elif issue.key.startswith('DKARB-'):
return cfg['def_assignees']['far_test'] #'osm9005'
else:
return 'osm9005'
return cfg['def_assignees']['default'] #'zim9003'
elif type == 'DoD PO':
return 'kom9010'
return cfg['def_assignees']['po'] #'kom9010'
elif type == 'DoD SA':
return cfg['def_assignees']['sa'] #'krp9002'
def create_subtask(issue, parent, type, subtask_sp=0, estimation_remark="", no_unit_test=False):
escaped = issue.fields.summary.replace('"', r'\"')
logging.info(f'summary ~ \"{escaped}\"')
assignee = get_assignee(type, issue)
description = get_description(type)
description = get_description(type, no_unit_test=no_unit_test)
try:
subtask = jira_server.search_issues(f'summary ~ \"{type} {escaped}\"')
project = parent.split('-')[0]
subtask = jira_server.search_issues(f'summary ~ \"{type} {escaped}\" AND project = {project}') # add the project
if subtask:
single_issue = jira_server.issue(subtask[0].key)
if single_issue.fields.summary == f'[{type}] {escaped}':
raise exceptions.JIRAError
except exceptions.JIRAError:
# correct estimation
#subtask.fields('timetracking': {'originalEstimate'}).Value() = subtask_sp
single_issue = jira_server.issue(subtask[0].key)
#single_issue = jira_server.issue(subtask[0].key)
try:
if cfg['update_desc_only']:
single_issue.update(fields={'description': description})
else:
single_issue.update(fields={'timetracking': {'originalEstimate': '{}d'.format(subtask_sp)}, 'description': description, 'assignee': {'name': assignee}})
except Exception as e:
logging.info(e)
@@ -102,13 +114,22 @@ def create_subtask(issue, parent, type, subtask_sp=0, estimation_remark="", no_u
logging.info('Created Sub-Task {}'.format(new_issue))
def get_description(type):
if (type == 'DoD SA/DEV'):
description = cfg['subtask_desc_dev']
elif (type == 'DoD Test'):
description = cfg['subtask_desc_test']
def get_description(type, no_unit_test=False):
if (type == 'Dev Backend'):
description = cfg['templates']['subtask_desc_be_dev']
if no_unit_test==False:
description += cfg['templates']['add_unit_test_desc']
elif (type in ('Dev Frontend', 'Dev Citizen-Frontend')):
description = cfg['templates']['subtask_desc_fe_dev']
elif (type == 'DoD SA'):
description = cfg['templates']['subtask_desc_sa']
#TODO: Add links to DEV-SubTasks
elif (type == 'Test-Anpassung (TOSCA/xRay)'):
#TODO: Use desc of story
description = 's. Story'
#description = cfg['templates']['subtask_desc_test']
elif (type == 'DoD PO'):
description = cfg['subtask_desc_po']
description = cfg['templates']['subtask_desc_po']
else:
description = 's. Story'
return description
@@ -124,7 +145,7 @@ with open("config.yaml", encoding='utf8') as f:
host = "https://jira.wien.gv.at/"
pat = "OTAyMTM3MjY0MjE0Ovz6bu0ti1TlEdSegmmiWiJ2wGeD"
sprint = 6
sprint = 5
headers = JIRA.DEFAULT_OPTIONS["headers"].copy()
headers["Authorization"] = f"Bearer {pat}"
@@ -132,7 +153,8 @@ jira_server = JIRA(server=host, options={"headers": headers})
# use filter or single issue
issues_Jql = jira_server.search_issues('filter=25827') #, expand='changelog')
#issues_Jql = jira_server.search_issues('key in (WRGWR-2932)') #, expand='changelog')
#issues_Jql = jira_server.search_issues('filter=30617') #, expand='changelog')
issues_Jql = jira_server.search_issues('key in (BAUWB-600)') #, 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(f'Creating sub-tasks out of estimation of pre-planning of {date.today()}')
@@ -159,8 +181,11 @@ for issue in issues_Jql:
for comment in comments:
comment_lines = comment.body.splitlines()
if len(comment_lines) == 9:
if len(comment_lines) in (5, 9):
if comment_lines[0][:5] == "Dev B":
if "Dev Unit-Tests: NN" in comment_lines:
no_unit_test = True
for comment_line in comment_lines:
if comment_line != "":
# pos = comment_lines[2].find('NN')
@@ -184,25 +209,25 @@ for issue in issues_Jql:
subtask_ph = float(comment_line_sub_parts[0]) * 0.5
estimation_remark = ""
else:
if comment_line_sub_parts[0].strip() == "tbd":
if comment_line_sub_parts[0].strip().lower() == "tbd":
subtask_ph = take_closest([1,2,3,5,8,13,21,42], sp_sum/3)
if comment_line_parts[0][:15] != "Test-Ausführung":
#if comment_line_parts[0][:15] != "Test-Ausführung":
create_subtask(issue,
issue.key,
comment_line_parts[0],
subtask_ph,
estimation_remark)
estimation_remark,
no_unit_test=no_unit_test)
sp_sum += subtask_ph / 0.5
else:
logging.info(f'Sub-task creation skipped {comment_line_parts[0]} equals \'NN\'')
if "Unit-Test" in comment_line_parts[0]:
no_unit_test = True
# find corresponding sub-task
# issuelinks.inwardIssue
try:
if sp != sp_sum:
if cfg['update_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))
@@ -213,7 +238,8 @@ for issue in issues_Jql:
logging.info('Done {}'.format(issue.key))
#create standard sub-tasks
for type in ['DoD SA/DEV','DoD Test','DoD PO']:
if cfg['separate_dod_subtasks']:
for type in ['DoD SA','DoD PO']:
create_subtask(issue,
issue.key,
type,