Skip to content

Commit

Permalink
Make furnish_ci_email_body() a pure function
Browse files Browse the repository at this point in the history
Summary: Create an extra level of indirection so that furnish_ci_email_body() can be pure. This makes testing the email notification formatting much easier. It also makes reviewing easier b/c people can look at the gold files.

Reviewed By: anakryiko

Differential Revision: D58206849

fbshipit-source-id: 37ef02eb460c406b9ac26fdcf24af03a3bb9490b
  • Loading branch information
Daniel Xu authored and facebook-github-bot committed Jun 5, 2024
1 parent 1d6efda commit 6a1cf53
Showing 1 changed file with 37 additions and 16 deletions.
53 changes: 37 additions & 16 deletions kernel_patches_daemon/branch_worker.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import shutil
import tempfile
import time
from collections import namedtuple
from contextlib import contextmanager
from datetime import datetime, timedelta, timezone
from email.mime.application import MIMEApplication
Expand Down Expand Up @@ -127,6 +128,12 @@
"""


# Context used to format email notification body
EmailBodyContext = namedtuple(
"EmailBodyContext", "status submission_name patchwork_url github_url inline_logs"
)


class StatusLabelSuffixes(Enum):
PASS = "ci-pass"
FAIL = "ci-fail"
Expand Down Expand Up @@ -189,27 +196,40 @@ async def get_ci_email_subject(series: Series) -> str:
return f"Re: {msg.get('subject', series.name)}"


def furnish_ci_email_body(
def build_email_body_context(
repo: Repository, pr: PullRequest, status: Status, series: Series, inline_logs: str
) -> str:
"""Prepare the body of a BPF CI email according to the provided status."""
if status == Status.SUCCESS:
github_actions_url = get_github_actions_url(repo, pr, status)
body = EMAIL_TEMPLATE_SUCCESS_BODY.format(github_actions_url=github_actions_url)
elif status == Status.FAILURE:
github_actions_url = get_github_actions_url(repo, pr, status)
) -> EmailBodyContext:
"""
Generate a context to be used for formatting email notification body.
This is used as an extra indirection to make testing easier.
"""
return EmailBodyContext(
status=status,
submission_name=get_ci_base(series)["name"],
patchwork_url=series.web_url + "&state=*",
github_url=get_github_actions_url(repo, pr, status),
inline_logs=inline_logs,
)


def furnish_ci_email_body(ctx: EmailBodyContext) -> str:
"""Prepare the body of a BPF CI email according to the provided context"""
if ctx.status == Status.SUCCESS:
body = EMAIL_TEMPLATE_SUCCESS_BODY.format(github_actions_url=ctx.github_url)
elif ctx.status == Status.FAILURE:
body = EMAIL_TEMPLATE_FAILURE_BODY.format(
inline_logs=inline_logs,
github_actions_url=github_actions_url,
inline_logs=ctx.inline_logs,
github_actions_url=ctx.github_url,
)
else:
assert status == Status.CONFLICT
body = EMAIL_TEMPLATE_MERGE_CONFLICT_BODY.format(github_pr_url=pr.html_url)
assert ctx.status == Status.CONFLICT
body = EMAIL_TEMPLATE_MERGE_CONFLICT_BODY.format(github_pr_url=ctx.github_url)

return EMAIL_TEMPLATE_BASE.format(
status=str(status.value).upper(),
submission_name=get_ci_base(series)["name"],
pw_series_url=series.web_url + "&state=*",
status=str(ctx.status.value).upper(),
submission_name=ctx.submission_name,
pw_series_url=ctx.patchwork_url,
body=body,
)

Expand Down Expand Up @@ -1102,7 +1122,8 @@ async def evaluate_ci_result(
failed_logs = await self.log_extractor.extract_failed_logs(jobs)
inline_logs = self.log_extractor.generate_inline_email_text(failed_logs)
subject = await get_ci_email_subject(series)
body = furnish_ci_email_body(self.repo, pr, status, series, inline_logs)
ctx = build_email_body_context(self.repo, pr, status, series, inline_logs)
body = furnish_ci_email_body(ctx)
await send_email(email, series, subject, body)

def expire_branches(self) -> None:
Expand Down

0 comments on commit 6a1cf53

Please sign in to comment.