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/.
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
32 r
"android-geckoview-docs",
35 r
"windows10-64-ref-hw",
36 r
"windows10-aarch64-qr",
38 r
"linux-", # hide all linux32 tasks by default - bug 1599197
39 r
"linux1804-32", # hide linux32 tests - bug 1599197
41 r
"web-platform-tests.*backlog", # hide wpt jobs that are not implemented yet - bug 1572820
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
):
52 _target_task_methods
[name
] = func
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}...")
66 task_id
= find_task_id(index_path
)
67 print(f
"Index {index_path} exists: taskId {task_id}")
70 print(f
"Index {index_path} doesn't exist.")
74 def filter_out_shipping_phase(task
, parameters
):
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
):
88 Filter out tasks that run via cron.
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.
116 task (str): String representing the task name.
117 optional_filters (list, optional):
118 Additional filters to apply to task filtering.
121 (Boolean): True if task does not match any known filters.
124 filters
= UNCOMMON_TRY_TASK_LABELS
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.
141 assert mode
in ["include", "exclude"]
143 any_match
= any(r
.search(task_label
) for r
in regexes
)
145 return mode
== "include"
146 return mode
!= "include"
149 def filter_release_tasks(task
, parameters
):
150 platform
= task
.attributes
.get("build_platform")
159 if task
.attributes
["kind"] == "l10n":
160 # This is on-change l10n
163 task
.attributes
["build_type"] == "opt"
164 and task
.attributes
.get("unittest_suite") != "talos"
165 and task
.attributes
.get("unittest_suite") != "raptor"
169 if task
.attributes
.get("shipping_phase") not in (None, "build"):
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"):
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
190 if build_type
== "debug":
191 if "linux" not in build_platform
:
192 # filter out windows/mac/android
194 elif task
.kind
not in ["spidermonkey"] and "-qr" in test_platform
:
195 # filter out linux-qr tests, leave spidermonkey
197 elif "64" not in build_platform
:
198 # filter out linux32 builds
201 # webrender-android-*-debug doesn't have attributes to find 'debug', using task.label.
202 if task
.kind
== "webrender" and "debug" in task
.label
:
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", []
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).
226 and "test_manifests" in task
.attributes
227 and not task
.attributes
["test_manifests"]
233 def standard_filter(task
, parameters
):
235 filter_func(task
, parameters
)
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
:
249 if "shippable" not in platform
:
251 if "p2" in platform
and "aarch64" in platform
:
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):
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
= [
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
)
290 k
: getattr(options
, k
)
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
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
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
)
347 # With no try mode, we schedule nothing, allowing the user to add tasks
348 # later via treeherder.
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"],)
367 for project
in projects
:
368 params
= dict(parameters
)
369 params
["project"] = project
370 parameters
= Parameters(**params
)
373 target_tasks_method
= PER_PROJECT_PARAMETERS
[project
]["target_tasks_method"]
375 target_tasks_method
= "default"
378 get_method(target_tasks_method
)(full_task_graph
, parameters
, graph_config
)
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
= []
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", [])]
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."""
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
438 if task
.kind
!= "test":
441 if parameters
["backstop"]:
444 build_type
= task
.attributes
.get("build_type")
446 if not build_type
or build_type
!= "opt" or filter_out_shippable(task
):
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
464 if task
.kind
!= "test":
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
:
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).
483 family
== "android" and not shippable
484 ) or "-" not in build_platform
486 if build_type
!= "opt" or not is_regular_opt
:
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
500 filtered_for_project
= target_tasks_default(
501 full_task_graph
, parameters
, graph_config
505 if task
.attributes
["kind"] == "artifact-build":
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."""
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."""
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."""
545 if not filter_release_tasks(task
, parameters
):
548 if not standard_filter(task
, parameters
):
551 platform
= task
.attributes
.get("build_platform")
553 # Android is not built on esr91.
554 if platform
and "android" in platform
:
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."""
569 if task
.attributes
.get("shipping_product") != parameters
["release_product"]:
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
:
577 if not filter_out_missing_signoffs(task
, parameters
):
580 if task
.attributes
.get("shipping_phase") == "promote":
583 return [l
for l
, t
in full_task_graph
.tasks
.items() if filter(t
)]
586 def is_geckoview(task
, parameters
):
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(
605 if not filter_out_missing_signoffs(task
, parameters
):
607 # Include promotion tasks; these will be optimized out
608 if task
.label
in filtered_for_candidates
:
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(
618 task
.attributes
.get("shipping_product") == parameters
["release_product"]
619 and task
.attributes
.get("shipping_phase") == "push"
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"
632 # ship_firefox_rc runs after `promote` rather than `push`; include
634 filtered_for_candidates
= target_tasks_promote_desktop(
640 # ship_firefox runs after `push`; include all push tasks.
641 filtered_for_candidates
= target_tasks_push_desktop(
648 if not filter_out_missing_signoffs(task
, parameters
):
650 # Include promotion tasks; these will be optimized out
651 if task
.label
in filtered_for_candidates
:
654 # XXX: Bug 1619603 - geckoview also ships alongside Firefox RC
655 if is_geckoview(task
, parameters
) and is_rc
:
659 task
.attributes
.get("shipping_product") != parameters
["release_product"]
660 or task
.attributes
.get("shipping_phase") != "ship"
664 if "secondary" in task
.kind
:
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"""
677 platform
= task
.attributes
.get("build_platform")
678 # disable mobile jobs
679 if str(platform
).startswith("android"):
682 if platform
== "linux64-asan":
684 # disable non-pine and tasks with a shipping phase
685 if standard_filter(task
, parameters
) or filter_out_shipping_phase(
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"""
698 # We disable everything in central, and adjust downstream.
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."""
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(
717 "reason": "to avoid triggering multiple nightlies off the same revision",
723 # XXX Starting 69, we don't ship Fennec Nightly anymore. We just want geckoview to be
725 return task
.attributes
.get("shipping_product") == "fennec" and task
.kind
in (
726 "beetmover-geckoview",
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.
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
:
746 try_name
= attributes
.get("raptor_try_name")
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
:
756 # ignore all windows 7 perf jobs scheduled automatically
757 if "windows7" in platform
or "windows10-32" in platform
:
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
:
768 if "chromium" in try_name
:
769 if "tp6" in try_name
and "macosx1014" in platform
:
772 if "-live" in try_name
:
774 if "-fis" in try_name
:
776 if "linux" in platform
:
777 if "speedometer" in try_name
:
780 # Don't run tp6 raptor tests
781 if "tp6" in try_name
:
784 elif accept_raptor_android_build(platform
):
785 # Ignore all fennec tests here, we run those weekly
786 if "fennec" in try_name
:
788 # Only run webrender tests
789 if "chrome-m" not in try_name
and "-qr" not in platform
:
791 # Select live site tests
792 if "-live" in try_name
:
794 # Select fenix resource usage tests
795 if "fenix" in try_name
:
796 if "-power" in try_name
:
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
:
806 if cpu_n_memory_task
:
807 if "-speedometer-" in try_name
:
809 if "-scn" in try_name
and "-idle" in try_name
:
812 return "browsertime" in try_name
813 # Select browsertime-specific tests
814 if "browsertime" in try_name
:
815 if "speedometer" in try_name
:
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
):
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
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."""
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,
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(
921 "reason": "to avoid triggering multiple nightlies off the same revision",
926 # Tasks that aren't platform specific
927 release_filter
= make_desktop_nightly_filter({None}
)
929 l
for l
, t
in full_task_graph
.tasks
.items() if release_filter(t
, parameters
)
931 # Avoid duplicate tasks.
933 set(target_tasks_nightly_win32(full_task_graph
, parameters
, graph_config
))
934 |
set(target_tasks_nightly_win64(full_task_graph
, parameters
, graph_config
))
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
))
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"""
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
:
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."""
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"""
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."""
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."""
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."""
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."""
1051 if not filter_for_project(task
, parameters
):
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.
1066 if not task
.attributes
.get("shipping_product"):
1068 if parameters
["release_type"].startswith(
1070 ) and "android" in task
.attributes
.get("build_platform", ""):
1072 if parameters
["release_type"] != "beta" and "devedition" in task
.attributes
.get(
1073 "build_platform", ""
1076 if task
.attributes
.get("shipping_phase") == "build":
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(
1106 ) and "android" in task
.attributes
.get("build_platform", ""):
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"""
1126 if task
.kind
in ["code-review"]:
1130 if task
.attributes
.get("code-review") is True:
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"""
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
1151 platform
= task
.attributes
.get("build_platform")
1152 attributes
= task
.attributes
1154 if platform
and "android" not in platform
:
1156 if attributes
.get("unittest_suite") != "raptor":
1158 try_name
= attributes
.get("raptor_try_name")
1159 if "-cold" in try_name
and "shippable" in platform
:
1160 # Get browsertime amazon smoke tests
1162 "browsertime" in try_name
1163 and "amazon" in try_name
1164 and "search" not in try_name
1165 and "fenix" in try_name
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
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")
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
:
1192 if attributes
.get("unittest_suite") != "raptor" and not vismet
:
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
:
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":
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"]:
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":
1236 if task
.attributes
.get("cron", False):
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":
1248 if task
.attributes
.get("cron", False) and any(
1249 test_name
in name
for test_name
in ["view"]
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."""
1259 return task
.kind
in ["l10n-cross-channel"]
1261 return [l
for l
, t
in full_task_graph
.tasks
.items() if filter(t
)]