Applies all discovered transformation methods to a single Redmine issue and sends a single update API call if changes are made.
(self, issue)
| 1095 | |
| 1096 | |
| 1097 | def _process_issue_transformations(self, issue): |
| 1098 | """ |
| 1099 | Applies all discovered transformation methods to a single Redmine issue |
| 1100 | and sends a single update API call if changes are made. |
| 1101 | """ |
| 1102 | self.issues_inspected += 1 |
| 1103 | issue = self.R.issue.get(issue.id, include=['children', 'journals', 'relations']) |
| 1104 | issue_update = IssueUpdate(issue, self.session, self.G) |
| 1105 | issue_update.logger.debug("Beginning transformation processing.") |
| 1106 | |
| 1107 | if IS_GITHUB_ACTION: |
| 1108 | log_stream.flush() |
| 1109 | print(f"::group::Processing Issue #{issue.id}: {issue.subject}", file=sys.stderr, flush=True) # Start GitHub Actions group |
| 1110 | issue_update.logger.info(f"Issue URL: {issue.url}") |
| 1111 | else: |
| 1112 | issue_update.logger.info(f"Processing issue: {issue.url} '{issue.subject}'") |
| 1113 | |
| 1114 | try: |
| 1115 | applied_transformations = [] |
| 1116 | for transform_method in self.transform_methods: |
| 1117 | # Each transformation method modifies the same issue_update object |
| 1118 | transform_name = transform_method.__name__.removeprefix("_transform_") |
| 1119 | issue_update.logger.debug(f"Calling transformation: {transform_name}") |
| 1120 | issue_update.set_transform(transform_name) |
| 1121 | if transform_method(issue_update): |
| 1122 | issue_update.logger.info(f"Transformation {transform_method.__name__} resulted in a change.") |
| 1123 | applied_transformations.append(transform_method.__name__) |
| 1124 | |
| 1125 | issue_update.set_transform(None) |
| 1126 | if issue_update.has_changes: |
| 1127 | issue_update.logger.info("Changes detected. Sending update to Redmine...") |
| 1128 | try: |
| 1129 | # We cannot put top-level changes in the PUT request against |
| 1130 | # the redmine API via redminelib. So we send it manually. |
| 1131 | payload = issue_update.get_update_payload() |
| 1132 | issue_update.logger.debug("PUT payload:\n%s", json.dumps(payload, indent=4)) |
| 1133 | headers = { |
| 1134 | 'Content-Type': 'application/json', |
| 1135 | 'X-Redmine-API-Key': REDMINE_API_KEY, |
| 1136 | } |
| 1137 | endpoint = f"{REDMINE_ENDPOINT}/issues/{issue.id}.json" |
| 1138 | response = requests.put(endpoint, headers=headers, data=json.dumps(payload)) |
| 1139 | response.raise_for_status() |
| 1140 | issue_update.logger.info("Successfully updated Redmine issue.") |
| 1141 | self.issues_modified += 1 |
| 1142 | for t_name in applied_transformations: |
| 1143 | self.modifications_made.setdefault(t_name, set()).add(issue.id) |
| 1144 | return True |
| 1145 | except requests.exceptions.HTTPError as e: |
| 1146 | issue_update.logger.error("API PUT failure during upkeep.", exc_info=True) |
| 1147 | raise RedmineUpdateException(issue_update, exception=e, traceback=traceback.format_exc()) |
| 1148 | else: |
| 1149 | issue_update.logger.info("No changes detected after all transformations. No Redmine update sent.") |
| 1150 | return False |
| 1151 | except UpkeepException as e: |
| 1152 | self._handle_upkeep_failure(issue_update, e) |
| 1153 | return False |
| 1154 | finally: |
no test coverage detected