(repo|submodule)_roller: Reduce CCing

Don't CC authors and reviewers on rolls of more than 10 commits.
Something may be broken and we don't want to spam people.

Change-Id: I71ec429d3dc2e4fd351a861b05c540668782dcb8
Reviewed-on: https://pigweed-review.googlesource.com/c/infra/recipes/+/154650
Presubmit-Verified: CQ Bot Account <pigweed-scoped@luci-project-accounts.iam.gserviceaccount.com>
Commit-Queue: Auto-Submit <auto-submit@pigweed.google.com.iam.gserviceaccount.com>
Pigweed-Auto-Submit: Rob Mohr <mohrr@google.com>
Reviewed-by: Ted Pudlik <tpudlik@google.com>
diff --git a/recipes/repo_roller.proto b/recipes/repo_roller.proto
index 24b6689..bb302ba 100644
--- a/recipes/repo_roller.proto
+++ b/recipes/repo_roller.proto
@@ -53,4 +53,9 @@
 
   // Auto roller module options.
   recipe_modules.fuchsia.auto_roller.Options auto_roller_options = 11;
+
+  // Max number of commits for which authors and reviewers should be CCd.
+  // Default is 10. To disable CCing, don't set the "cc_*_on_rolls" values
+  // above, or set this to a negative value.
+  int32 max_commits_for_ccing = 12;
 }
diff --git a/recipes/repo_roller.py b/recipes/repo_roller.py
index 9a359fd..13c888f 100644
--- a/recipes/repo_roller.py
+++ b/recipes/repo_roller.py
@@ -225,26 +225,29 @@
         direction=direction,
     )
 
-    cc = set()
     authors = api.roll_util.authors(roll)
-    if cc_authors_on_rolls:
-        cc.update(authors)
-    if cc_reviewers_on_rolls:
-        cc.update(api.roll_util.reviewers(roll))
 
-    def include_cc(email):
-        return api.roll_util.include_cc(
-            email, cc_domains, checkout.gerrit_host()
-        )
+    max_commits_for_ccing = props.max_commits_for_ccing or 10
+    if len(roll.commits) <= max_commits_for_ccing:
+        cc = set()
+        if cc_authors_on_rolls:
+            cc.update(authors)
+        if cc_reviewers_on_rolls:
+            cc.update(api.roll_util.reviewers(roll))
 
-    # include_cc() writes steps, so we want things sorted before calling it.
-    cc = sorted(set(cc))
-    cc_emails = [x.email for x in cc if include_cc(x)]
+        def include_cc(email):
+            return api.roll_util.include_cc(
+                email, cc_domains, checkout.gerrit_host()
+            )
 
-    if always_cc:
-        props.auto_roller_options.cc_emails.extend(cc_emails)
-    else:
-        props.auto_roller_options.cc_on_failure_emails.extend(cc_emails)
+        # include_cc() writes steps, so we want things sorted before calling it.
+        cc = sorted(set(cc))
+        cc_emails = [x.email for x in cc if include_cc(x)]
+
+        if always_cc:
+            props.auto_roller_options.cc_emails.extend(cc_emails)
+        else:
+            props.auto_roller_options.cc_on_failure_emails.extend(cc_emails)
 
     author_override = None
     with api.step.nest('authors') as pres:
diff --git a/recipes/submodule_roller.proto b/recipes/submodule_roller.proto
index 1a50f81..b51adea 100644
--- a/recipes/submodule_roller.proto
+++ b/recipes/submodule_roller.proto
@@ -64,4 +64,9 @@
 
   // Auto roller module options.
   recipe_modules.fuchsia.auto_roller.Options auto_roller_options = 10;
+
+  // Max number of commits for which authors and reviewers should be CCd.
+  // Default is 10. To disable CCing, don't set the "cc_*_on_rolls" values
+  // above, or set this to a negative value.
+  int32 max_commits_for_ccing = 11;
 }
diff --git a/recipes/submodule_roller.py b/recipes/submodule_roller.py
index 6df7d86..5fff26f 100644
--- a/recipes/submodule_roller.py
+++ b/recipes/submodule_roller.py
@@ -166,26 +166,30 @@
         with api.step.nest('nothing to roll, exiting'):
             return
 
-    cc = set()
     authors = api.roll_util.authors(*rolls.values())
-    if cc_authors_on_rolls:
-        cc.update(authors)
-    if cc_reviewers_on_rolls:
-        cc.update(api.roll_util.reviewers(*rolls.values()))
+    num_commits = sum(len(x.commits) for x in rolls.values())
 
-    def include_cc(email):
-        return api.roll_util.include_cc(
-            email, cc_domains, checkout.gerrit_host()
-        )
+    max_commits_for_ccing = props.max_commits_for_ccing or 10
+    if num_commits <= max_commits_for_ccing:
+        cc = set()
+        if cc_authors_on_rolls:
+            cc.update(authors)
+        if cc_reviewers_on_rolls:
+            cc.update(api.roll_util.reviewers(*rolls.values()))
 
-    # include_cc() writes steps, so we want things sorted before calling it.
-    cc = sorted(set(cc))
-    cc_emails = [x.email for x in cc if include_cc(x)]
+        def include_cc(email):
+            return api.roll_util.include_cc(
+                email, cc_domains, checkout.gerrit_host()
+            )
 
-    if always_cc:
-        props.auto_roller_options.cc_emails.extend(cc_emails)
-    else:
-        props.auto_roller_options.cc_on_failure_emails.extend(cc_emails)
+        # include_cc() writes steps, so we want things sorted before calling it.
+        cc = sorted(set(cc))
+        cc_emails = [x.email for x in cc if include_cc(x)]
+
+        if always_cc:
+            props.auto_roller_options.cc_emails.extend(cc_emails)
+        else:
+            props.auto_roller_options.cc_on_failure_emails.extend(cc_emails)
 
     author_override = None
     with api.step.nest('authors') as pres: