From bce402d18219c107128f4f6478b89801dbc1f22c Mon Sep 17 00:00:00 2001 From: Brian Stack Date: Wed, 12 Apr 2017 21:01:46 -0700 Subject: [PATCH] Bug 591688 - Notify when decision task fails r=dustin,gps This uses the email provided by mozilla-taskcluster to find who to email about failed decision tasks. It also adds some validation of the try syntax that we've previously ignored. Any platforms or build types specified in try sytax that don't exist in the full task graph will throw an error. MozReview-Commit-ID: JOKkLle7hEe --HG-- extra : rebase_source : 65299c95c60bcb3c6a295b1f8f2f18477c2852db --- .taskcluster.yml | 2 ++ taskcluster/taskgraph/try_option_syntax.py | 30 ++++++++++++++++++---- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/.taskcluster.yml b/.taskcluster.yml index 7676e4235f85..a1a4914339dd 100644 --- a/.taskcluster.yml +++ b/.taskcluster.yml @@ -65,6 +65,8 @@ tasks: - "index.gecko.v2.{{project}}.latest.firefox.decision" - "tc-treeherder.v2.{{project}}.{{revision}}.{{pushlog_id}}" - "tc-treeherder-stage.v2.{{project}}.{{revision}}.{{pushlog_id}}" + - "notify.email.{{owner}}.on-failed" + - "notify.email.{{owner}}.on-exception" payload: env: diff --git a/taskcluster/taskgraph/try_option_syntax.py b/taskcluster/taskgraph/try_option_syntax.py index ce9e6e20647f..5f174b3df3b8 100644 --- a/taskcluster/taskgraph/try_option_syntax.py +++ b/taskcluster/taskgraph/try_option_syntax.py @@ -249,7 +249,7 @@ def parse_message(message): # In order to run test jobs multiple times parser.add_argument('--rebuild', dest='trigger_tests', type=int, default=1) parts = parts[try_idx:] if try_idx is not None else [] - args, _ = parser.parse_known_args(parts[try_idx:]) + args, _ = parser.parse_known_args(parts) return args @@ -306,8 +306,8 @@ class TryOptionSyntax(object): assert args is not None 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.build_types = self.parse_build_types(args.build_types, full_task_graph) + self.platforms = self.parse_platforms(args.platforms, full_task_graph) 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) @@ -329,14 +329,23 @@ class TryOptionSyntax(object): expanded.extend(j.strip() for j in job.split(',')) return expanded - def parse_build_types(self, build_types_arg): + def parse_build_types(self, build_types_arg, full_task_graph): if build_types_arg is None: build_types_arg = [] + build_types = filter(None, [BUILD_TYPE_ALIASES.get(build_type) for build_type in build_types_arg]) + + all_types = set(t.attributes['build_type'] + for t in full_task_graph.tasks.itervalues() + if 'build_type' in t.attributes) + bad_types = set(build_types) - all_types + if bad_types: + raise Exception("Unknown build type(s) [%s] specified for try" % ','.join(bad_types)) + return build_types - def parse_platforms(self, platform_arg): + def parse_platforms(self, platform_arg, full_task_graph): if platform_arg == 'all': return None @@ -348,6 +357,17 @@ class TryOptionSyntax(object): logger.info("platform %s triggers ridealong builds %s" % (build, ', '.join(RIDEALONG_BUILDS[build]))) + test_platforms = set(t.attributes['test_platform'] + for t in full_task_graph.tasks.itervalues() + if 'test_platform' in t.attributes) + build_platforms = set(t.attributes['build_platform'] + for t in full_task_graph.tasks.itervalues() + if 'build_platform' in t.attributes) + all_platforms = test_platforms | build_platforms + bad_platforms = set(results) - all_platforms + if bad_platforms: + raise Exception("Unknown platform(s) [%s] specified for try" % ','.join(bad_platforms)) + return results def parse_test_option(self, attr_name, test_arg, full_task_graph):