From 5cd9d55166b35aae421616122bfb1fce2679559c Mon Sep 17 00:00:00 2001 From: Daniil Baturin Date: Tue, 2 Jul 2024 20:09:43 +0100 Subject: Get the task unassigning workflow to work correctly and give the code a clean-up (more clean-up is coming) --- phabricator_tasks/get_task_data.py | 38 ++++++++++++++++-------------------- phabricator_tasks/tasks.py | 40 ++++++++++++++++++-------------------- 2 files changed, 36 insertions(+), 42 deletions(-) diff --git a/phabricator_tasks/get_task_data.py b/phabricator_tasks/get_task_data.py index 52d6f08..6a2fef7 100644 --- a/phabricator_tasks/get_task_data.py +++ b/phabricator_tasks/get_task_data.py @@ -50,8 +50,7 @@ class Phabricator(PhabricatorOriginal): def __init__(self, **kwargs): kwargs['interface'] = copy.deepcopy(parse_interfaces(INTERFACES)) super(Phabricator, self).__init__(self, **kwargs) - -''' end of extend the original Phabricator class''' + def phab_api(token): return Phabricator(host='https://vyos.dev/api/', token=token) @@ -94,26 +93,29 @@ def get_project_default_column(project_id, workboards): return workboard['phid'], workboard['fields']['name'] return None, None - def close_task(task_id, token): phab = phab_api(token) try: - response = phab.maniphest.update( - id=task_id, - status='resolved' + response = phab.maniphest.edit( + objectIdentifier=task_id, + transactions=[{'type': 'status', 'value': 'resolved'}] ) if response.response['isClosed']: print(f'T{task_id} closed') except Exception as e: print(f'T{task_id} Error: {e}') - def unassign_task(task_id, token): phab = phab_api(token) - raise NotImplementedError + try: + response = phab.maniphest.edit( + objectIdentifier=task_id, + transactions=[{'type': 'owner', 'value': None}] + ) + except Exception as e: + print(f'T{task_id} Error: {e}') def get_task_data(token): - phab = phab_api(token) # get list with all open status namens open_status_list = phab.maniphest.querystatuses().response @@ -124,7 +126,7 @@ def get_task_data(token): tasks = phab_search(phab.maniphest.search, constraints={ 'statuses': open_status_list }) - + # get all projects to translate id to name projects_raw = phab_search(phab.project.search) projects = {} @@ -132,7 +134,7 @@ def get_task_data(token): projects[p['phid']] = p['fields']['name'] workboards = phab_search(phab.project.column.search) - + # get sub-project hirarchy from proxyPHID in workboards project_hirarchy = {} for workboard in workboards: @@ -148,10 +150,11 @@ def get_task_data(token): for task in tasks: task_data = { 'task_id': task['id'], + 'task_phid': task['phid'], 'task_name': task['fields']['name'], 'task_status': task['fields']['status']['value'], 'assigned_user': task['fields']['ownerPHID'], - 'assigned_time': None, + 'last_modified': task['fields']['dateModified'], 'projects': [] } if task['fields']['status']['value'] in open_status_list: @@ -160,13 +163,6 @@ def get_task_data(token): task_data['task_open'] = False transactions = phab.maniphest.gettasktransactions(ids=[task['id']]) - # transactionType: reassign to get assigened time - if task_data['assigned_user']: - for transaction in transactions[str(task['id'])]: - if transaction['transactionType'] == 'reassign' and transaction['newValue'] == task['fields']['ownerPHID']: - task_data['assigned_time'] = transaction['dateCreated'] - break - # transactionType: core:edge # loop reversed from oldest to newest transaction # core:edge transactionType is used if the task is moved to another project but stay in default column @@ -181,7 +177,7 @@ def get_task_data(token): for newValue in transaction['newValue']: if "PHID-PROJ" in newValue: task_projects.append(newValue) - + # transactionType: core:columns # use task_projects items as search indicator 'boardPHID' == project_id # remove project from task_projects if the task is moved from the default column to another column @@ -196,7 +192,7 @@ def get_task_data(token): 'project_id': transaction['newValue'][0]['boardPHID'], }) - + # handle remaining projects and set the project base default column for project in task_projects: default_columnid, default_columnname = get_project_default_column(project, workboards) diff --git a/phabricator_tasks/tasks.py b/phabricator_tasks/tasks.py index fd76f69..5504369 100644 --- a/phabricator_tasks/tasks.py +++ b/phabricator_tasks/tasks.py @@ -1,9 +1,9 @@ ''' -implement Tasks checks and workflows on vyos.dev - -1. Close a tasks if the Task is in all "Finished" columns +Phorge task chores: +1. Close a tasks if it's "Finished" in all boards but not yet resolved +2. Unassign tasks that are nominally assigned to someone but had no activity in a long time ''' @@ -20,7 +20,7 @@ args = parser.parse_args() TOKEN = args.token DRYRUN = args.dry -# DRYRUN = True + UNASSIGN_AFTER_DAYS = 90 UNASSIGN_AFTER_DAYS = timedelta(days=UNASSIGN_AFTER_DAYS) NOW = datetime.now() @@ -31,7 +31,8 @@ if DRYRUN: tasks = get_task_data(TOKEN) for task in tasks: - # close tasks it is in any projects "finished" column + # Close tasks that are in the "Finished" column in all projects + # but aren't marked resolved yet if len(task['projects']) > 0: finished = True for project in task['projects']: @@ -39,22 +40,19 @@ for task in tasks: finished = False break if finished: + print(f'Closing task T{task["task_id"]} (finished in all boards)') if DRYRUN: - print(f'dryrun: T{task["task_id"]} would be closed') + pass else: - close_task(task['task_id'], TOKEN) - continue - - - ''' - # unassign tasks with no process after UNASSIGN_AFTER_DAYS - if task['assigned_user'] and task['assigned_time']: - delta = NOW - datetime.fromtimestamp(int(task['assigned_time'])) + close_task(task['task_phid'], TOKEN) + + # Unassign tasks that supposed assignees aren't actively working on in a long time + if task['assigned_user']: + delta = NOW - datetime.fromtimestamp(int(task['last_modified'])) if delta > UNASSIGN_AFTER_DAYS: - if task['task_status'] != 'open': - if DRYRUN: - print(f'dryrun: T{task["task_id"]} with status {task['task_status']} would be unassigned after {delta.days} days') - else: - unassign_task(task['task_id'], TOKEN) - continue - ''' \ No newline at end of file + print(f'Unassigning task T{task["task_id"]} after {delta.days} days of inactivity') + if DRYRUN: + pass + else: + unassign_task(task['task_id'], TOKEN) + -- cgit v1.2.3