Skip to content

Commit

Permalink
Add basic support for issue-config file defaults
Browse files Browse the repository at this point in the history
  • Loading branch information
kkaarreell committed Nov 14, 2024
1 parent b074811 commit fd6ff9a
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 7 deletions.
5 changes: 5 additions & 0 deletions component-config.yaml.sample
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ transitions:
dropped:
- Dropped

#defaults:
# fields:
# "Pool Team": "my_great_team"
# "Story Points": 0

issues:

- summary: "Errata Workflow Checklist {% if ERRATUM.respin_count > 0 %}(respin {{ ERRATUM.respin_count }}){% endif %}"
Expand Down
13 changes: 7 additions & 6 deletions newa/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1101,13 +1101,13 @@ class OnRespinAction(Enum):


@define
class IssueAction: # type: ignore[no-untyped-def]
summary: str
description: str
id: str
type: IssueType = field(converter=IssueType)
class IssueAction(Serializable): # type: ignore[no-untyped-def]
type: IssueType = field(converter=IssueType, default=IssueType.TASK)
on_respin: OnRespinAction = field( # type: ignore[var-annotated]
converter=lambda value: OnRespinAction(value), default=OnRespinAction.CLOSE)
summary: Optional[str] = None
description: Optional[str] = None
id: Optional[str] = None
assignee: Optional[str] = None
parent_id: Optional[str] = None
job_recipe: Optional[str] = None
Expand All @@ -1118,9 +1118,10 @@ class IssueAction: # type: ignore[no-untyped-def]

@define
class IssueConfig(Serializable): # type: ignore[no-untyped-def]

project: str = field()
transitions: dict[str, list[str]] = field()
defaults: Optional[IssueAction] = field( # type: ignore[var-annotated]
converter=lambda action: IssueAction(**action) if action else None, default=None)
issues: list[IssueAction] = field( # type: ignore[var-annotated]
factory=list, converter=lambda issues: [
IssueAction(**issue) for issue in issues])
Expand Down
41 changes: 40 additions & 1 deletion newa/cli.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import copy
import datetime
import logging
import multiprocessing
Expand Down Expand Up @@ -26,6 +27,7 @@
ExecuteJob,
Execution,
Issue,
IssueAction,
IssueConfig,
IssueHandler,
JiraJob,
Expand Down Expand Up @@ -456,8 +458,16 @@ def _jira_fake_id_generator() -> Generator[str, int, None]:

jira_none_id = _jira_fake_id_generator()

def _default_action_id_generator() -> Generator[str, int, None]:
n = 1
while True:
yield f'ACTION_ID_{n}'
n += 1

default_action_id = _default_action_id_generator()

# load issue mapping specified on a command line
issue_mapping = {}
issue_mapping: dict[str, str] = {}
artifact_jobs = ctx.load_artifact_jobs('event-')

# issue mapping is relevant only when using issue-config file
Expand Down Expand Up @@ -511,13 +521,35 @@ def _jira_fake_id_generator() -> Generator[str, int, None]:
# Use to prevent endless loop over the issue actions.
endless_loop_check: dict[str, int] = {}

# updates
def _update_action_with_defaults(
action: IssueAction,
defaults: Optional[IssueAction] = None) -> IssueAction:
new_action = copy.deepcopy(action)
if not isinstance(defaults, IssueAction):
return new_action
for attr_name in dir(defaults):
attr = getattr(defaults, attr_name)
if attr and (not attr_name.startswith('_') or callable(attr)):
if attr_name == 'fields' and defaults.fields:
if new_action.fields:
new_action.fields.update(copy.deepcopy(defaults.fields))
else:
setattr(new_action, attr_name, copy.deepcopy(defaults.fields))
elif not getattr(new_action, attr_name, None):
setattr(new_action, attr_name, copy.deepcopy(attr))
return new_action

# Iterate over issue actions. Take one, if it's not possible to finish it,
# put it back at the end of the queue.
while issue_actions:
action = issue_actions.pop(0)

ctx.logger.info(f"Processing {action.id}")

# update action object with default attributes when not present
action = _update_action_with_defaults(action, config.defaults)

if action.when and not eval_test(action.when,
JOB=artifact_job,
EVENT=artifact_job.event,
Expand All @@ -527,6 +559,13 @@ def _jira_fake_id_generator() -> Generator[str, int, None]:
ctx.logger.info(f"Skipped, issue action is irrelevant ({action.when})")
continue

if not action.id:
action.id = next(default_action_id)
if not action.summary:
raise Exception(f"Action {action} does not have a 'summary' defined.")
if not action.description:
raise Exception(f"Action {action} does not have a 'description' defined.")

rendered_summary = render_template(
action.summary,
ERRATUM=artifact_job.erratum,
Expand Down

0 comments on commit fd6ff9a

Please sign in to comment.