diff --git a/component-config.yaml.sample b/component-config.yaml.sample index d8c9d4b..255d2e4 100644 --- a/component-config.yaml.sample +++ b/component-config.yaml.sample @@ -60,4 +60,5 @@ issues: id: subtask_regression parent_id: errata_task on_respin: close + transition: True job_recipe: https://raw.githubusercontent.com/RedHatQE/newa/ks_recipe_job/component-recipe.yaml.sample diff --git a/newa/__init__.py b/newa/__init__.py index 51451f5..cdccde5 100644 --- a/newa/__init__.py +++ b/newa/__init__.py @@ -645,7 +645,7 @@ class Issue(Cloneable, Serializable): summary: Optional[str] = None closed: Optional[bool] = None url: Optional[str] = None - transition_pass: Optional[str] = None + transition_passed: Optional[str] = None transition_results: Optional[str] = None def __str__(self) -> str: @@ -1123,8 +1123,8 @@ class IssueAction: # type: ignore[no-untyped-def] class IssueTransitions(Serializable): closed: list[str] = field() dropped: list[str] = field() - passed: Optional[list[str]] = field() - results: Optional[list[str]] = field() + passed: Optional[list[str]] = None + results: Optional[list[str]] = None @define diff --git a/newa/cli.py b/newa/cli.py index 1c6b77a..4d71d55 100644 --- a/newa/cli.py +++ b/newa/cli.py @@ -47,6 +47,7 @@ JIRA_NONE_ID = '_NO_ISSUE' STATEDIR_PARENT_DIR = Path('/var/tmp/newa') STATEDIR_NAME_PATTERN = r'^run-([0-9]+)$' +TF_RESULT_PASSED = 'passed' logging.basicConfig( format='%(asctime)s %(message)s', @@ -99,6 +100,22 @@ def initialize_jira_connection(ctx: CLIContext) -> Any: return jira.JIRA(jira_url, token_auth=jira_token) +def issue_transition(connection: Any, transition: str, issue_id: str) -> None: + try: + # if the transition has a format status.resolution close with resolution + if '.' in transition: + status, resolution = transition.split('.', 1) + connection.transition_issue(issue_id, + transition=status, + resolution={'name': resolution}) + # otherwise close just using the status + else: + connection.transition_issue(issue_id, + transition=transition) + except jira.JIRAError as e: + raise Exception(f"Cannot transition issue {issue_id} into {transition}!") from e + + @click.group(chain=True) @click.option( '--state-dir', @@ -561,11 +578,22 @@ def _jira_fake_id_generator() -> Generator[str, int, None]: new_issues: list[Issue] = [] old_issues: list[Issue] = [] + # read transition settings + transition_passed = None + transition_results = None + if action.transition: + if jira_handler.transitions.passed: + transition_passed = jira_handler.transitions.passed[0] + if jira_handler.transitions.results: + transition_results = jira_handler.transitions.results[0] + # first check if we have a match in issue_mapping if action.id and action.id in issue_mapping and issue_mapping[action.id].strip(): mapped_issue = Issue( issue_mapping[action.id].strip(), - group=config.group) + group=config.group, + transition_passed=transition_passed, + transition_results=transition_results) jira_issue = jira_handler.get_details(mapped_issue) mapped_issue.closed = jira_issue.get_field( "status").name in jira_handler.transitions.closed @@ -603,14 +631,18 @@ def _jira_fake_id_generator() -> Generator[str, int, None]: Issue( jira_issue_key, group=config.group, - closed=jira_issue["status"] == "closed")) + closed=jira_issue["status"] == "closed", + transition_passed=transition_passed, + transition_results=transition_results)) # opened old issues may be reused elif jira_issue["status"] == "opened": old_issues.append( Issue( jira_issue_key, group=config.group, - closed=False)) + closed=False, + transition_passed=transition_passed, + transition_results=transition_results)) # Old opened issue(s) can be re-used for the current respin. if old_issues and action.on_respin == OnRespinAction.KEEP: @@ -1050,6 +1082,7 @@ def cmd_report(ctx: CLIContext) -> None: # now for each jira id finish the respective launch and report results for jira_id in jira_execute_job_mapping: + all_tests_passed = True # get RP launch details launch_uuid = jira_execute_job_mapping[jira_id][0].request.reportportal.get( 'launch_uuid', None) @@ -1065,6 +1098,8 @@ def cmd_report(ctx: CLIContext) -> None: 'result': job.execution.result, 'uuid': job.execution.request_uuid, 'url': job.execution.artifacts_url} + if job.execution.result != TF_RESULT_PASSED: + all_tests_passed = False launch_description = jira_execute_job_mapping[jira_id][0].request.reportportal.get( 'launch_description', '') if launch_description: @@ -1098,3 +1133,16 @@ def cmd_report(ctx: CLIContext) -> None: f'Jira issue {jira_id} was updated with a RP launch URL {launch_url}') except jira.JIRAError as e: raise Exception(f"Unable to add a comment to issue {jira_id}!") from e + # change Jira issue state if required + if execute_job.jira.transition_passed and all_tests_passed: + issue_transition(jira_connection, + execute_job.jira.transition_passed, + jira_id) + ctx.logger.info( + f'Issue {jira_id} state changed to {execute_job.jira.transition_passed}') + elif execute_job.jira.transition_results: + issue_transition(jira_connection, + execute_job.jira.transition_results, + jira_id) + ctx.logger.info( + f'Issue {jira_id} state changed to {execute_job.jira.transition_results}')