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 datetime
import datetime
, timedelta
12 from redo
import retry
13 from taskgraph
.parameters
import Parameters
14 from taskgraph
.target_tasks
import _target_task
, get_method
15 from taskgraph
.util
.taskcluster
import find_task_id
17 from gecko_taskgraph
import GECKO
, try_option_syntax
18 from gecko_taskgraph
.util
.attributes
import (
19 match_run_on_hg_branches
,
20 match_run_on_projects
,
22 from gecko_taskgraph
.util
.hg
import find_hg_revision_push_info
, get_hg_commit_message
23 from gecko_taskgraph
.util
.platforms
import platform_family
25 logger
= logging
.getLogger(__name__
)
28 # Some tasks show up in the target task set, but are possibly special cases,
29 # uncommon tasks, or tasks running against limited hardware set that they
30 # should only be selectable with --full.
31 UNCOMMON_TRY_TASK_LABELS
= [
32 # Platforms and/or Build types
33 r
"build-.*-gcp", # Bug 1631990
34 r
"mingwclang", # Bug 1631990
35 r
"valgrind", # Bug 1631990
37 r
"android-geckoview-docs",
40 r
"windows11-64-2009-hw-ref",
41 r
"windows10-aarch64-qr",
43 r
"linux-", # hide all linux32 tasks by default - bug 1599197
44 r
"linux1804-32", # hide linux32 tests - bug 1599197
46 r
"web-platform-tests.*backlog", # hide wpt jobs that are not implemented yet - bug 1572820
48 r
"-profiling-", # talos/raptor profiling jobs are run too often
49 r
"-32-.*-webgpu", # webgpu gets little benefit from these tests.
52 # Hide shippable versions of tests we have opt versions of because the non-shippable
53 # versions are faster to run. This is mostly perf tests.
54 r
"-shippable(?!.*(awsy|browsertime|marionette-headless|mochitest-devtools-chrome-fis|raptor|talos|web-platform-tests-wdspec-headless|mochitest-plain-headless))", # noqa - too long
55 r
"nightly-simulation",
59 def index_exists(index_path
, reason
=""):
60 print(f
"Looking for existing index {index_path} {reason}...")
62 task_id
= find_task_id(index_path
)
63 print(f
"Index {index_path} exists: taskId {task_id}")
66 print(f
"Index {index_path} doesn't exist.")
70 def filter_out_shipping_phase(task
, parameters
):
72 # nightly still here because of geckodriver
73 not task
.attributes
.get("nightly")
74 and task
.attributes
.get("shipping_phase") in (None, "build")
78 def filter_out_devedition(task
, parameters
):
79 return not task
.attributes
.get("shipping_product") == "devedition"
82 def filter_out_cron(task
, parameters
):
84 Filter out tasks that run via cron.
86 return not task
.attributes
.get("cron")
89 def filter_for_project(task
, parameters
):
90 """Filter tasks by project. Optionally enable nightlies."""
91 run_on_projects
= set(task
.attributes
.get("run_on_projects", []))
92 return match_run_on_projects(parameters
["project"], run_on_projects
)
95 def filter_for_hg_branch(task
, parameters
):
96 """Filter tasks by hg branch.
97 If `run_on_hg_branch` is not defined, then task runs on all branches"""
98 run_on_hg_branches
= set(task
.attributes
.get("run_on_hg_branches", ["all"]))
99 return match_run_on_hg_branches(parameters
["hg_branch"], run_on_hg_branches
)
102 def filter_on_platforms(task
, platforms
):
103 """Filter tasks on the given platform"""
104 platform
= task
.attributes
.get("build_platform")
105 return platform
in platforms
108 def filter_by_uncommon_try_tasks(task
, optional_filters
=None):
109 """Filters tasks that should not be commonly run on try.
112 task (str): String representing the task name.
113 optional_filters (list, optional):
114 Additional filters to apply to task filtering.
117 (Boolean): True if task does not match any known filters.
120 filters
= UNCOMMON_TRY_TASK_LABELS
122 filters
= itertools
.chain(filters
, optional_filters
)
124 return not any(re
.search(pattern
, task
) for pattern
in filters
)
127 def filter_by_regex(task_label
, regexes
, mode
="include"):
128 """Filters tasks according to a list of pre-compiled reguar expressions.
130 If mode is "include", a task label must match any regex to pass.
131 If it is "exclude", a task label must _not_ match any regex to pass.
136 assert mode
in ["include", "exclude"]
138 any_match
= any(r
.search(task_label
) for r
in regexes
)
140 return mode
== "include"
141 return mode
!= "include"
144 def filter_release_tasks(task
, parameters
):
145 platform
= task
.attributes
.get("build_platform")
154 if task
.attributes
["kind"] == "l10n":
155 # This is on-change l10n
158 task
.attributes
["build_type"] == "opt"
159 and task
.attributes
.get("unittest_suite") != "talos"
160 and task
.attributes
.get("unittest_suite") != "raptor"
164 if task
.attributes
.get("shipping_phase") not in (None, "build"):
167 """ No debug on release, keep on ESR with 4 week cycles, release
168 will not be too different from central, but ESR will live for a long time.
170 From June 2019 -> June 2020, we found 1 unique regression on ESR debug
171 and 5 unique regressions on beta/release. Keeping spidermonkey and linux
172 debug finds all but 1 unique regressions (windows found on try) for beta/release.
174 ...but debug-only failures started showing up on ESR (esr-91, esr-102) so
175 desktop debug tests were added back for beta.
177 build_type
= task
.attributes
.get("build_type", "")
178 build_platform
= task
.attributes
.get("build_platform", "")
179 test_platform
= task
.attributes
.get("test_platform", "")
181 if parameters
["release_type"].startswith("esr") or (
182 parameters
["release_type"] == "beta" and "android" not in build_platform
186 # code below here is intended to reduce release debug tasks
187 if task
.kind
== "hazard" or "toolchain" in build_platform
:
188 # keep hazard and toolchain builds around
191 if build_type
== "debug":
192 if "linux" not in build_platform
:
193 # filter out windows/mac/android
195 if task
.kind
not in ["spidermonkey"] and "-qr" in test_platform
:
196 # filter out linux-qr tests, leave spidermonkey
198 if "64" not in build_platform
:
199 # filter out linux32 builds
202 # webrender-android-*-debug doesn't have attributes to find 'debug', using task.label.
203 if task
.kind
== "webrender" and "debug" in task
.label
:
208 def filter_out_missing_signoffs(task
, parameters
):
209 for signoff
in parameters
["required_signoffs"]:
210 if signoff
not in parameters
["signoff_urls"] and signoff
in task
.attributes
.get(
211 "required_signoffs", []
217 def filter_tests_without_manifests(task
, parameters
):
218 """Remove test tasks that have an empty 'test_manifests' attribute.
220 This situation can arise when the test loader (e.g bugbug) decided there
221 weren't any important manifests to run for the given push. We filter tasks
222 out here rather than in the transforms so that the full task graph is still
223 aware that the task exists (which is needed by the backfill action).
227 and "test_manifests" in task
.attributes
228 and not task
.attributes
["test_manifests"]
234 def standard_filter(task
, parameters
):
236 filter_func(task
, parameters
)
240 filter_for_hg_branch
,
241 filter_tests_without_manifests
,
246 def accept_raptor_android_build(platform
):
247 """Helper function for selecting the correct android raptor builds."""
248 if "android" not in platform
:
250 if "shippable" not in platform
:
252 if "p5" in platform
and "aarch64" in platform
:
254 if "p6" in platform
and "aarch64" in platform
:
256 if "s21" in platform
and "aarch64" in platform
:
258 if "a51" in platform
:
263 def accept_raptor_desktop_build(platform
):
264 """Helper function for selecting correct desktop raptor builds."""
265 if "android" in platform
:
267 # ignore all windows 7 perf jobs scheduled automatically
268 if "windows7" in platform
or "windows10-32" in platform
:
270 # Completely ignore all non-shippable platforms
271 if "shippable" in platform
:
276 def accept_awsy_task(try_name
, platform
):
277 if accept_raptor_desktop_build(platform
):
278 if "windows" in platform
and "windows11-64" not in platform
:
280 if "dmd" in try_name
:
282 if "awsy-base" in try_name
:
284 if "awsy-tp6" in try_name
:
289 def filter_unsupported_artifact_builds(task
, parameters
):
290 try_config
= parameters
.get("try_task_config", {})
291 if not try_config
.get("use-artifact-builds", False):
294 supports_artifact_builds
= task
.attributes
.get("supports-artifact-builds", True)
295 return supports_artifact_builds
298 def filter_out_shippable(task
):
299 return not task
.attributes
.get("shippable", False)
302 def _try_task_config(full_task_graph
, parameters
, graph_config
):
303 requested_tasks
= parameters
["try_task_config"]["tasks"]
304 pattern_tasks
= [x
for x
in requested_tasks
if x
.endswith("-*")]
305 tasks
= list(set(requested_tasks
) - set(pattern_tasks
))
308 for pattern
in pattern_tasks
:
311 for t
in full_task_graph
.graph
.nodes
312 if t
.split(pattern
.replace("*", ""))[-1].isnumeric()
315 matched_tasks
.extend(found
)
319 if "MOZHARNESS_TEST_PATHS" in parameters
["try_task_config"].get("env", {}):
320 matched_tasks
= [x
for x
in matched_tasks
if x
.endswith("-1")]
322 selected_tasks
= set(tasks
) |
set(matched_tasks
)
323 missing
.update(selected_tasks
- set(full_task_graph
.tasks
))
326 missing_str
= "\n ".join(sorted(missing
))
328 f
"The following tasks were requested but do not exist in the full task graph and will be skipped:\n {missing_str}"
330 return list(selected_tasks
- missing
)
333 def _try_option_syntax(full_task_graph
, parameters
, graph_config
):
334 """Generate a list of target tasks based on try syntax in
335 parameters['message'] and, for context, the full task graph."""
336 options
= try_option_syntax
.TryOptionSyntax(
337 parameters
, full_task_graph
, graph_config
339 target_tasks_labels
= [
341 for t
in full_task_graph
.tasks
.values()
342 if options
.task_matches(t
)
343 and filter_by_uncommon_try_tasks(t
.label
)
344 and filter_unsupported_artifact_builds(t
, parameters
)
348 k
: getattr(options
, k
)
355 for l
in target_tasks_labels
:
356 task
= full_task_graph
[l
]
357 if "unittest_suite" in task
.attributes
:
358 task
.attributes
["task_duplicates"] = options
.trigger_tests
360 for l
in target_tasks_labels
:
361 task
= full_task_graph
[l
]
362 # If the developer wants test jobs to be rebuilt N times we add that value here
363 if options
.trigger_tests
> 1 and "unittest_suite" in task
.attributes
:
364 task
.attributes
["task_duplicates"] = options
.trigger_tests
366 # If the developer wants test talos jobs to be rebuilt N times we add that value here
368 options
.talos_trigger_tests
> 1
369 and task
.attributes
.get("unittest_suite") == "talos"
371 task
.attributes
["task_duplicates"] = options
.talos_trigger_tests
373 # If the developer wants test raptor jobs to be rebuilt N times we add that value here
375 options
.raptor_trigger_tests
376 and options
.raptor_trigger_tests
> 1
377 and task
.attributes
.get("unittest_suite") == "raptor"
379 task
.attributes
["task_duplicates"] = options
.raptor_trigger_tests
381 task
.attributes
.update(attributes
)
383 # Add notifications here as well
384 if options
.notifications
:
385 for task
in full_task_graph
:
386 owner
= parameters
.get("owner")
387 routes
= task
.task
.setdefault("routes", [])
388 if options
.notifications
== "all":
389 routes
.append(f
"notify.email.{owner}.on-any")
390 elif options
.notifications
== "failure":
391 routes
.append(f
"notify.email.{owner}.on-failed")
392 routes
.append(f
"notify.email.{owner}.on-exception")
394 return target_tasks_labels
397 @_target_task("try_tasks")
398 def target_tasks_try(full_task_graph
, parameters
, graph_config
):
399 try_mode
= parameters
["try_mode"]
400 if try_mode
== "try_task_config":
401 return _try_task_config(full_task_graph
, parameters
, graph_config
)
402 if try_mode
== "try_option_syntax":
403 return _try_option_syntax(full_task_graph
, parameters
, graph_config
)
404 # With no try mode, we schedule nothing, allowing the user to add tasks
405 # later via treeherder.
409 @_target_task("try_select_tasks")
410 def target_tasks_try_select(full_task_graph
, parameters
, graph_config
):
411 tasks
= target_tasks_try_select_uncommon(full_task_graph
, parameters
, graph_config
)
412 return [l
for l
in tasks
if filter_by_uncommon_try_tasks(l
)]
415 @_target_task("try_select_tasks_uncommon")
416 def target_tasks_try_select_uncommon(full_task_graph
, parameters
, graph_config
):
417 from gecko_taskgraph
.decision
import PER_PROJECT_PARAMETERS
419 projects
= ("autoland", "mozilla-central")
420 if parameters
["project"] not in projects
:
421 projects
= (parameters
["project"],)
424 for project
in projects
:
425 params
= dict(parameters
)
426 params
["project"] = project
427 parameters
= Parameters(**params
)
430 target_tasks_method
= PER_PROJECT_PARAMETERS
[project
]["target_tasks_method"]
432 target_tasks_method
= "default"
435 get_method(target_tasks_method
)(full_task_graph
, parameters
, graph_config
)
441 @_target_task("try_auto")
442 def target_tasks_try_auto(full_task_graph
, parameters
, graph_config
):
443 """Target the tasks which have indicated they should be run on autoland
444 (rather than try) via the `run_on_projects` attributes.
446 Should do the same thing as the `default` target tasks method.
448 params
= dict(parameters
)
449 params
["project"] = "autoland"
450 parameters
= Parameters(**params
)
452 regex_filters
= parameters
["try_task_config"].get("tasks-regex")
453 include_regexes
= exclude_regexes
= []
455 include_regexes
= [re
.compile(r
) for r
in regex_filters
.get("include", [])]
456 exclude_regexes
= [re
.compile(r
) for r
in regex_filters
.get("exclude", [])]
460 for l
, t
in full_task_graph
.tasks
.items()
461 if standard_filter(t
, parameters
)
462 and filter_out_shipping_phase(t
, parameters
)
463 and filter_out_devedition(t
, parameters
)
464 and filter_by_uncommon_try_tasks(t
.label
)
465 and filter_by_regex(t
.label
, include_regexes
, mode
="include")
466 and filter_by_regex(t
.label
, exclude_regexes
, mode
="exclude")
467 and filter_unsupported_artifact_builds(t
, parameters
)
468 and filter_out_shippable(t
)
472 @_target_task("default")
473 def target_tasks_default(full_task_graph
, parameters
, graph_config
):
474 """Target the tasks which have indicated they should be run on this project
475 via the `run_on_projects` attributes."""
478 for l
, t
in full_task_graph
.tasks
.items()
479 if standard_filter(t
, parameters
)
480 and filter_out_shipping_phase(t
, parameters
)
481 and filter_out_devedition(t
, parameters
)
485 @_target_task("autoland_tasks")
486 def target_tasks_autoland(full_task_graph
, parameters
, graph_config
):
487 """In addition to doing the filtering by project that the 'default'
488 filter does, also remove any tests running against shippable builds
489 for non-backstop pushes."""
490 filtered_for_project
= target_tasks_default(
491 full_task_graph
, parameters
, graph_config
495 if task
.kind
!= "test":
498 if parameters
["backstop"]:
501 build_type
= task
.attributes
.get("build_type")
503 if not build_type
or build_type
!= "opt" or filter_out_shippable(task
):
508 return [l
for l
in filtered_for_project
if filter(full_task_graph
[l
])]
511 @_target_task("mozilla_central_tasks")
512 def target_tasks_mozilla_central(full_task_graph
, parameters
, graph_config
):
513 """In addition to doing the filtering by project that the 'default'
514 filter does, also remove any tests running against regular (aka not shippable,
515 asan, etc.) opt builds."""
516 filtered_for_project
= target_tasks_default(
517 full_task_graph
, parameters
, graph_config
521 if task
.kind
!= "test":
524 build_platform
= task
.attributes
.get("build_platform")
525 build_type
= task
.attributes
.get("build_type")
526 shippable
= task
.attributes
.get("shippable", False)
528 if not build_platform
or not build_type
:
531 family
= platform_family(build_platform
)
532 # We need to know whether this test is against a "regular" opt build
533 # (which is to say, not shippable, asan, tsan, or any other opt build
534 # with other properties). There's no positive test for this, so we have to
535 # do it somewhat hackily. Android doesn't have variants other than shippable
536 # so it is pretty straightforward to check for. Other platforms have many
537 # variants, but none of the regular opt builds we're looking for have a "-"
538 # in their platform name, so this works (for now).
540 family
== "android" and not shippable
541 ) or "-" not in build_platform
543 if build_type
!= "opt" or not is_regular_opt
:
548 return [l
for l
in filtered_for_project
if filter(full_task_graph
[l
])]
551 @_target_task("graphics_tasks")
552 def target_tasks_graphics(full_task_graph
, parameters
, graph_config
):
553 """In addition to doing the filtering by project that the 'default'
554 filter does, also remove artifact builds because we have csets on
555 the graphics branch that aren't on the candidate branches of artifact
557 filtered_for_project
= target_tasks_default(
558 full_task_graph
, parameters
, graph_config
562 if task
.attributes
["kind"] == "artifact-build":
566 return [l
for l
in filtered_for_project
if filter(full_task_graph
[l
])]
569 @_target_task("mozilla_beta_tasks")
570 def target_tasks_mozilla_beta(full_task_graph
, parameters
, graph_config
):
571 """Select the set of tasks required for a promotable beta or release build
572 of desktop, plus android CI. The candidates build process involves a pipeline
573 of builds and signing, but does not include beetmover or balrog jobs."""
577 for l
, t
in full_task_graph
.tasks
.items()
578 if filter_release_tasks(t
, parameters
) and standard_filter(t
, parameters
)
582 @_target_task("mozilla_release_tasks")
583 def target_tasks_mozilla_release(full_task_graph
, parameters
, graph_config
):
584 """Select the set of tasks required for a promotable beta or release build
585 of desktop, plus android CI. The candidates build process involves a pipeline
586 of builds and signing, but does not include beetmover or balrog jobs."""
590 for l
, t
in full_task_graph
.tasks
.items()
591 if filter_release_tasks(t
, parameters
) and standard_filter(t
, parameters
)
595 @_target_task("mozilla_esr115_tasks")
596 def target_tasks_mozilla_esr115(full_task_graph
, parameters
, graph_config
):
597 """Select the set of tasks required for a promotable beta or release build
598 of desktop, without android CI. The candidates build process involves a pipeline
599 of builds and signing, but does not include beetmover or balrog jobs."""
602 if not filter_release_tasks(task
, parameters
):
605 if not standard_filter(task
, parameters
):
608 platform
= task
.attributes
.get("build_platform")
610 # Android is not built on esr115.
611 if platform
and "android" in platform
:
616 return [l
for l
, t
in full_task_graph
.tasks
.items() if filter(t
)]
619 @_target_task("promote_desktop")
620 def target_tasks_promote_desktop(full_task_graph
, parameters
, graph_config
):
621 """Select the superset of tasks required to promote a beta or release build
622 of a desktop product. This should include all non-android
623 mozilla_{beta,release} tasks, plus l10n, beetmover, balrog, etc."""
626 if task
.attributes
.get("shipping_product") != parameters
["release_product"]:
629 # 'secondary' balrog/update verify/final verify tasks only run for RCs
630 if parameters
.get("release_type") != "release-rc":
631 if "secondary" in task
.kind
:
634 if not filter_out_missing_signoffs(task
, parameters
):
637 if task
.attributes
.get("shipping_phase") == "promote":
640 return [l
for l
, t
in full_task_graph
.tasks
.items() if filter(t
)]
643 @_target_task("push_desktop")
644 def target_tasks_push_desktop(full_task_graph
, parameters
, graph_config
):
645 """Select the set of tasks required to push a build of desktop to cdns.
646 Previous build deps will be optimized out via action task."""
647 filtered_for_candidates
= target_tasks_promote_desktop(
654 if not filter_out_missing_signoffs(task
, parameters
):
656 # Include promotion tasks; these will be optimized out
657 if task
.label
in filtered_for_candidates
:
661 task
.attributes
.get("shipping_product") == parameters
["release_product"]
662 and task
.attributes
.get("shipping_phase") == "push"
666 return [l
for l
, t
in full_task_graph
.tasks
.items() if filter(t
)]
669 @_target_task("ship_desktop")
670 def target_tasks_ship_desktop(full_task_graph
, parameters
, graph_config
):
671 """Select the set of tasks required to ship desktop.
672 Previous build deps will be optimized out via action task."""
673 is_rc
= parameters
.get("release_type") == "release-rc"
675 # ship_firefox_rc runs after `promote` rather than `push`; include
677 filtered_for_candidates
= target_tasks_promote_desktop(
683 # ship_firefox runs after `push`; include all push tasks.
684 filtered_for_candidates
= target_tasks_push_desktop(
691 if not filter_out_missing_signoffs(task
, parameters
):
693 # Include promotion tasks; these will be optimized out
694 if task
.label
in filtered_for_candidates
:
698 task
.attributes
.get("shipping_product") != parameters
["release_product"]
699 or task
.attributes
.get("shipping_phase") != "ship"
703 if "secondary" in task
.kind
:
707 return [l
for l
, t
in full_task_graph
.tasks
.items() if filter(t
)]
710 @_target_task("pine_tasks")
711 def target_tasks_pine(full_task_graph
, parameters
, graph_config
):
712 """Bug 1879960 - no reftests or wpt needed"""
713 filtered_for_project
= target_tasks_default(
714 full_task_graph
, parameters
, graph_config
718 suite
= task
.attributes
.get("unittest_suite", "")
719 if "reftest" in suite
or "web-platform" in suite
:
723 return [l
for l
in filtered_for_project
if filter(full_task_graph
[l
])]
726 @_target_task("larch_tasks")
727 def target_tasks_larch(full_task_graph
, parameters
, graph_config
):
728 """Bug 1879213 - only run necessary tasks on larch"""
729 filtered_for_project
= target_tasks_default(
730 full_task_graph
, parameters
, graph_config
734 # no localized builds, no android
737 or "msix" in task
.kind
738 or "android" in task
.attributes
.get("build_platform", "")
739 or (task
.kind
== "test" and "msix" in task
.label
)
742 # otherwise reduce tests only
743 if task
.kind
!= "test":
745 return "browser-chrome" in task
.label
or "xpcshell" in task
.label
747 return [l
for l
in filtered_for_project
if filter(full_task_graph
[l
])]
750 @_target_task("kaios_tasks")
751 def target_tasks_kaios(full_task_graph
, parameters
, graph_config
):
752 """The set of tasks to run for kaios integration"""
755 # We disable everything in central, and adjust downstream.
758 return [l
for l
, t
in full_task_graph
.tasks
.items() if filter(t
)]
761 @_target_task("custom-car_perf_testing")
762 def target_tasks_custom_car_perf_testing(full_task_graph
, parameters
, graph_config
):
763 """Select tasks required for running daily performance tests for custom chromium-as-release."""
766 platform
= task
.attributes
.get("test_platform")
767 attributes
= task
.attributes
768 if attributes
.get("unittest_suite") != "raptor":
771 try_name
= attributes
.get("raptor_try_name")
773 # Desktop and Android selection for CaR
774 if accept_raptor_desktop_build(platform
) or accept_raptor_android_build(
777 if "browsertime" in try_name
and (
778 "custom-car" in try_name
or "cstm-car-m" in try_name
780 if "hw-s21" in platform
and "speedometer3" not in try_name
:
785 return [l
for l
, t
in full_task_graph
.tasks
.items() if filter(t
)]
788 @_target_task("general_perf_testing")
789 def target_tasks_general_perf_testing(full_task_graph
, parameters
, graph_config
):
791 Select tasks required for running performance tests 3 times a week.
795 platform
= task
.attributes
.get("test_platform")
796 attributes
= task
.attributes
797 if attributes
.get("unittest_suite") != "raptor":
800 try_name
= attributes
.get("raptor_try_name")
802 if "tp6-bench" in try_name
:
805 # Bug 1867669 - Temporarily disable all live site tests
806 if "live" in try_name
and "sheriffed" not in try_name
:
810 if accept_raptor_desktop_build(platform
):
811 # Select some browsertime tasks as desktop smoke-tests
812 if "browsertime" in try_name
:
813 if "chrome" in try_name
:
814 if "tp6" in try_name
and "essential" not in try_name
:
817 if "chromium" in try_name
:
818 if "tp6" in try_name
and "essential" not in try_name
:
821 # chromium-as-release has it's own cron
822 if "custom-car" in try_name
:
824 if "-live" in try_name
:
826 if "-fis" in try_name
:
828 if "linux" in platform
:
829 if "speedometer" in try_name
:
831 if "safari" and "benchmark" in try_name
:
834 elif accept_raptor_android_build(platform
):
835 if "hw-s21" in platform
and "speedometer3" not in try_name
:
837 if "chrome-m" in try_name
and (
838 ("ebay" in try_name
and "live" not in try_name
)
841 and ("facebook" in try_name
or "dailymail" in try_name
)
845 # Ignore all fennec tests here, we run those weekly
846 if "fennec" in try_name
:
848 # Only run webrender tests
849 if "chrome-m" not in try_name
and "-qr" not in platform
:
851 # Select live site tests
852 if "-live" in try_name
:
854 # Select fenix resource usage tests
855 if "fenix" in try_name
:
856 # Bug 1816421 disable fission perf tests
857 if "-fis" in try_name
:
859 if "-power" in try_name
:
861 # Select geckoview resource usage tests
862 if "geckoview" in try_name
:
863 # Bug 1816421 disable fission perf tests
864 if "-fis" in try_name
:
866 # Run cpu+memory, and power tests
867 cpu_n_memory_task
= "-cpu" in try_name
and "-memory" in try_name
868 power_task
= "-power" in try_name
869 # Ignore cpu+memory+power tests
870 if power_task
and cpu_n_memory_task
:
872 if cpu_n_memory_task
:
875 return "browsertime" in try_name
876 # Select browsertime-specific tests
877 if "browsertime" in try_name
:
878 # Don't run android CaR sp tests as we already have a cron for this.
879 if "m-car" in try_name
:
881 if "fenix" in try_name
:
883 if "speedometer" in try_name
:
885 if "motionmark" in try_name
and "1-3" in try_name
:
886 if "chrome-m" in try_name
:
890 return [l
for l
, t
in full_task_graph
.tasks
.items() if filter(t
)]
893 def make_desktop_nightly_filter(platforms
):
894 """Returns a filter that gets all nightly tasks on the given platform."""
896 def filter(task
, parameters
):
899 filter_on_platforms(task
, platforms
),
900 filter_for_project(task
, parameters
),
901 task
.attributes
.get("shippable", False),
902 # Tests and nightly only builds don't have `shipping_product` set
903 task
.attributes
.get("shipping_product")
904 in {None, "firefox", "thunderbird"},
905 task
.kind
not in {"l10n"}, # no on-change l10n
912 @_target_task("sp-perftests")
913 def target_tasks_speedometer_tests(full_task_graph
, parameters
, graph_config
):
915 platform
= task
.attributes
.get("test_platform")
916 attributes
= task
.attributes
917 if attributes
.get("unittest_suite") != "raptor":
920 if accept_raptor_desktop_build(platform
) or accept_raptor_android_build(
923 try_name
= attributes
.get("raptor_try_name")
924 if "hw-s21" in platform
and "speedometer3" not in try_name
:
927 "browsertime" in try_name
928 and "speedometer" in try_name
929 and "chrome" in try_name
933 return [l
for l
, t
in full_task_graph
.tasks
.items() if filter(t
)]
936 @_target_task("nightly_linux")
937 def target_tasks_nightly_linux(full_task_graph
, parameters
, graph_config
):
938 """Select the set of tasks required for a nightly build of linux. The
939 nightly build process involves a pipeline of builds, signing,
940 and, eventually, uploading the tasks to balrog."""
941 filter = make_desktop_nightly_filter(
942 {"linux64-shippable", "linux-shippable", "linux-aarch64-shippable"}
944 return [l
for l
, t
in full_task_graph
.tasks
.items() if filter(t
, parameters
)]
947 @_target_task("nightly_macosx")
948 def target_tasks_nightly_macosx(full_task_graph
, parameters
, graph_config
):
949 """Select the set of tasks required for a nightly build of macosx. The
950 nightly build process involves a pipeline of builds, signing,
951 and, eventually, uploading the tasks to balrog."""
952 filter = make_desktop_nightly_filter({"macosx64-shippable"})
953 return [l
for l
, t
in full_task_graph
.tasks
.items() if filter(t
, parameters
)]
956 @_target_task("nightly_win32")
957 def target_tasks_nightly_win32(full_task_graph
, parameters
, graph_config
):
958 """Select the set of tasks required for a nightly build of win32 and win64.
959 The nightly build process involves a pipeline of builds, signing,
960 and, eventually, uploading the tasks to balrog."""
961 filter = make_desktop_nightly_filter({"win32-shippable"})
962 return [l
for l
, t
in full_task_graph
.tasks
.items() if filter(t
, parameters
)]
965 @_target_task("nightly_win64")
966 def target_tasks_nightly_win64(full_task_graph
, parameters
, graph_config
):
967 """Select the set of tasks required for a nightly build of win32 and win64.
968 The nightly build process involves a pipeline of builds, signing,
969 and, eventually, uploading the tasks to balrog."""
970 filter = make_desktop_nightly_filter({"win64-shippable"})
971 return [l
for l
, t
in full_task_graph
.tasks
.items() if filter(t
, parameters
)]
974 @_target_task("nightly_win64_aarch64")
975 def target_tasks_nightly_win64_aarch64(full_task_graph
, parameters
, graph_config
):
976 """Select the set of tasks required for a nightly build of win32 and win64.
977 The nightly build process involves a pipeline of builds, signing,
978 and, eventually, uploading the tasks to balrog."""
979 filter = make_desktop_nightly_filter({"win64-aarch64-shippable"})
980 return [l
for l
, t
in full_task_graph
.tasks
.items() if filter(t
, parameters
)]
983 @_target_task("nightly_asan")
984 def target_tasks_nightly_asan(full_task_graph
, parameters
, graph_config
):
985 """Select the set of tasks required for a nightly build of asan. The
986 nightly build process involves a pipeline of builds, signing,
987 and, eventually, uploading the tasks to balrog."""
988 filter = make_desktop_nightly_filter(
989 {"linux64-asan-reporter-shippable", "win64-asan-reporter-shippable"}
991 return [l
for l
, t
in full_task_graph
.tasks
.items() if filter(t
, parameters
)]
994 @_target_task("daily_releases")
995 def target_tasks_daily_releases(full_task_graph
, parameters
, graph_config
):
996 """Select the set of tasks required to identify if we should release.
997 If we determine that we should the task will communicate to ship-it to
998 schedule the release itself."""
1001 return task
.kind
in ["maybe-release"]
1003 return [l
for l
, t
in full_task_graph
.tasks
.items() if filter(t
)]
1006 @_target_task("nightly_desktop")
1007 def target_tasks_nightly_desktop(full_task_graph
, parameters
, graph_config
):
1008 """Select the set of tasks required for a nightly build of linux, mac,
1011 f
"{graph_config['trust-domain']}.v2.{parameters['project']}.revision."
1012 f
"{parameters['head_rev']}.taskgraph.decision-nightly-desktop"
1014 if os
.environ
.get("MOZ_AUTOMATION") and retry(
1018 "reason": "to avoid triggering multiple nightlies off the same revision",
1023 # Tasks that aren't platform specific
1024 release_filter
= make_desktop_nightly_filter({None}
)
1026 l
for l
, t
in full_task_graph
.tasks
.items() if release_filter(t
, parameters
)
1028 # Avoid duplicate tasks.
1030 set(target_tasks_nightly_win32(full_task_graph
, parameters
, graph_config
))
1031 |
set(target_tasks_nightly_win64(full_task_graph
, parameters
, graph_config
))
1033 target_tasks_nightly_win64_aarch64(
1034 full_task_graph
, parameters
, graph_config
1037 |
set(target_tasks_nightly_macosx(full_task_graph
, parameters
, graph_config
))
1038 |
set(target_tasks_nightly_linux(full_task_graph
, parameters
, graph_config
))
1039 |
set(target_tasks_nightly_asan(full_task_graph
, parameters
, graph_config
))
1040 |
set(release_tasks
)
1044 @_target_task("nightly_all")
1045 def target_tasks_nightly_all(full_task_graph
, parameters
, graph_config
):
1046 """Select the set of tasks required for a nightly build of firefox desktop and android"""
1048 set(target_tasks_nightly_desktop(full_task_graph
, parameters
, graph_config
))
1049 |
set(target_tasks_nightly_android(full_task_graph
, parameters
, graph_config
))
1053 # Run Searchfox analysis once daily.
1054 @_target_task("searchfox_index")
1055 def target_tasks_searchfox(full_task_graph
, parameters
, graph_config
):
1056 """Select tasks required for indexing Firefox for Searchfox web site each day"""
1058 "searchfox-linux64-searchfox/debug",
1059 "searchfox-macosx64-searchfox/debug",
1060 "searchfox-win64-searchfox/debug",
1061 "searchfox-android-armv7-searchfox/debug",
1062 "searchfox-ios-searchfox/debug",
1063 "source-test-file-metadata-bugzilla-components",
1064 "source-test-file-metadata-test-info-all",
1065 "source-test-wpt-metadata-summary",
1069 # Run build linux64-plain-clang-trunk/opt on mozilla-central/beta with perf tests
1070 @_target_task("linux64_clang_trunk_perf")
1071 def target_tasks_build_linux64_clang_trunk_perf(
1072 full_task_graph
, parameters
, graph_config
1074 """Select tasks required to run perf test on linux64 build with clang trunk"""
1076 # Only keep tasks generated from platform `linux1804-64-clang-trunk-qr/opt`
1077 def filter(task_label
):
1078 if "linux1804-64-clang-trunk-qr/opt" in task_label
:
1082 return [l
for l
, t
in full_task_graph
.tasks
.items() if filter(t
.label
)]
1085 # Run Updatebot's cron job 4 times daily.
1086 @_target_task("updatebot_cron")
1087 def target_tasks_updatebot_cron(full_task_graph
, parameters
, graph_config
):
1088 """Select tasks required to run Updatebot's cron job"""
1089 return ["updatebot-cron"]
1092 @_target_task("customv8_update")
1093 def target_tasks_customv8_update(full_task_graph
, parameters
, graph_config
):
1094 """Select tasks required for building latest d8/v8 version."""
1095 return ["toolchain-linux64-custom-v8"]
1098 @_target_task("file_update")
1099 def target_tasks_file_update(full_task_graph
, parameters
, graph_config
):
1100 """Select the set of tasks required to perform nightly in-tree file updates"""
1103 # For now any task in the repo-update kind is ok
1104 return task
.kind
in ["repo-update"]
1106 return [l
for l
, t
in full_task_graph
.tasks
.items() if filter(t
)]
1109 @_target_task("l10n_bump")
1110 def target_tasks_l10n_bump(full_task_graph
, parameters
, graph_config
):
1111 """Select the set of tasks required to perform l10n bumping."""
1114 # For now any task in the repo-update kind is ok
1115 return task
.kind
in ["l10n-bump"]
1117 return [l
for l
, t
in full_task_graph
.tasks
.items() if filter(t
)]
1120 @_target_task("merge_automation")
1121 def target_tasks_merge_automation(full_task_graph
, parameters
, graph_config
):
1122 """Select the set of tasks required to perform repository merges."""
1125 # For now any task in the repo-update kind is ok
1126 return task
.kind
in ["merge-automation"]
1128 return [l
for l
, t
in full_task_graph
.tasks
.items() if filter(t
)]
1131 @_target_task("scriptworker_canary")
1132 def target_tasks_scriptworker_canary(full_task_graph
, parameters
, graph_config
):
1133 """Select the set of tasks required to run scriptworker canaries."""
1136 # For now any task in the repo-update kind is ok
1137 return task
.kind
in ["scriptworker-canary"]
1139 return [l
for l
, t
in full_task_graph
.tasks
.items() if filter(t
)]
1142 @_target_task("cron_bouncer_check")
1143 def target_tasks_bouncer_check(full_task_graph
, parameters
, graph_config
):
1144 """Select the set of tasks required to perform bouncer version verification."""
1147 if not filter_for_project(task
, parameters
):
1149 # For now any task in the repo-update kind is ok
1150 return task
.kind
in ["cron-bouncer-check"]
1152 return [l
for l
, t
in full_task_graph
.tasks
.items() if filter(t
)]
1155 @_target_task("staging_release_builds")
1156 def target_tasks_staging_release(full_task_graph
, parameters
, graph_config
):
1158 Select all builds that are part of releases.
1162 if not task
.attributes
.get("shipping_product"):
1164 if parameters
["release_type"].startswith(
1166 ) and "android" in task
.attributes
.get("build_platform", ""):
1168 if parameters
["release_type"] != "beta" and "devedition" in task
.attributes
.get(
1169 "build_platform", ""
1172 if task
.attributes
.get("shipping_phase") == "build":
1176 return [l
for l
, t
in full_task_graph
.tasks
.items() if filter(t
)]
1179 @_target_task("release_simulation")
1180 def target_tasks_release_simulation(full_task_graph
, parameters
, graph_config
):
1182 Select builds that would run on push on a release branch.
1184 project_by_release
= {
1185 "nightly": "mozilla-central",
1186 "beta": "mozilla-beta",
1187 "release": "mozilla-release",
1188 "esr115": "mozilla-esr115",
1190 target_project
= project_by_release
.get(parameters
["release_type"])
1191 if target_project
is None:
1192 raise Exception("Unknown or unspecified release type in simulation run.")
1194 def filter_for_target_project(task
):
1195 """Filter tasks by project. Optionally enable nightlies."""
1196 run_on_projects
= set(task
.attributes
.get("run_on_projects", []))
1197 return match_run_on_projects(target_project
, run_on_projects
)
1199 def filter_out_android_on_esr(task
):
1200 if parameters
["release_type"].startswith(
1202 ) and "android" in task
.attributes
.get("build_platform", ""):
1208 for l
, t
in full_task_graph
.tasks
.items()
1209 if filter_release_tasks(t
, parameters
)
1210 and filter_out_cron(t
, parameters
)
1211 and filter_for_target_project(t
)
1212 and filter_out_android_on_esr(t
)
1216 @_target_task("codereview")
1217 def target_tasks_codereview(full_task_graph
, parameters
, graph_config
):
1218 """Select all code review tasks needed to produce a report"""
1222 if task
.kind
in ["code-review"]:
1226 if task
.attributes
.get("code-review") is True:
1231 return [l
for l
, t
in full_task_graph
.tasks
.items() if filter(t
)]
1234 @_target_task("nothing")
1235 def target_tasks_nothing(full_task_graph
, parameters
, graph_config
):
1236 """Select nothing, for DONTBUILD pushes"""
1240 @_target_task("daily_beta_perf")
1241 def target_tasks_daily_beta_perf(full_task_graph
, parameters
, graph_config
):
1243 Select performance tests on the beta branch to be run daily
1246 f
"{graph_config['trust-domain']}.v2.{parameters['project']}.revision."
1247 f
"{parameters['head_rev']}.taskgraph.decision-daily-beta-perf"
1249 if os
.environ
.get("MOZ_AUTOMATION") and retry(
1253 "reason": "to avoid triggering multiple daily beta perftests off of the same revision",
1259 platform
= task
.attributes
.get("test_platform")
1260 attributes
= task
.attributes
1261 try_name
= attributes
.get("raptor_try_name") or task
.label
1263 unittest_suite
= attributes
.get("unittest_suite")
1264 if unittest_suite
not in ("raptor", "awsy", "talos"):
1269 # Select beta tasks for awsy
1270 if "awsy" in try_name
:
1271 if accept_awsy_task(try_name
, platform
):
1275 # Select beta tasks for talos
1276 if "talos" == unittest_suite
:
1277 if accept_raptor_desktop_build(platform
):
1278 if "windows11-64" in platform
:
1279 if "xperf" in try_name
:
1282 if ("mac" in platform
or "windows" in platform
) and "g3" in try_name
:
1284 if "-swr" in try_name
:
1285 if "dromaeo" in try_name
:
1287 if "perf-reftest-singletons" in try_name
:
1289 if "realworldweb" in try_name
:
1293 for x
in ("prof", "ipc", "gli", "sessionrestore", "tabswitch")
1299 if accept_raptor_desktop_build(platform
):
1300 if "browsertime" and "firefox" in try_name
:
1301 if "profiling" in try_name
:
1303 if "bytecode" in try_name
:
1305 if "live" in try_name
:
1307 if "webext" in try_name
:
1309 if "unity" in try_name
:
1311 if "wasm" in try_name
:
1313 if "tp6-bench" in try_name
:
1315 if "tp6" in try_name
:
1317 if "benchmark" in try_name
:
1319 elif accept_raptor_android_build(platform
):
1320 # Select browsertime & geckoview specific tests
1321 if "browsertime" and "geckoview" in try_name
:
1322 if "power" in try_name
:
1324 if "cpu" in try_name
:
1326 if "profiling" in try_name
:
1328 if "-live" in try_name
:
1330 if "speedometer" in try_name
:
1332 if "webgl" in try_name
:
1334 if "tp6m" in try_name
:
1339 return [l
for l
, t
in full_task_graph
.tasks
.items() if filter(t
)]
1342 @_target_task("weekly_release_perf")
1343 def target_tasks_weekly_release_perf(full_task_graph
, parameters
, graph_config
):
1345 Select performance tests on the release branch to be run weekly
1349 platform
= task
.attributes
.get("test_platform")
1350 attributes
= task
.attributes
1351 try_name
= attributes
.get("raptor_try_name") or task
.label
1353 if attributes
.get("unittest_suite") not in ("raptor", "awsy"):
1358 # Select release tasks for awsy
1359 if "awsy" in try_name
:
1360 if accept_awsy_task(try_name
, platform
):
1364 # Select browsertime tests
1365 if accept_raptor_desktop_build(platform
):
1366 if "browsertime" and "firefox" in try_name
:
1367 if "power" in try_name
:
1369 if "profiling" in try_name
:
1371 if "bytecode" in try_name
:
1373 if "live" in try_name
:
1375 if "webext" in try_name
:
1377 if "tp6-bench" in try_name
:
1379 if "tp6" in try_name
:
1381 if "benchmark" in try_name
:
1383 if "youtube-playback" in try_name
:
1385 elif accept_raptor_android_build(platform
):
1386 # Select browsertime & geckoview specific tests
1387 if "browsertime" and "geckoview" in try_name
:
1388 if "power" in try_name
:
1390 if "cpu" in try_name
:
1392 if "profiling" in try_name
:
1394 if "-live" in try_name
:
1396 if "speedometer" in try_name
:
1398 if "webgl" in try_name
:
1400 if "tp6m" in try_name
:
1402 if "youtube-playback" in try_name
:
1407 return [l
for l
, t
in full_task_graph
.tasks
.items() if filter(t
)]
1410 @_target_task("raptor_tp6m")
1411 def target_tasks_raptor_tp6m(full_task_graph
, parameters
, graph_config
):
1413 Select tasks required for running raptor cold page-load tests on fenix and refbrow
1417 platform
= task
.attributes
.get("build_platform")
1418 attributes
= task
.attributes
1420 if platform
and "android" not in platform
:
1422 if attributes
.get("unittest_suite") != "raptor":
1424 try_name
= attributes
.get("raptor_try_name")
1425 if "-cold" in try_name
and "shippable" in platform
:
1426 # Get browsertime amazon smoke tests
1428 "browsertime" in try_name
1429 and "amazon" in try_name
1430 and "search" not in try_name
1434 return [l
for l
, t
in full_task_graph
.tasks
.items() if filter(t
)]
1437 @_target_task("backfill_all_browsertime")
1438 def target_tasks_backfill_all_browsertime(full_task_graph
, parameters
, graph_config
):
1440 Search for revisions that contains patches that were reviewed by perftest reviewers
1441 and landed the day before the cron is running. Trigger backfill-all-browsertime action
1442 task on each of them.
1444 from gecko_taskgraph
.actions
.util
import get_decision_task_id
, get_pushes
1446 def date_is_yesterday(date
):
1447 yesterday
= datetime
.today() - timedelta(days
=1)
1448 date
= datetime
.fromtimestamp(date
)
1449 return date
.date() == yesterday
.date()
1451 def reviewed_by_perftest(push
):
1453 commit_message
= get_hg_commit_message(
1454 os
.path
.join(GECKO
, graph_config
["product-dir"]), rev
=push
1456 except Exception as e
:
1460 for line
in commit_message
.split("\n\n"):
1461 if line
.lower().startswith("bug ") and "r=" in line
:
1462 if "perftest-reviewers" in line
.split("r=")[-1]:
1467 pushes
= get_pushes(
1468 project
=parameters
["head_repository"],
1469 end_id
=int(parameters
["pushlog_id"]),
1473 for push_id
in sorted([int(p
) for p
in pushes
.keys()], reverse
=True):
1474 push_rev
= pushes
[str(push_id
)]["changesets"][-1]
1475 push_info
= find_hg_revision_push_info(
1476 "https://hg.mozilla.org/integration/" + parameters
["project"], push_rev
1478 pushdate
= int(push_info
["pushdate"])
1479 if date_is_yesterday(pushdate
) and reviewed_by_perftest(push_rev
):
1480 from gecko_taskgraph
.actions
.util
import trigger_action
1483 f
"Revision {push_rev} was created yesterday and was reviewed by "
1484 f
"#perftest-reviewers."
1487 push_decision_task_id
= get_decision_task_id(
1488 parameters
["project"], push_id
1491 print(f
"Could not find decision task for push {push_id}")
1495 action_name
="backfill-all-browsertime",
1496 # This lets the action know on which push we want to add a new task
1497 decision_task_id
=push_decision_task_id
,
1499 except Exception as e
:
1500 print(f
"Failed to trigger action for {push_rev}: {e}")
1505 @_target_task("condprof")
1506 def target_tasks_condprof(full_task_graph
, parameters
, graph_config
):
1508 Select tasks required for building conditioned profiles.
1510 for name
, task
in full_task_graph
.tasks
.items():
1511 if task
.kind
== "condprof":
1512 if "a51" not in name
: # bug 1765348
1516 @_target_task("system_symbols")
1517 def target_tasks_system_symbols(full_task_graph
, parameters
, graph_config
):
1519 Select tasks for scraping and uploading system symbols.
1521 for name
, task
in full_task_graph
.tasks
.items():
1524 "system-symbols-upload",
1525 "system-symbols-reprocess",
1530 @_target_task("perftest")
1531 def target_tasks_perftest(full_task_graph
, parameters
, graph_config
):
1533 Select perftest tasks we want to run daily
1535 for name
, task
in full_task_graph
.tasks
.items():
1536 if task
.kind
!= "perftest":
1538 if task
.attributes
.get("cron", False):
1542 @_target_task("perftest-on-autoland")
1543 def target_tasks_perftest_autoland(full_task_graph
, parameters
, graph_config
):
1545 Select perftest tasks we want to run daily
1547 for name
, task
in full_task_graph
.tasks
.items():
1548 if task
.kind
!= "perftest":
1550 if task
.attributes
.get("cron", False) and any(
1551 test_name
in name
for test_name
in ["view"]
1556 @_target_task("l10n-cross-channel")
1557 def target_tasks_l10n_cross_channel(full_task_graph
, parameters
, graph_config
):
1558 """Select the set of tasks required to run l10n cross-channel."""
1561 return task
.kind
in ["l10n-cross-channel"]
1563 return [l
for l
, t
in full_task_graph
.tasks
.items() if filter(t
)]
1566 @_target_task("are-we-esmified-yet")
1567 def target_tasks_are_we_esmified_yet(full_task_graph
, parameters
, graph_config
):
1569 select the task to track the progress of the esmification project
1572 l
for l
, t
in full_task_graph
.tasks
.items() if t
.kind
== "are-we-esmified-yet"
1576 @_target_task("eslint-build")
1577 def target_tasks_eslint_build(full_task_graph
, parameters
, graph_config
):
1578 """Select the task to run additional ESLint rules which require a build."""
1580 for name
, task
in full_task_graph
.tasks
.items():
1581 if task
.kind
!= "source-test":
1583 if "eslint-build" in name
:
1587 @_target_task("holly_tasks")
1588 def target_tasks_holly(full_task_graph
, parameters
, graph_config
):
1589 """Bug 1814661: only run updatebot tasks on holly"""
1592 return task
.kind
== "updatebot"
1594 return [l
for l
, t
in full_task_graph
.tasks
.items() if filter(t
)]
1597 @_target_task("snap_upstream_tests")
1598 def target_tasks_snap_upstream_tests(full_task_graph
, parameters
, graph_config
):
1600 Select tasks for testing Snap package built as upstream. Omit -try because
1601 it does not really make sense on a m-c cron
1603 for name
, task
in full_task_graph
.tasks
.items():
1604 if "snap-upstream-test" in name
and not "-try" in name
:
1608 @_target_task("nightly-android")
1609 def target_tasks_nightly_android(full_task_graph
, parameters
, graph_config
):
1610 def filter(task
, parameters
):
1612 if task
.attributes
.get("shipping_product") == "fennec" and task
.kind
in (
1613 "beetmover-geckoview",
1619 build_type
= task
.attributes
.get("build-type", "")
1620 return build_type
in (
1624 "fenix-nightly-firebase",
1625 "focus-nightly-firebase",
1629 f
"{graph_config['trust-domain']}.v2.{parameters['project']}.branch."
1630 f
"{parameters['head_ref']}.revision.{parameters['head_rev']}.taskgraph.decision-nightly-android"
1632 if os
.environ
.get("MOZ_AUTOMATION") and retry(
1636 "reason": "to avoid triggering multiple nightlies off the same revision",
1641 return [l
for l
, t
in full_task_graph
.tasks
.items() if filter(t
, parameters
)]
1644 @_target_task("android-l10n-import")
1645 def target_tasks_android_l10n_import(full_task_graph
, parameters
, graph_config
):
1646 return [l
for l
, t
in full_task_graph
.tasks
.items() if l
== "android-l10n-import"]