Bug 1755481: correct documentation of `nsIClipboard::getData`. r=mccr8
[gecko.git] / taskcluster / gecko_taskgraph / target_tasks.py
blob6817332d144f60a99b39232f1e189590e15aa37a
1 # This Source Code Form is subject to the terms of the Mozilla Public
2 # License, v. 2.0. If a copy of the MPL was not distributed with this
3 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
6 import copy
7 import os
8 import re
10 from redo import retry
11 from taskgraph.parameters import Parameters
13 from gecko_taskgraph import try_option_syntax
14 from gecko_taskgraph.util.attributes import (
15 match_run_on_projects,
16 match_run_on_hg_branches,
18 from gecko_taskgraph.util.platforms import platform_family
19 from gecko_taskgraph.util.taskcluster import find_task_id
21 _target_task_methods = {}
23 # Some tasks show up in the target task set, but are possibly special cases,
24 # uncommon tasks, or tasks running against limited hardware set that they
25 # should only be selectable with --full.
26 UNCOMMON_TRY_TASK_LABELS = [
27 # Platforms and/or Build types
28 r"build-.*-gcp", # Bug 1631990
29 r"mingwclang", # Bug 1631990
30 r"valgrind", # Bug 1631990
31 # Android tasks
32 r"android-geckoview-docs",
33 r"android-hw",
34 # Windows tasks
35 r"windows10-64-ref-hw",
36 r"windows10-aarch64-qr",
37 # Linux tasks
38 r"linux-", # hide all linux32 tasks by default - bug 1599197
39 r"linux1804-32", # hide linux32 tests - bug 1599197
40 # Test tasks
41 r"web-platform-tests.*backlog", # hide wpt jobs that are not implemented yet - bug 1572820
42 r"-ccov",
43 r"-profiling-", # talos/raptor profiling jobs are run too often
44 # Hide shippable versions of tests we have opt versions of because the non-shippable
45 # versions are faster to run. This is mostly perf tests.
46 r"-shippable(?!.*(awsy|browsertime|marionette-headless|mochitest-devtools-chrome-fis|raptor|talos|web-platform-tests-wdspec-headless|mochitest-plain-headless))", # noqa - too long
50 def _target_task(name):
51 def wrap(func):
52 _target_task_methods[name] = func
53 return func
55 return wrap
58 def get_method(method):
59 """Get a target_task_method to pass to a TaskGraphGenerator."""
60 return _target_task_methods[method]
63 def index_exists(index_path, reason=""):
64 print(f"Looking for existing index {index_path} {reason}...")
65 try:
66 task_id = find_task_id(index_path)
67 print(f"Index {index_path} exists: taskId {task_id}")
68 return True
69 except KeyError:
70 print(f"Index {index_path} doesn't exist.")
71 return False
74 def filter_out_shipping_phase(task, parameters):
75 return (
76 # nightly still here because of geckodriver
77 not task.attributes.get("nightly")
78 and task.attributes.get("shipping_phase") in (None, "build")
82 def filter_out_devedition(task, parameters):
83 return not task.attributes.get("shipping_product") == "devedition"
86 def filter_out_cron(task, parameters):
87 """
88 Filter out tasks that run via cron.
89 """
90 return not task.attributes.get("cron")
93 def filter_for_project(task, parameters):
94 """Filter tasks by project. Optionally enable nightlies."""
95 run_on_projects = set(task.attributes.get("run_on_projects", []))
96 return match_run_on_projects(parameters["project"], run_on_projects)
99 def filter_for_hg_branch(task, parameters):
100 """Filter tasks by hg branch.
101 If `run_on_hg_branch` is not defined, then task runs on all branches"""
102 run_on_hg_branches = set(task.attributes.get("run_on_hg_branches", ["all"]))
103 return match_run_on_hg_branches(parameters["hg_branch"], run_on_hg_branches)
106 def filter_on_platforms(task, platforms):
107 """Filter tasks on the given platform"""
108 platform = task.attributes.get("build_platform")
109 return platform in platforms
112 def filter_by_uncommon_try_tasks(task, optional_filters=None):
113 """Filters tasks that should not be commonly run on try.
115 Args:
116 task (str): String representing the task name.
117 optional_filters (list, optional):
118 Additional filters to apply to task filtering.
120 Returns:
121 (Boolean): True if task does not match any known filters.
122 False otherwise.
124 filters = UNCOMMON_TRY_TASK_LABELS
125 if optional_filters:
126 filters = copy.deepcopy(filters)
127 filters.extend(optional_filters)
129 return not any(re.search(pattern, task) for pattern in UNCOMMON_TRY_TASK_LABELS)
132 def filter_by_regex(task_label, regexes, mode="include"):
133 """Filters tasks according to a list of pre-compiled reguar expressions.
135 If mode is "include", a task label must match any regex to pass.
136 If it is "exclude", a task label must _not_ match any regex to pass.
138 if not regexes:
139 return True
141 assert mode in ["include", "exclude"]
143 any_match = any(r.search(task_label) for r in regexes)
144 if any_match:
145 return mode == "include"
146 return mode != "include"
149 def filter_release_tasks(task, parameters):
150 platform = task.attributes.get("build_platform")
151 if platform in (
152 "linux",
153 "linux64",
154 "macosx64",
155 "win32",
156 "win64",
157 "win64-aarch64",
159 if task.attributes["kind"] == "l10n":
160 # This is on-change l10n
161 return True
162 if (
163 task.attributes["build_type"] == "opt"
164 and task.attributes.get("unittest_suite") != "talos"
165 and task.attributes.get("unittest_suite") != "raptor"
167 return False
169 if task.attributes.get("shipping_phase") not in (None, "build"):
170 return False
172 """ No debug on beta/release, keep on ESR with 4 week cycles, beta/release
173 will not be too different from central, but ESR will live for a long time.
175 From June 2019 -> June 2020, we found 1 unique regression on ESR debug
176 and 5 unique regressions on beta/release. Keeping spidermonkey and linux
177 debug finds all but 1 unique regressions (windows found on try) for beta/release.
179 if parameters["release_type"].startswith("esr"):
180 return True
182 # code below here is intended to reduce beta/release debug tasks
183 build_type = task.attributes.get("build_type", "")
184 build_platform = task.attributes.get("build_platform", "")
185 test_platform = task.attributes.get("test_platform", "")
186 if task.kind == "hazard" or "toolchain" in build_platform:
187 # keep hazard and toolchain builds around
188 return True
190 if build_type == "debug":
191 if "linux" not in build_platform:
192 # filter out windows/mac/android
193 return False
194 elif task.kind not in ["spidermonkey"] and "-qr" in test_platform:
195 # filter out linux-qr tests, leave spidermonkey
196 return False
197 elif "64" not in build_platform:
198 # filter out linux32 builds
199 return False
201 # webrender-android-*-debug doesn't have attributes to find 'debug', using task.label.
202 if task.kind == "webrender" and "debug" in task.label:
203 return False
204 return True
207 def filter_out_missing_signoffs(task, parameters):
208 for signoff in parameters["required_signoffs"]:
209 if signoff not in parameters["signoff_urls"] and signoff in task.attributes.get(
210 "required_signoffs", []
212 return False
213 return True
216 def filter_tests_without_manifests(task, parameters):
217 """Remove test tasks that have an empty 'test_manifests' attribute.
219 This situation can arise when the test loader (e.g bugbug) decided there
220 weren't any important manifests to run for the given push. We filter tasks
221 out here rather than in the transforms so that the full task graph is still
222 aware that the task exists (which is needed by the backfill action).
224 if (
225 task.kind == "test"
226 and "test_manifests" in task.attributes
227 and not task.attributes["test_manifests"]
229 return False
230 return True
233 def standard_filter(task, parameters):
234 return all(
235 filter_func(task, parameters)
236 for filter_func in (
237 filter_out_cron,
238 filter_for_project,
239 filter_for_hg_branch,
240 filter_tests_without_manifests,
245 def accept_raptor_android_build(platform):
246 """Helper function for selecting the correct android raptor builds."""
247 if "android" not in platform:
248 return False
249 if "shippable" not in platform:
250 return False
251 if "p2" in platform and "aarch64" in platform:
252 return True
253 if "g5" in platform:
254 return True
257 def filter_unsupported_artifact_builds(task, parameters):
258 try_config = parameters.get("try_task_config", {})
259 if not try_config.get("use-artifact-builds", False):
260 return True
262 supports_artifact_builds = task.attributes.get("supports-artifact-builds", True)
263 return supports_artifact_builds
266 def filter_out_shippable(task):
267 return not task.attributes.get("shippable", False)
270 def _try_task_config(full_task_graph, parameters, graph_config):
271 requested_tasks = parameters["try_task_config"]["tasks"]
272 return list(set(requested_tasks) & full_task_graph.graph.nodes)
275 def _try_option_syntax(full_task_graph, parameters, graph_config):
276 """Generate a list of target tasks based on try syntax in
277 parameters['message'] and, for context, the full task graph."""
278 options = try_option_syntax.TryOptionSyntax(
279 parameters, full_task_graph, graph_config
281 target_tasks_labels = [
282 t.label
283 for t in full_task_graph.tasks.values()
284 if options.task_matches(t)
285 and filter_by_uncommon_try_tasks(t.label)
286 and filter_unsupported_artifact_builds(t, parameters)
289 attributes = {
290 k: getattr(options, k)
291 for k in [
292 "no_retry",
293 "tag",
297 for l in target_tasks_labels:
298 task = full_task_graph[l]
299 if "unittest_suite" in task.attributes:
300 task.attributes["task_duplicates"] = options.trigger_tests
302 for l in target_tasks_labels:
303 task = full_task_graph[l]
304 # If the developer wants test jobs to be rebuilt N times we add that value here
305 if options.trigger_tests > 1 and "unittest_suite" in task.attributes:
306 task.attributes["task_duplicates"] = options.trigger_tests
308 # If the developer wants test talos jobs to be rebuilt N times we add that value here
309 if (
310 options.talos_trigger_tests > 1
311 and task.attributes.get("unittest_suite") == "talos"
313 task.attributes["task_duplicates"] = options.talos_trigger_tests
315 # If the developer wants test raptor jobs to be rebuilt N times we add that value here
316 if (
317 options.raptor_trigger_tests
318 and options.raptor_trigger_tests > 1
319 and task.attributes.get("unittest_suite") == "raptor"
321 task.attributes["task_duplicates"] = options.raptor_trigger_tests
323 task.attributes.update(attributes)
325 # Add notifications here as well
326 if options.notifications:
327 for task in full_task_graph:
328 owner = parameters.get("owner")
329 routes = task.task.setdefault("routes", [])
330 if options.notifications == "all":
331 routes.append(f"notify.email.{owner}.on-any")
332 elif options.notifications == "failure":
333 routes.append(f"notify.email.{owner}.on-failed")
334 routes.append(f"notify.email.{owner}.on-exception")
336 return target_tasks_labels
339 @_target_task("try_tasks")
340 def target_tasks_try(full_task_graph, parameters, graph_config):
341 try_mode = parameters["try_mode"]
342 if try_mode == "try_task_config":
343 return _try_task_config(full_task_graph, parameters, graph_config)
344 elif try_mode == "try_option_syntax":
345 return _try_option_syntax(full_task_graph, parameters, graph_config)
346 else:
347 # With no try mode, we schedule nothing, allowing the user to add tasks
348 # later via treeherder.
349 return []
352 @_target_task("try_select_tasks")
353 def target_tasks_try_select(full_task_graph, parameters, graph_config):
354 tasks = target_tasks_try_select_uncommon(full_task_graph, parameters, graph_config)
355 return [l for l in tasks if filter_by_uncommon_try_tasks(l)]
358 @_target_task("try_select_tasks_uncommon")
359 def target_tasks_try_select_uncommon(full_task_graph, parameters, graph_config):
360 from gecko_taskgraph.decision import PER_PROJECT_PARAMETERS
362 projects = ("autoland", "mozilla-central")
363 if parameters["project"] not in projects:
364 projects = (parameters["project"],)
366 tasks = set()
367 for project in projects:
368 params = dict(parameters)
369 params["project"] = project
370 parameters = Parameters(**params)
372 try:
373 target_tasks_method = PER_PROJECT_PARAMETERS[project]["target_tasks_method"]
374 except KeyError:
375 target_tasks_method = "default"
377 tasks.update(
378 get_method(target_tasks_method)(full_task_graph, parameters, graph_config)
381 return sorted(tasks)
384 @_target_task("try_auto")
385 def target_tasks_try_auto(full_task_graph, parameters, graph_config):
386 """Target the tasks which have indicated they should be run on autoland
387 (rather than try) via the `run_on_projects` attributes.
389 Should do the same thing as the `default` target tasks method.
391 params = dict(parameters)
392 params["project"] = "autoland"
393 parameters = Parameters(**params)
395 regex_filters = parameters["try_task_config"].get("tasks-regex")
396 include_regexes = exclude_regexes = []
397 if regex_filters:
398 include_regexes = [re.compile(r) for r in regex_filters.get("include", [])]
399 exclude_regexes = [re.compile(r) for r in regex_filters.get("exclude", [])]
401 return [
403 for l, t in full_task_graph.tasks.items()
404 if standard_filter(t, parameters)
405 and filter_out_shipping_phase(t, parameters)
406 and filter_out_devedition(t, parameters)
407 and filter_by_uncommon_try_tasks(t.label)
408 and filter_by_regex(t.label, include_regexes, mode="include")
409 and filter_by_regex(t.label, exclude_regexes, mode="exclude")
410 and filter_unsupported_artifact_builds(t, parameters)
411 and filter_out_shippable(t)
415 @_target_task("default")
416 def target_tasks_default(full_task_graph, parameters, graph_config):
417 """Target the tasks which have indicated they should be run on this project
418 via the `run_on_projects` attributes."""
419 return [
421 for l, t in full_task_graph.tasks.items()
422 if standard_filter(t, parameters)
423 and filter_out_shipping_phase(t, parameters)
424 and filter_out_devedition(t, parameters)
428 @_target_task("autoland_tasks")
429 def target_tasks_autoland(full_task_graph, parameters, graph_config):
430 """In addition to doing the filtering by project that the 'default'
431 filter does, also remove any tests running against shippable builds
432 for non-backstop pushes."""
433 filtered_for_project = target_tasks_default(
434 full_task_graph, parameters, graph_config
437 def filter(task):
438 if task.kind != "test":
439 return True
441 if parameters["backstop"]:
442 return True
444 build_type = task.attributes.get("build_type")
446 if not build_type or build_type != "opt" or filter_out_shippable(task):
447 return True
449 return False
451 return [l for l in filtered_for_project if filter(full_task_graph[l])]
454 @_target_task("mozilla_central_tasks")
455 def target_tasks_mozilla_central(full_task_graph, parameters, graph_config):
456 """In addition to doing the filtering by project that the 'default'
457 filter does, also remove any tests running against regular (aka not shippable,
458 asan, etc.) opt builds."""
459 filtered_for_project = target_tasks_default(
460 full_task_graph, parameters, graph_config
463 def filter(task):
464 if task.kind != "test":
465 return True
467 build_platform = task.attributes.get("build_platform")
468 build_type = task.attributes.get("build_type")
469 shippable = task.attributes.get("shippable", False)
471 if not build_platform or not build_type:
472 return True
474 family = platform_family(build_platform)
475 # We need to know whether this test is against a "regular" opt build
476 # (which is to say, not shippable, asan, tsan, or any other opt build
477 # with other properties). There's no positive test for this, so we have to
478 # do it somewhat hackily. Android doesn't have variants other than shippable
479 # so it is pretty straightforward to check for. Other platforms have many
480 # variants, but none of the regular opt builds we're looking for have a "-"
481 # in their platform name, so this works (for now).
482 is_regular_opt = (
483 family == "android" and not shippable
484 ) or "-" not in build_platform
486 if build_type != "opt" or not is_regular_opt:
487 return True
489 return False
491 return [l for l in filtered_for_project if filter(full_task_graph[l])]
494 @_target_task("graphics_tasks")
495 def target_tasks_graphics(full_task_graph, parameters, graph_config):
496 """In addition to doing the filtering by project that the 'default'
497 filter does, also remove artifact builds because we have csets on
498 the graphics branch that aren't on the candidate branches of artifact
499 builds"""
500 filtered_for_project = target_tasks_default(
501 full_task_graph, parameters, graph_config
504 def filter(task):
505 if task.attributes["kind"] == "artifact-build":
506 return False
507 return True
509 return [l for l in filtered_for_project if filter(full_task_graph[l])]
512 @_target_task("mozilla_beta_tasks")
513 def target_tasks_mozilla_beta(full_task_graph, parameters, graph_config):
514 """Select the set of tasks required for a promotable beta or release build
515 of desktop, plus android CI. The candidates build process involves a pipeline
516 of builds and signing, but does not include beetmover or balrog jobs."""
518 return [
520 for l, t in full_task_graph.tasks.items()
521 if filter_release_tasks(t, parameters) and standard_filter(t, parameters)
525 @_target_task("mozilla_release_tasks")
526 def target_tasks_mozilla_release(full_task_graph, parameters, graph_config):
527 """Select the set of tasks required for a promotable beta or release build
528 of desktop, plus android CI. The candidates build process involves a pipeline
529 of builds and signing, but does not include beetmover or balrog jobs."""
531 return [
533 for l, t in full_task_graph.tasks.items()
534 if filter_release_tasks(t, parameters) and standard_filter(t, parameters)
538 @_target_task("mozilla_esr91_tasks")
539 def target_tasks_mozilla_esr91(full_task_graph, parameters, graph_config):
540 """Select the set of tasks required for a promotable beta or release build
541 of desktop, without android CI. The candidates build process involves a pipeline
542 of builds and signing, but does not include beetmover or balrog jobs."""
544 def filter(task):
545 if not filter_release_tasks(task, parameters):
546 return False
548 if not standard_filter(task, parameters):
549 return False
551 platform = task.attributes.get("build_platform")
553 # Android is not built on esr91.
554 if platform and "android" in platform:
555 return False
557 return True
559 return [l for l, t in full_task_graph.tasks.items() if filter(t)]
562 @_target_task("promote_desktop")
563 def target_tasks_promote_desktop(full_task_graph, parameters, graph_config):
564 """Select the superset of tasks required to promote a beta or release build
565 of a desktop product. This should include all non-android
566 mozilla_{beta,release} tasks, plus l10n, beetmover, balrog, etc."""
568 def filter(task):
569 if task.attributes.get("shipping_product") != parameters["release_product"]:
570 return False
572 # 'secondary' balrog/update verify/final verify tasks only run for RCs
573 if parameters.get("release_type") != "release-rc":
574 if "secondary" in task.kind:
575 return False
577 if not filter_out_missing_signoffs(task, parameters):
578 return False
580 if task.attributes.get("shipping_phase") == "promote":
581 return True
583 return [l for l, t in full_task_graph.tasks.items() if filter(t)]
586 def is_geckoview(task, parameters):
587 return (
588 task.attributes.get("shipping_product") == "fennec"
589 and task.kind in ("beetmover-geckoview", "upload-symbols")
590 and parameters["release_product"] == "firefox"
594 @_target_task("push_desktop")
595 def target_tasks_push_desktop(full_task_graph, parameters, graph_config):
596 """Select the set of tasks required to push a build of desktop to cdns.
597 Previous build deps will be optimized out via action task."""
598 filtered_for_candidates = target_tasks_promote_desktop(
599 full_task_graph,
600 parameters,
601 graph_config,
604 def filter(task):
605 if not filter_out_missing_signoffs(task, parameters):
606 return False
607 # Include promotion tasks; these will be optimized out
608 if task.label in filtered_for_candidates:
609 return True
610 # XXX: Bug 1612540 - include beetmover jobs for publishing geckoview, along
611 # with the regular Firefox (not Devedition!) releases so that they are at sync
612 if "mozilla-esr" not in parameters["project"] and is_geckoview(
613 task, parameters
615 return True
617 if (
618 task.attributes.get("shipping_product") == parameters["release_product"]
619 and task.attributes.get("shipping_phase") == "push"
621 return True
623 return [l for l, t in full_task_graph.tasks.items() if filter(t)]
626 @_target_task("ship_desktop")
627 def target_tasks_ship_desktop(full_task_graph, parameters, graph_config):
628 """Select the set of tasks required to ship desktop.
629 Previous build deps will be optimized out via action task."""
630 is_rc = parameters.get("release_type") == "release-rc"
631 if is_rc:
632 # ship_firefox_rc runs after `promote` rather than `push`; include
633 # all promote tasks.
634 filtered_for_candidates = target_tasks_promote_desktop(
635 full_task_graph,
636 parameters,
637 graph_config,
639 else:
640 # ship_firefox runs after `push`; include all push tasks.
641 filtered_for_candidates = target_tasks_push_desktop(
642 full_task_graph,
643 parameters,
644 graph_config,
647 def filter(task):
648 if not filter_out_missing_signoffs(task, parameters):
649 return False
650 # Include promotion tasks; these will be optimized out
651 if task.label in filtered_for_candidates:
652 return True
654 # XXX: Bug 1619603 - geckoview also ships alongside Firefox RC
655 if is_geckoview(task, parameters) and is_rc:
656 return True
658 if (
659 task.attributes.get("shipping_product") != parameters["release_product"]
660 or task.attributes.get("shipping_phase") != "ship"
662 return False
664 if "secondary" in task.kind:
665 return is_rc
666 else:
667 return not is_rc
669 return [l for l, t in full_task_graph.tasks.items() if filter(t)]
672 @_target_task("pine_tasks")
673 def target_tasks_pine(full_task_graph, parameters, graph_config):
674 """Bug 1339179 - no mobile automation needed on pine"""
676 def filter(task):
677 platform = task.attributes.get("build_platform")
678 # disable mobile jobs
679 if str(platform).startswith("android"):
680 return False
681 # disable asan
682 if platform == "linux64-asan":
683 return False
684 # disable non-pine and tasks with a shipping phase
685 if standard_filter(task, parameters) or filter_out_shipping_phase(
686 task, parameters
688 return True
690 return [l for l, t in full_task_graph.tasks.items() if filter(t)]
693 @_target_task("kaios_tasks")
694 def target_tasks_kaios(full_task_graph, parameters, graph_config):
695 """The set of tasks to run for kaios integration"""
697 def filter(task):
698 # We disable everything in central, and adjust downstream.
699 return False
701 return [l for l, t in full_task_graph.tasks.items() if filter(t)]
704 @_target_task("ship_geckoview")
705 def target_tasks_ship_geckoview(full_task_graph, parameters, graph_config):
706 """Select the set of tasks required to ship geckoview nightly. The
707 nightly build process involves a pipeline of builds and an upload to
708 maven.mozilla.org."""
709 index_path = (
710 f"{graph_config['trust-domain']}.v2.{parameters['project']}.revision."
711 f"{parameters['head_rev']}.taskgraph.decision-ship-geckoview"
713 if os.environ.get("MOZ_AUTOMATION") and retry(
714 index_exists,
715 args=(index_path,),
716 kwargs={
717 "reason": "to avoid triggering multiple nightlies off the same revision",
720 return []
722 def filter(task):
723 # XXX Starting 69, we don't ship Fennec Nightly anymore. We just want geckoview to be
724 # uploaded
725 return task.attributes.get("shipping_product") == "fennec" and task.kind in (
726 "beetmover-geckoview",
727 "upload-symbols",
730 return [l for l, t in full_task_graph.tasks.items() if filter(t)]
733 @_target_task("general_perf_testing")
734 def target_tasks_general_perf_testing(full_task_graph, parameters, graph_config):
736 Select tasks required for running performance tests 3 times a week.
739 def filter(task):
740 platform = task.attributes.get("test_platform")
741 attributes = task.attributes
742 vismet = attributes.get("kind") == "visual-metrics-dep"
743 if attributes.get("unittest_suite") != "raptor" and not vismet:
744 return False
746 try_name = attributes.get("raptor_try_name")
747 if vismet:
748 # Visual metric tasks are configured a bit differently
749 platform = task.task.get("extra").get("treeherder-platform")
750 try_name = task.label
752 # Completely ignore all non-shippable platforms
753 if "shippable" not in platform:
754 return False
756 # ignore all windows 7 perf jobs scheduled automatically
757 if "windows7" in platform or "windows10-32" in platform:
758 return False
760 # Desktop selection
761 if "android" not in platform:
762 # Select some browsertime tasks as desktop smoke-tests
763 if "browsertime" in try_name:
764 if "chrome" in try_name:
765 if "tp6" in try_name and "macosx1014" in platform:
766 return False
767 return True
768 if "chromium" in try_name:
769 if "tp6" in try_name and "macosx1014" in platform:
770 return False
771 return True
772 if "-live" in try_name:
773 return True
774 if "-fis" in try_name:
775 return False
776 if "linux" in platform:
777 if "speedometer" in try_name:
778 return True
779 else:
780 # Don't run tp6 raptor tests
781 if "tp6" in try_name:
782 return False
783 # Android selection
784 elif accept_raptor_android_build(platform):
785 # Ignore all fennec tests here, we run those weekly
786 if "fennec" in try_name:
787 return False
788 # Only run webrender tests
789 if "chrome-m" not in try_name and "-qr" not in platform:
790 return False
791 # Select live site tests
792 if "-live" in try_name:
793 return True
794 # Select fenix resource usage tests
795 if "fenix" in try_name:
796 if "-power" in try_name:
797 return True
798 # Select geckoview resource usage tests
799 if "geckoview" in try_name:
800 # Run cpu+memory, and power tests
801 cpu_n_memory_task = "-cpu" in try_name and "-memory" in try_name
802 power_task = "-power" in try_name
803 # Ignore cpu+memory+power tests
804 if power_task and cpu_n_memory_task:
805 return False
806 if cpu_n_memory_task:
807 if "-speedometer-" in try_name:
808 return True
809 if "-scn" in try_name and "-idle" in try_name:
810 return True
811 if power_task:
812 return "browsertime" in try_name
813 # Select browsertime-specific tests
814 if "browsertime" in try_name:
815 if "speedometer" in try_name:
816 return True
817 return False
819 return [l for l, t in full_task_graph.tasks.items() if filter(t)]
822 def make_desktop_nightly_filter(platforms):
823 """Returns a filter that gets all nightly tasks on the given platform."""
825 def filter(task, parameters):
826 return all(
828 filter_on_platforms(task, platforms),
829 filter_for_project(task, parameters),
830 task.attributes.get("shippable", False),
831 # Tests and nightly only builds don't have `shipping_product` set
832 task.attributes.get("shipping_product")
833 in {None, "firefox", "thunderbird"},
834 task.kind not in {"l10n"}, # no on-change l10n
838 return filter
841 @_target_task("nightly_linux")
842 def target_tasks_nightly_linux(full_task_graph, parameters, graph_config):
843 """Select the set of tasks required for a nightly build of linux. The
844 nightly build process involves a pipeline of builds, signing,
845 and, eventually, uploading the tasks to balrog."""
846 filter = make_desktop_nightly_filter({"linux64-shippable", "linux-shippable"})
847 return [l for l, t in full_task_graph.tasks.items() if filter(t, parameters)]
850 @_target_task("nightly_macosx")
851 def target_tasks_nightly_macosx(full_task_graph, parameters, graph_config):
852 """Select the set of tasks required for a nightly build of macosx. The
853 nightly build process involves a pipeline of builds, signing,
854 and, eventually, uploading the tasks to balrog."""
855 filter = make_desktop_nightly_filter({"macosx64-shippable"})
856 return [l for l, t in full_task_graph.tasks.items() if filter(t, parameters)]
859 @_target_task("nightly_win32")
860 def target_tasks_nightly_win32(full_task_graph, parameters, graph_config):
861 """Select the set of tasks required for a nightly build of win32 and win64.
862 The nightly build process involves a pipeline of builds, signing,
863 and, eventually, uploading the tasks to balrog."""
864 filter = make_desktop_nightly_filter({"win32-shippable"})
865 return [l for l, t in full_task_graph.tasks.items() if filter(t, parameters)]
868 @_target_task("nightly_win64")
869 def target_tasks_nightly_win64(full_task_graph, parameters, graph_config):
870 """Select the set of tasks required for a nightly build of win32 and win64.
871 The nightly build process involves a pipeline of builds, signing,
872 and, eventually, uploading the tasks to balrog."""
873 filter = make_desktop_nightly_filter({"win64-shippable"})
874 return [l for l, t in full_task_graph.tasks.items() if filter(t, parameters)]
877 @_target_task("nightly_win64_aarch64")
878 def target_tasks_nightly_win64_aarch64(full_task_graph, parameters, graph_config):
879 """Select the set of tasks required for a nightly build of win32 and win64.
880 The nightly build process involves a pipeline of builds, signing,
881 and, eventually, uploading the tasks to balrog."""
882 filter = make_desktop_nightly_filter({"win64-aarch64-shippable"})
883 return [l for l, t in full_task_graph.tasks.items() if filter(t, parameters)]
886 @_target_task("nightly_asan")
887 def target_tasks_nightly_asan(full_task_graph, parameters, graph_config):
888 """Select the set of tasks required for a nightly build of asan. The
889 nightly build process involves a pipeline of builds, signing,
890 and, eventually, uploading the tasks to balrog."""
891 filter = make_desktop_nightly_filter(
892 {"linux64-asan-reporter-shippable", "win64-asan-reporter-shippable"}
894 return [l for l, t in full_task_graph.tasks.items() if filter(t, parameters)]
897 @_target_task("daily_releases")
898 def target_tasks_daily_releases(full_task_graph, parameters, graph_config):
899 """Select the set of tasks required to identify if we should release.
900 If we determine that we should the task will communicate to ship-it to
901 schedule the release itself."""
903 def filter(task):
904 return task.kind in ["maybe-release"]
906 return [l for l, t in full_task_graph.tasks.items() if filter(t)]
909 @_target_task("nightly_desktop")
910 def target_tasks_nightly_desktop(full_task_graph, parameters, graph_config):
911 """Select the set of tasks required for a nightly build of linux, mac,
912 windows."""
913 index_path = (
914 f"{graph_config['trust-domain']}.v2.{parameters['project']}.revision."
915 f"{parameters['head_rev']}.taskgraph.decision-nightly-desktop"
917 if os.environ.get("MOZ_AUTOMATION") and retry(
918 index_exists,
919 args=(index_path,),
920 kwargs={
921 "reason": "to avoid triggering multiple nightlies off the same revision",
924 return []
926 # Tasks that aren't platform specific
927 release_filter = make_desktop_nightly_filter({None})
928 release_tasks = [
929 l for l, t in full_task_graph.tasks.items() if release_filter(t, parameters)
931 # Avoid duplicate tasks.
932 return list(
933 set(target_tasks_nightly_win32(full_task_graph, parameters, graph_config))
934 | set(target_tasks_nightly_win64(full_task_graph, parameters, graph_config))
935 | set(
936 target_tasks_nightly_win64_aarch64(
937 full_task_graph, parameters, graph_config
940 | set(target_tasks_nightly_macosx(full_task_graph, parameters, graph_config))
941 | set(target_tasks_nightly_linux(full_task_graph, parameters, graph_config))
942 | set(target_tasks_nightly_asan(full_task_graph, parameters, graph_config))
943 | set(release_tasks)
947 # Run Searchfox analysis once daily.
948 @_target_task("searchfox_index")
949 def target_tasks_searchfox(full_task_graph, parameters, graph_config):
950 """Select tasks required for indexing Firefox for Searchfox web site each day"""
951 return [
952 "searchfox-linux64-searchfox/debug",
953 "searchfox-macosx64-searchfox/debug",
954 "searchfox-win64-searchfox/debug",
955 "searchfox-android-armv7-searchfox/debug",
956 "source-test-file-metadata-bugzilla-components",
957 "source-test-file-metadata-test-info-all",
958 "source-test-wpt-metadata-summary",
962 # Run build linux64-plain-clang-trunk/opt on mozilla-central/beta with perf tests
963 @_target_task("linux64_clang_trunk_perf")
964 def target_tasks_build_linux64_clang_trunk_perf(
965 full_task_graph, parameters, graph_config
967 """Select tasks required to run perf test on linux64 build with clang trunk"""
969 # Only keep tasks generated from platform `linux1804-64-clang-trunk-qr/opt`
970 def filter(task_label):
971 if "linux1804-64-clang-trunk-qr/opt" in task_label:
972 return True
973 return False
975 return [l for l, t in full_task_graph.tasks.items() if filter(t.label)]
978 # Run Updatebot's cron job 4 times daily.
979 @_target_task("updatebot_cron")
980 def target_tasks_updatebot_cron(full_task_graph, parameters, graph_config):
981 """Select tasks required to run Updatebot's cron job"""
982 return ["updatebot-cron"]
985 @_target_task("customv8_update")
986 def target_tasks_customv8_update(full_task_graph, parameters, graph_config):
987 """Select tasks required for building latest d8/v8 version."""
988 return ["toolchain-linux64-custom-v8"]
991 @_target_task("chromium_update")
992 def target_tasks_chromium_update(full_task_graph, parameters, graph_config):
993 """Select tasks required for building latest chromium versions."""
994 return [
995 "fetch-linux64-chromium",
996 "fetch-win32-chromium",
997 "fetch-win64-chromium",
998 "fetch-mac-chromium",
1002 @_target_task("file_update")
1003 def target_tasks_file_update(full_task_graph, parameters, graph_config):
1004 """Select the set of tasks required to perform nightly in-tree file updates"""
1006 def filter(task):
1007 # For now any task in the repo-update kind is ok
1008 return task.kind in ["repo-update"]
1010 return [l for l, t in full_task_graph.tasks.items() if filter(t)]
1013 @_target_task("l10n_bump")
1014 def target_tasks_l10n_bump(full_task_graph, parameters, graph_config):
1015 """Select the set of tasks required to perform l10n bumping."""
1017 def filter(task):
1018 # For now any task in the repo-update kind is ok
1019 return task.kind in ["l10n-bump"]
1021 return [l for l, t in full_task_graph.tasks.items() if filter(t)]
1024 @_target_task("merge_automation")
1025 def target_tasks_merge_automation(full_task_graph, parameters, graph_config):
1026 """Select the set of tasks required to perform repository merges."""
1028 def filter(task):
1029 # For now any task in the repo-update kind is ok
1030 return task.kind in ["merge-automation"]
1032 return [l for l, t in full_task_graph.tasks.items() if filter(t)]
1035 @_target_task("scriptworker_canary")
1036 def target_tasks_scriptworker_canary(full_task_graph, parameters, graph_config):
1037 """Select the set of tasks required to run scriptworker canaries."""
1039 def filter(task):
1040 # For now any task in the repo-update kind is ok
1041 return task.kind in ["scriptworker-canary"]
1043 return [l for l, t in full_task_graph.tasks.items() if filter(t)]
1046 @_target_task("cron_bouncer_check")
1047 def target_tasks_bouncer_check(full_task_graph, parameters, graph_config):
1048 """Select the set of tasks required to perform bouncer version verification."""
1050 def filter(task):
1051 if not filter_for_project(task, parameters):
1052 return False
1053 # For now any task in the repo-update kind is ok
1054 return task.kind in ["cron-bouncer-check"]
1056 return [l for l, t in full_task_graph.tasks.items() if filter(t)]
1059 @_target_task("staging_release_builds")
1060 def target_tasks_staging_release(full_task_graph, parameters, graph_config):
1062 Select all builds that are part of releases.
1065 def filter(task):
1066 if not task.attributes.get("shipping_product"):
1067 return False
1068 if parameters["release_type"].startswith(
1069 "esr"
1070 ) and "android" in task.attributes.get("build_platform", ""):
1071 return False
1072 if parameters["release_type"] != "beta" and "devedition" in task.attributes.get(
1073 "build_platform", ""
1075 return False
1076 if task.attributes.get("shipping_phase") == "build":
1077 return True
1078 return False
1080 return [l for l, t in full_task_graph.tasks.items() if filter(t)]
1083 @_target_task("release_simulation")
1084 def target_tasks_release_simulation(full_task_graph, parameters, graph_config):
1086 Select builds that would run on push on a release branch.
1088 project_by_release = {
1089 "nightly": "mozilla-central",
1090 "beta": "mozilla-beta",
1091 "release": "mozilla-release",
1092 "esr91": "mozilla-esr91",
1094 target_project = project_by_release.get(parameters["release_type"])
1095 if target_project is None:
1096 raise Exception("Unknown or unspecified release type in simulation run.")
1098 def filter_for_target_project(task):
1099 """Filter tasks by project. Optionally enable nightlies."""
1100 run_on_projects = set(task.attributes.get("run_on_projects", []))
1101 return match_run_on_projects(target_project, run_on_projects)
1103 def filter_out_android_on_esr(task):
1104 if parameters["release_type"].startswith(
1105 "esr"
1106 ) and "android" in task.attributes.get("build_platform", ""):
1107 return False
1108 return True
1110 return [
1112 for l, t in full_task_graph.tasks.items()
1113 if filter_release_tasks(t, parameters)
1114 and filter_out_cron(t, parameters)
1115 and filter_for_target_project(t)
1116 and filter_out_android_on_esr(t)
1120 @_target_task("codereview")
1121 def target_tasks_codereview(full_task_graph, parameters, graph_config):
1122 """Select all code review tasks needed to produce a report"""
1124 def filter(task):
1125 # Ending tasks
1126 if task.kind in ["code-review"]:
1127 return True
1129 # Analyzer tasks
1130 if task.attributes.get("code-review") is True:
1131 return True
1133 return False
1135 return [l for l, t in full_task_graph.tasks.items() if filter(t)]
1138 @_target_task("nothing")
1139 def target_tasks_nothing(full_task_graph, parameters, graph_config):
1140 """Select nothing, for DONTBUILD pushes"""
1141 return []
1144 @_target_task("raptor_tp6m")
1145 def target_tasks_raptor_tp6m(full_task_graph, parameters, graph_config):
1147 Select tasks required for running raptor cold page-load tests on fenix and refbrow
1150 def filter(task):
1151 platform = task.attributes.get("build_platform")
1152 attributes = task.attributes
1154 if platform and "android" not in platform:
1155 return False
1156 if attributes.get("unittest_suite") != "raptor":
1157 return False
1158 try_name = attributes.get("raptor_try_name")
1159 if "-cold" in try_name and "shippable" in platform:
1160 # Get browsertime amazon smoke tests
1161 if (
1162 "browsertime" in try_name
1163 and "amazon" in try_name
1164 and "search" not in try_name
1165 and "fenix" in try_name
1167 return True
1169 return [l for l, t in full_task_graph.tasks.items() if filter(t)]
1172 @_target_task("perftest_s7")
1173 def target_tasks_perftest_s7(full_task_graph, parameters, graph_config):
1175 Select tasks required for running raptor page-load tests on geckoview against S7
1178 def filter(task):
1179 build_platform = task.attributes.get("build_platform", "")
1180 test_platform = task.attributes.get("test_platform", "")
1181 attributes = task.attributes
1182 vismet = attributes.get("kind") == "visual-metrics-dep"
1183 try_name = attributes.get("raptor_try_name")
1185 if vismet:
1186 # Visual metric tasks are configured a bit differently
1187 test_platform = task.task.get("extra").get("treeherder-platform")
1188 try_name = task.label
1190 if build_platform and "android" not in build_platform:
1191 return False
1192 if attributes.get("unittest_suite") != "raptor" and not vismet:
1193 return False
1194 if "s7" in test_platform and "-qr" in test_platform:
1195 if "geckoview" in try_name and (
1196 "unity-webgl" in try_name
1197 or "speedometer" in try_name
1198 or "tp6m-essential" in try_name
1200 if "power" in try_name:
1201 return False
1202 else:
1203 return True
1205 return [l for l, t in full_task_graph.tasks.items() if filter(t)]
1208 @_target_task("condprof")
1209 def target_tasks_condprof(full_task_graph, parameters, graph_config):
1211 Select tasks required for building conditioned profiles.
1213 for name, task in full_task_graph.tasks.items():
1214 if task.kind == "condprof":
1215 yield name
1218 @_target_task("system_symbols")
1219 def target_tasks_system_symbols(full_task_graph, parameters, graph_config):
1221 Select tasks for scraping and uploading system symbols.
1223 for name, task in full_task_graph.tasks.items():
1224 if task.kind in ["system-symbols", "system-symbols-upload"]:
1225 yield name
1228 @_target_task("perftest")
1229 def target_tasks_perftest(full_task_graph, parameters, graph_config):
1231 Select perftest tasks we want to run daily
1233 for name, task in full_task_graph.tasks.items():
1234 if task.kind != "perftest":
1235 continue
1236 if task.attributes.get("cron", False):
1237 yield name
1240 @_target_task("perftest-on-autoland")
1241 def target_tasks_perftest_autoland(full_task_graph, parameters, graph_config):
1243 Select perftest tasks we want to run daily
1245 for name, task in full_task_graph.tasks.items():
1246 if task.kind != "perftest":
1247 continue
1248 if task.attributes.get("cron", False) and any(
1249 test_name in name for test_name in ["view"]
1251 yield name
1254 @_target_task("l10n-cross-channel")
1255 def target_tasks_l10n_cross_channel(full_task_graph, parameters, graph_config):
1256 """Select the set of tasks required to run l10n cross-channel."""
1258 def filter(task):
1259 return task.kind in ["l10n-cross-channel"]
1261 return [l for l, t in full_task_graph.tasks.items() if filter(t)]