blob: 12375a20264094cc5e2375c907b45fc7840b0eb6 [file] [log] [blame]
# Copyright 2025 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Pings an email address about any autogenerated CLs that need review."""
import argparse
import logging
from pathlib import Path
from typing import List
from cros_utils import cros_paths
from cros_utils import email_sender
from cros_utils import git_utils
def count_outstanding_cls(chromeos_root: Path) -> int:
query = " ".join(
(
"owner:mobiletc-prebuild@google.com",
"topic:crostc-auto-cl",
"status:open",
"-is:wip",
"-is:submittable",
)
)
cls = git_utils.query_gerrit(
chromeos_root,
query,
)
logging.info("CLs matching query %r: %s", query, cls)
return len(cls)
def main(argv: List[str]) -> None:
# This is meant to be run from a ChromeOS tree for simplicity.
chromeos_root = cros_paths.script_chromiumos_checkout_or_exit()
logging.basicConfig(
format=">> %(asctime)s: %(levelname)s: %(filename)s:%(lineno)d: "
"%(message)s",
level=logging.INFO,
)
parser = argparse.ArgumentParser(
description=__doc__,
formatter_class=argparse.RawDescriptionHelpFormatter,
)
parser.add_argument(
"--email",
help="Email to send ping to",
)
parser.add_argument(
"-n",
"--dry-run",
action="store_true",
help="Don't actually send an email",
)
opts = parser.parse_args(argv)
if not (opts.email or opts.dry_run):
parser.error("You must pass either --dry-run or --email")
logging.info("Searching for CLs that need a review...")
num_outstanding_cls = count_outstanding_cls(chromeos_root)
if not num_outstanding_cls:
logging.info("No outstanding CLs found; exit")
return
logging.info(
"Sending email notification of %d outstanding CLs", num_outstanding_cls
)
# NOTE: Please keep this subject constant, so Chat threads these
# notifications instead of posting new discussions.
subject = "Autogenerated CL(s) need review"
body = (
f"http://go/crostc-unreviewed-auto-cls says {num_outstanding_cls} "
"need(s) review"
)
if opts.dry_run:
logging.info("--dry-run specified; skipping sending email")
logging.info("Subject: %s", subject)
logging.info("Body: %s", body)
return
email_sender.EmailSender().SendGSEmail(
subject=subject,
identifier="cl-pings",
text_body=body,
direct_recipients=(opts.email,),
)