Bug 1275774 - Add notify routes to taskcluster tasks for certain try flags draft
authorBrian Stack <bstack@mozilla.com>
Mon, 26 Sep 2016 10:57:14 -0700
changeset 418516 1add188f671b252a731d13114f93d2910130f4f4
parent 417704 2f10b3e70eb28167ed9ead624a1194f7989c4a16
child 418517 be80dd1454981fe3a15c6f7be80142273ee5c0bd
push id30698
push userbstack@mozilla.com
push dateWed, 28 Sep 2016 16:35:50 +0000
bugs1275774
milestone52.0a1
Bug 1275774 - Add notify routes to taskcluster tasks for certain try flags MozReview-Commit-ID: 4ugUjv0NCZK
taskcluster/taskgraph/target_tasks.py
taskcluster/taskgraph/test/test_target_tasks.py
taskcluster/taskgraph/try_option_syntax.py
--- a/taskcluster/taskgraph/target_tasks.py
+++ b/taskcluster/taskgraph/target_tasks.py
@@ -52,16 +52,27 @@ def target_tasks_try_option_syntax(full_
 
     # If the developer wants test jobs to be rebuilt N times we add that value here
     if int(options.trigger_tests) > 1:
         for l in target_tasks_labels:
             task = full_task_graph[l]
             if 'unittest_suite' in task.attributes:
                 task.attributes['task_duplicates'] = options.trigger_tests
 
+    # Add notifications here as well
+    if options.notifications:
+        for task in full_task_graph:
+            owner = parameters.get('owner')
+            routes = task.task.setdefault('routes', [])
+            if options.notifications == 'all':
+                routes.append("notify.email.{}.on-any".format(owner))
+            elif options.notifications == 'failure':
+                routes.append("notify.email.{}.on-failed".format(owner))
+                routes.append("notify.email.{}.on-exception".format(owner))
+
     return target_tasks_labels
 
 
 @_target_task('default')
 def target_tasks_default(full_task_graph, parameters):
     """Target the tasks which have indicated they should be run on this project
     via the `run_on_projects` attributes."""
     def filter(task):
--- a/taskcluster/taskgraph/test/test_target_tasks.py
+++ b/taskcluster/taskgraph/test/test_target_tasks.py
@@ -13,16 +13,17 @@ from ..taskgraph import TaskGraph
 from .util import TestTask
 from mozunit import main
 
 
 class FakeTryOptionSyntax(object):
 
     def __init__(self, message, task_graph):
         self.trigger_tests = 0
+        self.notifications = None
 
     def task_matches(self, attributes):
         return 'at-at' in attributes
 
 
 class TestTargetTasks(unittest.TestCase):
 
     def test_from_parameters(self):
--- a/taskcluster/taskgraph/try_option_syntax.py
+++ b/taskcluster/taskgraph/try_option_syntax.py
@@ -166,33 +166,34 @@ RIDEALONG_BUILDS = {
         'sm-tsan',
         'sm-asan',
         'sm-msan',
     ],
 }
 
 TEST_CHUNK_SUFFIX = re.compile('(.*)-([0-9]+)$')
 
+
 class TryOptionSyntax(object):
 
     def __init__(self, message, full_task_graph):
         """
         Parse a "try syntax" formatted commit message.  This is the old "-b do -p
         win32 -u all" format.  Aliases are applied to map short names to full
         names.
 
         The resulting object has attributes:
 
         - build_types: a list containing zero or more of 'opt' and 'debug'
         - platforms: a list of selected platform names, or None for all
         - unittests: a list of tests, of the form given below, or None for all
         - jobs: a list of requested job names, or None for all
         - trigger_tests: the number of times tests should be triggered (--rebuild)
         - interactive: true if --interactive
-        - notifications: one of 'none', 'all', 'failure'
+        - notifications: either None if no notifications or one of 'all' or 'failure'
 
         Note that -t is currently completely ignored.
 
         The unittests and talos lists contain dictionaries of the form:
 
         {
             'test': '<suite name>',
             'platforms': [..platform names..], # to limit to only certain platforms
@@ -201,17 +202,17 @@ class TryOptionSyntax(object):
         """
         self.jobs = []
         self.build_types = []
         self.platforms = []
         self.unittests = []
         self.talos = []
         self.trigger_tests = 0
         self.interactive = False
-        self.notifications = 'none'
+        self.notifications = None
 
         # shlex used to ensure we split correctly when giving values to argparse.
         parts = shlex.split(self.escape_whitespace_in_brackets(message))
         try_idx = None
         for idx, part in enumerate(parts):
             if part == TRY_DELIMITER:
                 try_idx = idx
                 break
@@ -224,32 +225,34 @@ class TryOptionSyntax(object):
         parser.add_argument('-b', '--build', dest='build_types')
         parser.add_argument('-p', '--platform', nargs='?',
                             dest='platforms', const='all', default='all')
         parser.add_argument('-u', '--unittests', nargs='?',
                             dest='unittests', const='all', default='all')
         parser.add_argument('-t', '--talos', nargs='?', dest='talos', const='all', default='all')
         parser.add_argument('-i', '--interactive',
                             dest='interactive', action='store_true', default=False)
-        parser.add_argument('-e', '--all-emails', dest='notifications', action='store_const', const='all')
-        parser.add_argument('-f', '--failure-emails', dest='notifications', action='store_const', const='failure')
+        parser.add_argument('-e', '--all-emails',
+                            dest='notifications', action='store_const', const='all')
+        parser.add_argument('-f', '--failure-emails',
+                            dest='notifications', action='store_const', const='failure')
         parser.add_argument('-j', '--job', dest='jobs', action='append')
         # In order to run test jobs multiple times
         parser.add_argument('--rebuild', dest='trigger_tests', type=int, default=1)
         args, _ = parser.parse_known_args(parts[try_idx:])
 
         self.jobs = self.parse_jobs(args.jobs)
         self.build_types = self.parse_build_types(args.build_types)
         self.platforms = self.parse_platforms(args.platforms)
         self.unittests = self.parse_test_option(
             "unittest_try_name", args.unittests, full_task_graph)
         self.talos = self.parse_test_option("talos_try_name", args.talos, full_task_graph)
         self.trigger_tests = args.trigger_tests
         self.interactive = args.interactive
-        self.notifications = args.notifications or self.notifications
+        self.notifications = args.notifications
 
     def parse_jobs(self, jobs_arg):
         if not jobs_arg or jobs_arg == ['all']:
             return None
         expanded = []
         for job in jobs_arg:
             expanded.extend(j.strip() for j in job.split(','))
         return expanded