|
21 | 21 | from services.comparison import ComparisonProxy |
22 | 22 | from services.decoration import Decoration |
23 | 23 | from services.license import is_properly_licensed |
24 | | -from services.notification.commit_notifications import ( |
25 | | - create_or_update_commit_notification_from_notification_result, |
26 | | -) |
| 24 | +from services.notification.commit_notifications import store_notification_results |
27 | 25 | from services.notification.notifiers import ( |
28 | 26 | StatusType, |
29 | 27 | get_all_notifier_classes_mapping, |
@@ -162,6 +160,8 @@ def get_notifiers_instances(self) -> Iterator[AbstractBaseNotifier]: |
162 | 160 | if yaml_field is not None: |
163 | 161 | for instance_type, instance_configs in yaml_field.items(): |
164 | 162 | class_to_use = mapping.get(instance_type) |
| 163 | + if not class_to_use: |
| 164 | + continue |
165 | 165 | for title, individual_config in instance_configs.items(): |
166 | 166 | yield class_to_use( |
167 | 167 | repository=self.repository, |
@@ -269,127 +269,101 @@ def notify(self, comparison: ComparisonProxy) -> list[IndividualResult]: |
269 | 269 | ), |
270 | 270 | ) |
271 | 271 |
|
272 | | - results = [] |
273 | | - status_or_checks_helper_text = {} |
274 | | - notifiers_to_notify = [ |
| 272 | + status_or_checks_notifiers, all_other_notifiers = split_notifiers( |
275 | 273 | notifier |
276 | 274 | for notifier in self.get_notifiers_instances() |
277 | 275 | if notifier.is_enabled() |
278 | | - ] |
279 | | - |
280 | | - status_or_checks_notifiers = [ |
281 | | - notifier |
282 | | - for notifier in notifiers_to_notify |
283 | | - if notifier.notification_type in notification_type_status_or_checks |
284 | | - ] |
285 | | - |
286 | | - all_other_notifiers = [ |
287 | | - notifier |
288 | | - for notifier in notifiers_to_notify |
289 | | - if notifier.notification_type not in notification_type_status_or_checks |
290 | | - ] |
| 276 | + ) |
291 | 277 |
|
292 | | - status_or_checks_results = [ |
| 278 | + results = [ |
293 | 279 | self.notify_individual_notifier(notifier, comparison) |
294 | 280 | for notifier in status_or_checks_notifiers |
295 | 281 | ] |
296 | 282 |
|
297 | | - if status_or_checks_results and all_other_notifiers: |
| 283 | + status_or_checks_helper_text = {} |
| 284 | + if results and all_other_notifiers: |
298 | 285 | # if the status/check fails, sometimes we want to add helper text to the message of the other notifications, |
299 | 286 | # to better surface that the status/check failed. |
300 | 287 | # so if there are status_and_checks_notifiers and all_other_notifiers, do the status_and_checks_notifiers first, |
301 | 288 | # look at the results of the checks, if any failed AND they are the type we have helper text for, |
302 | 289 | # add that text onto the other notifiers messages through status_or_checks_helper_text. |
303 | | - for result in status_or_checks_results: |
304 | | - notification_result = result["result"] |
305 | | - if ( |
306 | | - notification_result is not None |
307 | | - and notification_result.data_sent is not None |
308 | | - ): |
| 290 | + for notifier, result in results: |
| 291 | + if result is not None and result.data_sent is not None: |
309 | 292 | if ( |
310 | | - notification_result.data_sent.get("state") |
311 | | - == StatusState.failure.value |
312 | | - ) and notification_result.data_sent.get("included_helper_text"): |
| 293 | + result.data_sent.get("state") == StatusState.failure.value |
| 294 | + ) and result.data_sent.get("included_helper_text"): |
313 | 295 | status_or_checks_helper_text.update( |
314 | | - notification_result.data_sent["included_helper_text"] |
| 296 | + result.data_sent["included_helper_text"] |
315 | 297 | ) |
316 | | - results = results + status_or_checks_results |
317 | 298 |
|
318 | | - results = results + [ |
| 299 | + results.extend( |
319 | 300 | self.notify_individual_notifier( |
320 | 301 | notifier, |
321 | 302 | comparison, |
322 | 303 | status_or_checks_helper_text=status_or_checks_helper_text, |
323 | 304 | ) |
324 | 305 | for notifier in all_other_notifiers |
| 306 | + ) |
| 307 | + |
| 308 | + store_notification_results(comparison, results) |
| 309 | + |
| 310 | + return [ |
| 311 | + IndividualResult( |
| 312 | + notifier=notifier.name, title=notifier.title, result=result |
| 313 | + ) |
| 314 | + for notifier, result in results |
325 | 315 | ] |
326 | | - return results |
327 | 316 |
|
328 | 317 | def notify_individual_notifier( |
329 | 318 | self, |
330 | 319 | notifier: AbstractBaseNotifier, |
331 | 320 | comparison: ComparisonProxy, |
332 | 321 | status_or_checks_helper_text: Optional[dict[str, str]] = None, |
333 | | - ) -> IndividualResult: |
| 322 | + ) -> tuple[AbstractBaseNotifier, NotificationResult | None]: |
334 | 323 | commit = comparison.head.commit |
335 | 324 | base_commit = comparison.project_coverage_base.commit |
336 | | - log.info( |
337 | | - "Attempting individual notification", |
338 | | - extra=dict( |
339 | | - commit=commit.commitid, |
340 | | - base_commit=( |
341 | | - base_commit.commitid if base_commit is not None else "NO_BASE" |
342 | | - ), |
343 | | - repoid=commit.repoid, |
344 | | - notifier=notifier.name, |
345 | | - notifier_title=notifier.title, |
346 | | - ), |
347 | | - ) |
348 | | - # individual_result.result is updated in case of success |
349 | | - individual_result = IndividualResult( |
350 | | - notifier=notifier.name, title=notifier.title, result=None |
351 | | - ) |
| 325 | + log_extra = { |
| 326 | + "commit": commit.commitid, |
| 327 | + "base_commit": base_commit.commitid |
| 328 | + if base_commit is not None |
| 329 | + else "NO_BASE", |
| 330 | + "repoid": commit.repoid, |
| 331 | + "notifier": notifier.name, |
| 332 | + "notifier_title": notifier.title, |
| 333 | + } |
| 334 | + |
| 335 | + log.info("Attempting individual notification", extra=log_extra) |
352 | 336 | try: |
353 | 337 | res = notifier.notify( |
354 | 338 | comparison, status_or_checks_helper_text=status_or_checks_helper_text |
355 | 339 | ) |
356 | | - individual_result["result"] = res |
| 340 | + log_extra["result"] = res |
357 | 341 |
|
| 342 | + # TODO: The `CommentNotifier` is the only one implementing this method, |
| 343 | + # so maybe we should just move it there |
358 | 344 | notifier.store_results(comparison, res) |
359 | | - log.info( |
360 | | - "Individual notification done", |
361 | | - extra=dict( |
362 | | - individual_result=individual_result, |
363 | | - commit=commit.commitid, |
364 | | - base_commit=( |
365 | | - base_commit.commitid if base_commit is not None else "NO_BASE" |
366 | | - ), |
367 | | - repoid=commit.repoid, |
368 | | - ), |
369 | | - ) |
370 | | - return individual_result |
| 345 | + |
| 346 | + log.info("Individual notification done", extra=log_extra) |
| 347 | + return notifier, res |
371 | 348 | except (CeleryError, SoftTimeLimitExceeded): |
372 | 349 | raise |
373 | 350 | except Exception: |
374 | | - log.exception( |
375 | | - "Individual notifier failed", |
376 | | - extra=dict( |
377 | | - repoid=commit.repoid, |
378 | | - commit=commit.commitid, |
379 | | - individual_result=individual_result, |
380 | | - base_commit=( |
381 | | - base_commit.commitid if base_commit is not None else "NO_BASE" |
382 | | - ), |
383 | | - ), |
384 | | - ) |
385 | | - return individual_result |
386 | | - finally: |
387 | | - if ( |
388 | | - individual_result["result"] is None |
389 | | - or individual_result["result"].notification_attempted |
390 | | - ): |
391 | | - # only running if there is no result (indicating some exception) |
392 | | - # or there was an actual attempt |
393 | | - create_or_update_commit_notification_from_notification_result( |
394 | | - comparison, notifier, individual_result["result"] |
395 | | - ) |
| 351 | + log.exception("Individual notifier failed", extra=log_extra) |
| 352 | + return notifier, None |
| 353 | + |
| 354 | + |
| 355 | +def split_notifiers( |
| 356 | + notifiers: Iterator[AbstractBaseNotifier], |
| 357 | +) -> tuple[list[AbstractBaseNotifier], list[AbstractBaseNotifier]]: |
| 358 | + "Splits the input notifiers based on whether they are a status/check, or other notifier." |
| 359 | + |
| 360 | + status_or_checks_notifiers = [] |
| 361 | + all_other_notifiers = [] |
| 362 | + |
| 363 | + for notifier in notifiers: |
| 364 | + if notifier.notification_type in notification_type_status_or_checks: |
| 365 | + status_or_checks_notifiers.append(notifier) |
| 366 | + else: |
| 367 | + all_other_notifiers.append(notifier) |
| 368 | + |
| 369 | + return status_or_checks_notifiers, all_other_notifiers |
0 commit comments