Skip to content

k4bench.regression.notify

k4bench.regression.notify

E-group email delivery for the nightly regression report.

Stdlib-only (smtplib/email): the nightly job runs on CERN-network runners, so mail goes directly through CERN's outbound relay without authentication — no SMTP secrets to manage. If the relay ever starts rejecting these runners (SPF/relay ACL), fall back to an authenticated SMTP action with repo secrets.

Every night's report is emailed, regardless of content — regressions, failures, or a clean run all send.

Runnable as python -m k4bench.regression.notify report.json --to … — the module gates itself only on missing recipient config (exits quietly when none is set), so the CI step can run unconditionally.

send_report_email

send_report_email(report: NightlyReport, *, to_addr: str, from_addr: str, smtp_host: str = DEFAULT_SMTP_HOST, smtp_port: int = DEFAULT_SMTP_PORT, dashboard_url: str | None = None, actions_url: str | None = None, blame: BlameReport | None = None, historical_blame: dict[str, BlameReport] | None = None) -> bool

Send the report to to_addr, every night, regardless of content.

blame, when present, adds ranked candidate PRs under each confirmed regression it has attributed; historical_blame maps a first_confirmed_run_id to that night's sidecar, reused for same-release reconfirmations. Both are best-effort and never gate the email.

Returns True once the mail has been handed to the relay.

Source code in k4bench/regression/notify.py
def send_report_email(
    report: NightlyReport,
    *,
    to_addr: str,
    from_addr: str,
    smtp_host: str = DEFAULT_SMTP_HOST,
    smtp_port: int = DEFAULT_SMTP_PORT,
    dashboard_url: str | None = None,
    actions_url: str | None = None,
    blame: BlameReport | None = None,
    historical_blame: dict[str, BlameReport] | None = None,
) -> bool:
    """Send the report to *to_addr*, every night, regardless of content.

    *blame*, when present, adds ranked candidate PRs under each confirmed
    regression it has attributed; *historical_blame* maps a
    ``first_confirmed_run_id`` to that night's sidecar, reused for same-release
    reconfirmations. Both are best-effort and never gate the email.

    Returns ``True`` once the mail has been handed to the relay.
    """
    msg = MIMEMultipart("alternative")
    msg["Subject"] = email_subject(report)
    msg["From"] = from_addr
    msg["To"] = to_addr
    # Standard automated-message headers so mail clients and the relay treat
    # this as machine-generated (no auto-replies, sortable date, unique id).
    msg["Date"] = formatdate(localtime=False)
    msg["Message-ID"] = make_msgid(domain="cern.ch")
    msg["Auto-Submitted"] = "auto-generated"
    # Plain-text fallback first, HTML preferred-last per MIME convention.
    msg.attach(MIMEText(
        to_markdown(
            report, dashboard_url=dashboard_url, actions_url=actions_url,
            blame=blame, historical_blame=historical_blame,
        ),
        "plain", "utf-8",
    ))
    msg.attach(MIMEText(
        to_html(
            report, dashboard_url=dashboard_url, actions_url=actions_url,
            blame=blame, historical_blame=historical_blame,
        ),
        "html", "utf-8",
    ))

    with smtplib.SMTP(smtp_host, smtp_port) as smtp:
        smtp.sendmail(from_addr, [to_addr], msg.as_string())
    _log.info("send_report_email: sent nightly report email to %s", to_addr)
    return True