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",
56 # Can't actually run on try
61 def index_exists(index_path
, reason
=""):
62 print(f
"Looking for existing index {index_path} {reason}...")
64 task_id
= find_task_id(index_path
)
65 print(f
"Index {index_path} exists: taskId {task_id}")
68 print(f
"Index {index_path} doesn't exist.")
72 def filter_out_shipping_phase(task
, parameters
):
74 # nightly still here because of geckodriver
75 not task
.attributes
.get("nightly")
76 and task
.attributes
.get("shipping_phase") in (None, "build")
80 def filter_out_devedition(task
, parameters
):
81 return not task
.attributes
.get("shipping_product") == "devedition"
84 def filter_out_cron(task
, parameters
):
86 Filter out tasks that run via cron.
88 return not task
.attributes
.get("cron")
91 def filter_for_project(task
, parameters
):
92 """Filter tasks by project. Optionally enable nightlies."""
93 run_on_projects
= set(task
.attributes
.get("run_on_projects", []))
94 return match_run_on_projects(parameters
["project"], run_on_projects
)
97 def filter_for_hg_branch(task
, parameters
):
98 """Filter tasks by hg branch.
99 If `run_on_hg_branch` is not defined, then task runs on all branches"""
100 run_on_hg_branches
= set(task
.attributes
.get("run_on_hg_branches", ["all"]))
101 return match_run_on_hg_branches(parameters
["hg_branch"], run_on_hg_branches
)
104 def filter_on_platforms(task
, platforms
):
105 """Filter tasks on the given platform"""
106 platform
= task
.attributes
.get("build_platform")
107 return platform
in platforms
110 def filter_by_uncommon_try_tasks(task
, optional_filters
=None):
111 """Filters tasks that should not be commonly run on try.
114 task (str): String representing the task name.
115 optional_filters (list, optional):
116 Additional filters to apply to task filtering.
119 (Boolean): True if task does not match any known filters.
122 filters
= UNCOMMON_TRY_TASK_LABELS
124 filters
= itertools
.chain(filters
, optional_filters
)
126 return not any(re
.search(pattern
, task
) for pattern
in filters
)
129 def filter_by_regex(task_label
, regexes
, mode
="include"):
130 """Filters tasks according to a list of pre-compiled reguar expressions.
132 If mode is "include", a task label must match any regex to pass.
133 If it is "exclude", a task label must _not_ match any regex to pass.
138 assert mode
in ["include", "exclude"]
140 any_match
= any(r
.search(task_label
) for r
in regexes
)
142 return mode
== "include"
143 return mode
!= "include"
146 def filter_release_tasks(task
, parameters
):
147 platform
= task
.attributes
.get("build_platform")
156 if task
.attributes
["kind"] == "l10n":
157 # This is on-change l10n
160 task
.attributes
["build_type"] == "opt"
161 and task
.attributes
.get("unittest_suite") != "talos"
162 and task
.attributes
.get("unittest_suite") != "raptor"
166 if task
.attributes
.get("shipping_phase") not in (None, "build"):
169 """ No debug on release, keep on ESR with 4 week cycles, release
170 will not be too different from central, but ESR will live for a long time.
172 From June 2019 -> June 2020, we found 1 unique regression on ESR debug
173 and 5 unique regressions on beta/release. Keeping spidermonkey and linux
174 debug finds all but 1 unique regressions (windows found on try) for beta/release.
176 ...but debug-only failures started showing up on ESR (esr-91, esr-102) so
177 desktop debug tests were added back for beta.
179 build_type
= task
.attributes
.get("build_type", "")
180 build_platform
= task
.attributes
.get("build_platform", "")
181 test_platform
= task
.attributes
.get("test_platform", "")
183 if parameters
["release_type"].startswith("esr") or (
184 parameters
["release_type"] == "beta" and "android" not in build_platform
188 # code below here is intended to reduce release debug tasks
189 if task
.kind
== "hazard" or "toolchain" in build_platform
:
190 # keep hazard and toolchain builds around
193 if build_type
== "debug":
194 if "linux" not in build_platform
:
195 # filter out windows/mac/android
197 if task
.kind
not in ["spidermonkey"] and "-qr" in test_platform
:
198 # filter out linux-qr tests, leave spidermonkey
200 if "64" not in build_platform
:
201 # filter out linux32 builds
204 # webrender-android-*-debug doesn't have attributes to find 'debug', using task.label.
205 if task
.kind
== "webrender" and "debug" in task
.label
:
210 def filter_out_missing_signoffs(task
, parameters
):
211 for signoff
in parameters
["required_signoffs"]:
212 if signoff
not in parameters
["signoff_urls"] and signoff
in task
.attributes
.get(
213 "required_signoffs", []
219 def filter_tests_without_manifests(task
, parameters
):
220 """Remove test tasks that have an empty 'test_manifests' attribute.
222 This situation can arise when the test loader (e.g bugbug) decided there
223 weren't any important manifests to run for the given push. We filter tasks
224 out here rather than in the transforms so that the full task graph is still
225 aware that the task exists (which is needed by the backfill action).
229 and "test_manifests" in task
.attributes
230 and not task
.attributes
["test_manifests"]
236 def standard_filter(task
, parameters
):
238 filter_func(task
, parameters
)
242 filter_for_hg_branch
,
243 filter_tests_without_manifests
,
248 def accept_raptor_android_build(platform
):
249 """Helper function for selecting the correct android raptor builds."""
250 if "android" not in platform
:
252 if "shippable" not in platform
:
254 if "p5" in platform
and "aarch64" in platform
:
256 if "p6" in platform
and "aarch64" in platform
:
258 if "s21" in platform
and "aarch64" in platform
:
260 if "a51" in platform
:
265 def accept_raptor_desktop_build(platform
):
266 """Helper function for selecting correct desktop raptor builds."""
267 if "android" in platform
:
269 # ignore all windows 7 perf jobs scheduled automatically
270 if "windows7" in platform
or "windows10-32" in platform
:
272 # Completely ignore all non-shippable platforms
273 if "shippable" in platform
:
278 def accept_awsy_task(try_name
, platform
):
279 if accept_raptor_desktop_build(platform
):
280 if "windows" in platform
and "windows11-64" not in platform
:
282 if "dmd" in try_name
:
284 if "awsy-base" in try_name
:
286 if "awsy-tp6" in try_name
:
291 def filter_unsupported_artifact_builds(task
, parameters
):
292 try_config
= parameters
.get("try_task_config", {})
293 if not try_config
.get("use-artifact-builds", False):
296 supports_artifact_builds
= task
.attributes
.get("supports-artifact-builds", True)
297 return supports_artifact_builds
300 def filter_out_shippable(task
):
301 return not task
.attributes
.get("shippable", False)
304 def _try_task_config(full_task_graph
, parameters
, graph_config
):
305 requested_tasks
= parameters
["try_task_config"]["tasks"]
306 pattern_tasks
= [x
for x
in requested_tasks
if x
.endswith("-*")]
307 tasks
= list(set(requested_tasks
) - set(pattern_tasks
))
310 for pattern
in pattern_tasks
:
313 for t
in full_task_graph
.graph
.nodes
314 if t
.split(pattern
.replace("*", ""))[-1].isnumeric()
317 matched_tasks
.extend(found
)
321 if "MOZHARNESS_TEST_PATHS" in parameters
["try_task_config"].get("env", {}):
322 matched_tasks
= [x
for x
in matched_tasks
if x
.endswith("-1")]
324 selected_tasks
= set(tasks
) |
set(matched_tasks
)
325 missing
.update(selected_tasks
- set(full_task_graph
.tasks
))
328 missing_str
= "\n ".join(sorted(missing
))
330 f
"The following tasks were requested but do not exist in the full task graph and will be skipped:\n {missing_str}"
332 return list(selected_tasks
- missing
)
335 def _try_option_syntax(full_task_graph
, parameters
, graph_config
):
336 """Generate a list of target tasks based on try syntax in
337 parameters['message'] and, for context, the full task graph."""
338 options
= try_option_syntax
.TryOptionSyntax(
339 parameters
, full_task_graph
, graph_config
341 target_tasks_labels
= [
343 for t
in full_task_graph
.tasks
.values()
344 if options
.task_matches(t
)
345 and filter_by_uncommon_try_tasks(t
.label
)
346 and filter_unsupported_artifact_builds(t
, parameters
)
350 k
: getattr(options
, k
)
357 for l
in target_tasks_labels
:
358 task
= full_task_graph
[l
]
359 if "unittest_suite" in task
.attributes
:
360 task
.attributes
["task_duplicates"] = options
.trigger_tests
362 for l
in target_tasks_labels
:
363 task
= full_task_graph
[l
]
364 # If the developer wants test jobs to be rebuilt N times we add that value here
365 if options
.trigger_tests
> 1 and "unittest_suite" in task
.attributes
:
366 task
.attributes
["task_duplicates"] = options
.trigger_tests
368 # If the developer wants test talos jobs to be rebuilt N times we add that value here
370 options
.talos_trigger_tests
> 1
371 and task
.attributes
.get("unittest_suite") == "talos"
373 task
.attributes
["task_duplicates"] = options
.talos_trigger_tests
375 # If the developer wants test raptor jobs to be rebuilt N times we add that value here
377 options
.raptor_trigger_tests
378 and options
.raptor_trigger_tests
> 1
379 and task
.attributes
.get("unittest_suite") == "raptor"
381 task
.attributes
["task_duplicates"] = options
.raptor_trigger_tests
383 task
.attributes
.update(attributes
)
385 # Add notifications here as well
386 if options
.notifications
:
387 for task
in full_task_graph
:
388 owner
= parameters
.get("owner")
389 routes
= task
.task
.setdefault("routes", [])
390 if options
.notifications
== "all":
391 routes
.append(f
"notify.email.{owner}.on-any")
392 elif options
.notifications
== "failure":
393 routes
.append(f
"notify.email.{owner}.on-failed")
394 routes
.append(f
"notify.email.{owner}.on-exception")
396 return target_tasks_labels
399 @_target_task("try_tasks")
400 def target_tasks_try(full_task_graph
, parameters
, graph_config
):
401 try_mode
= parameters
["try_mode"]
402 if try_mode
== "try_task_config":
403 return _try_task_config(full_task_graph
, parameters
, graph_config
)
404 if try_mode
== "try_option_syntax":
405 return _try_option_syntax(full_task_graph
, parameters
, graph_config
)
406 # With no try mode, we schedule nothing, allowing the user to add tasks
407 # later via treeherder.
411 @_target_task("try_select_tasks")
412 def target_tasks_try_select(full_task_graph
, parameters
, graph_config
):
413 tasks
= target_tasks_try_select_uncommon(full_task_graph
, parameters
, graph_config
)
414 return [l
for l
in tasks
if filter_by_uncommon_try_tasks(l
)]
417 @_target_task("try_select_tasks_uncommon")
418 def target_tasks_try_select_uncommon(full_task_graph
, parameters
, graph_config
):
419 from gecko_taskgraph
.decision
import PER_PROJECT_PARAMETERS
421 projects
= ("autoland", "mozilla-central")
422 if parameters
["project"] not in projects
:
423 projects
= (parameters
["project"],)
426 for project
in projects
:
427 params
= dict(parameters
)
428 params
["project"] = project
429 parameters
= Parameters(**params
)
432 target_tasks_method
= PER_PROJECT_PARAMETERS
[project
]["target_tasks_method"]
434 target_tasks_method
= "default"
437 get_method(target_tasks_method
)(full_task_graph
, parameters
, graph_config
)
443 @_target_task("try_auto")
444 def target_tasks_try_auto(full_task_graph
, parameters
, graph_config
):
445 """Target the tasks which have indicated they should be run on autoland
446 (rather than try) via the `run_on_projects` attributes.
448 Should do the same thing as the `default` target tasks method.
450 params
= dict(parameters
)
451 params
["project"] = "autoland"
452 parameters
= Parameters(**params
)
454 regex_filters
= parameters
["try_task_config"].get("tasks-regex")
455 include_regexes
= exclude_regexes
= []
457 include_regexes
= [re
.compile(r
) for r
in regex_filters
.get("include", [])]
458 exclude_regexes
= [re
.compile(r
) for r
in regex_filters
.get("exclude", [])]
462 for l
, t
in full_task_graph
.tasks
.items()
463 if standard_filter(t
, parameters
)
464 and filter_out_shipping_phase(t
, parameters
)
465 and filter_out_devedition(t
, parameters
)
466 and filter_by_uncommon_try_tasks(t
.label
)
467 and filter_by_regex(t
.label
, include_regexes
, mode
="include")
468 and filter_by_regex(t
.label
, exclude_regexes
, mode
="exclude")
469 and filter_unsupported_artifact_builds(t
, parameters
)
470 and filter_out_shippable(t
)
474 @_target_task("default")
475 def target_tasks_default(full_task_graph
, parameters
, graph_config
):
476 """Target the tasks which have indicated they should be run on this project
477 via the `run_on_projects` attributes."""
480 for l
, t
in full_task_graph
.tasks
.items()
481 if standard_filter(t
, parameters
)
482 and filter_out_shipping_phase(t
, parameters
)
483 and filter_out_devedition(t
, parameters
)
487 @_target_task("autoland_tasks")
488 def target_tasks_autoland(full_task_graph
, parameters
, graph_config
):
489 """In addition to doing the filtering by project that the 'default'
490 filter does, also remove any tests running against shippable builds
491 for non-backstop pushes."""
492 filtered_for_project
= target_tasks_default(
493 full_task_graph
, parameters
, graph_config
497 if task
.kind
!= "test":
500 if parameters
["backstop"]:
503 build_type
= task
.attributes
.get("build_type")
505 if not build_type
or build_type
!= "opt" or filter_out_shippable(task
):
510 return [l
for l
in filtered_for_project
if filter(full_task_graph
[l
])]
513 @_target_task("mozilla_central_tasks")
514 def target_tasks_mozilla_central(full_task_graph
, parameters
, graph_config
):
515 """In addition to doing the filtering by project that the 'default'
516 filter does, also remove any tests running against regular (aka not shippable,
517 asan, etc.) opt builds."""
518 filtered_for_project
= target_tasks_default(
519 full_task_graph
, parameters
, graph_config
523 if task
.kind
!= "test":
526 build_platform
= task
.attributes
.get("build_platform")
527 build_type
= task
.attributes
.get("build_type")
528 shippable
= task
.attributes
.get("shippable", False)
530 if not build_platform
or not build_type
:
533 family
= platform_family(build_platform
)
534 # We need to know whether this test is against a "regular" opt build
535 # (which is to say, not shippable, asan, tsan, or any other opt build
536 # with other properties). There's no positive test for this, so we have to
537 # do it somewhat hackily. Android doesn't have variants other than shippable
538 # so it is pretty straightforward to check for. Other platforms have many
539 # variants, but none of the regular opt builds we're looking for have a "-"
540 # in their platform name, so this works (for now).
542 family
== "android" and not shippable
543 ) or "-" not in build_platform
545 if build_type
!= "opt" or not is_regular_opt
:
550 return [l
for l
in filtered_for_project
if filter(full_task_graph
[l
])]
553 @_target_task("graphics_tasks")
554 def target_tasks_graphics(full_task_graph
, parameters
, graph_config
):
555 """In addition to doing the filtering by project that the 'default'
556 filter does, also remove artifact builds because we have csets on
557 the graphics branch that aren't on the candidate branches of artifact
559 filtered_for_project
= target_tasks_default(
560 full_task_graph
, parameters
, graph_config
564 if task
.attributes
["kind"] == "artifact-build":
568 return [l
for l
in filtered_for_project
if filter(full_task_graph
[l
])]
571 @_target_task("mozilla_beta_tasks")
572 def target_tasks_mozilla_beta(full_task_graph
, parameters
, graph_config
):
573 """Select the set of tasks required for a promotable beta or release build
574 of desktop, plus android CI. The candidates build process involves a pipeline
575 of builds and signing, but does not include beetmover or balrog jobs."""
579 for l
, t
in full_task_graph
.tasks
.items()
580 if filter_release_tasks(t
, parameters
) and standard_filter(t
, parameters
)
584 @_target_task("mozilla_release_tasks")
585 def target_tasks_mozilla_release(full_task_graph
, parameters
, graph_config
):
586 """Select the set of tasks required for a promotable beta or release build
587 of desktop, plus android CI. The candidates build process involves a pipeline
588 of builds and signing, but does not include beetmover or balrog jobs."""
592 for l
, t
in full_task_graph
.tasks
.items()
593 if filter_release_tasks(t
, parameters
) and standard_filter(t
, parameters
)
597 @_target_task("mozilla_esr115_tasks")
598 def target_tasks_mozilla_esr115(full_task_graph
, parameters
, graph_config
):
599 """Select the set of tasks required for a promotable beta or release build
600 of desktop, without android CI. The candidates build process involves a pipeline
601 of builds and signing, but does not include beetmover or balrog jobs."""
604 if not filter_release_tasks(task
, parameters
):
607 if not standard_filter(task
, parameters
):
610 platform
= task
.attributes
.get("build_platform")
612 # Android is not built on esr115.
613 if platform
and "android" in platform
:
618 return [l
for l
, t
in full_task_graph
.tasks
.items() if filter(t
)]
621 @_target_task("promote_desktop")
622 def target_tasks_promote_desktop(full_task_graph
, parameters
, graph_config
):
623 """Select the superset of tasks required to promote a beta or release build
624 of a desktop product. This should include all non-android
625 mozilla_{beta,release} tasks, plus l10n, beetmover, balrog, etc."""
628 if task
.attributes
.get("shipping_product") != parameters
["release_product"]:
631 # 'secondary' balrog/update verify/final verify tasks only run for RCs
632 if parameters
.get("release_type") != "release-rc":
633 if "secondary" in task
.kind
:
636 if not filter_out_missing_signoffs(task
, parameters
):
639 if task
.attributes
.get("shipping_phase") == "promote":
642 return [l
for l
, t
in full_task_graph
.tasks
.items() if filter(t
)]
645 @_target_task("push_desktop")
646 def target_tasks_push_desktop(full_task_graph
, parameters
, graph_config
):
647 """Select the set of tasks required to push a build of desktop to cdns.
648 Previous build deps will be optimized out via action task."""
649 filtered_for_candidates
= target_tasks_promote_desktop(
656 if not filter_out_missing_signoffs(task
, parameters
):
658 # Include promotion tasks; these will be optimized out
659 if task
.label
in filtered_for_candidates
:
663 task
.attributes
.get("shipping_product") == parameters
["release_product"]
664 and task
.attributes
.get("shipping_phase") == "push"
668 return [l
for l
, t
in full_task_graph
.tasks
.items() if filter(t
)]
671 @_target_task("ship_desktop")
672 def target_tasks_ship_desktop(full_task_graph
, parameters
, graph_config
):
673 """Select the set of tasks required to ship desktop.
674 Previous build deps will be optimized out via action task."""
675 is_rc
= parameters
.get("release_type") == "release-rc"
677 # ship_firefox_rc runs after `promote` rather than `push`; include
679 filtered_for_candidates
= target_tasks_promote_desktop(
685 # ship_firefox runs after `push`; include all push tasks.
686 filtered_for_candidates
= target_tasks_push_desktop(
693 if not filter_out_missing_signoffs(task
, parameters
):
695 # Include promotion tasks; these will be optimized out
696 if task
.label
in filtered_for_candidates
:
700 task
.attributes
.get("shipping_product") != parameters
["release_product"]
701 or task
.attributes
.get("shipping_phase") != "ship"
705 if "secondary" in task
.kind
:
709 return [l
for l
, t
in full_task_graph
.tasks
.items() if filter(t
)]
712 @_target_task("pine_tasks")
713 def target_tasks_pine(full_task_graph
, parameters
, graph_config
):
714 """Bug 1879960 - no reftests or wpt needed"""
715 filtered_for_project
= target_tasks_default(
716 full_task_graph
, parameters
, graph_config
720 suite
= task
.attributes
.get("unittest_suite", "")
721 if "reftest" in suite
or "web-platform" in suite
:
725 return [l
for l
in filtered_for_project
if filter(full_task_graph
[l
])]
728 @_target_task("larch_tasks")
729 def target_tasks_larch(full_task_graph
, parameters
, graph_config
):
730 """Bug 1879213 - only run necessary tasks on larch"""
731 filtered_for_project
= target_tasks_default(
732 full_task_graph
, parameters
, graph_config
736 # no localized builds, no android
739 or "msix" in task
.kind
740 or "android" in task
.attributes
.get("build_platform", "")
741 or (task
.kind
== "test" and "msix" in task
.label
)
744 # otherwise reduce tests only
745 if task
.kind
!= "test":
747 return "browser-chrome" in task
.label
or "xpcshell" in task
.label
749 return [l
for l
in filtered_for_project
if filter(full_task_graph
[l
])]
752 @_target_task("kaios_tasks")
753 def target_tasks_kaios(full_task_graph
, parameters
, graph_config
):
754 """The set of tasks to run for kaios integration"""
757 # We disable everything in central, and adjust downstream.
760 return [l
for l
, t
in full_task_graph
.tasks
.items() if filter(t
)]
763 @_target_task("custom-car_perf_testing")
764 def target_tasks_custom_car_perf_testing(full_task_graph
, parameters
, graph_config
):
765 """Select tasks required for running daily performance tests for custom chromium-as-release."""
768 platform
= task
.attributes
.get("test_platform")
769 attributes
= task
.attributes
770 if attributes
.get("unittest_suite") != "raptor":
773 try_name
= attributes
.get("raptor_try_name")
775 # Desktop and Android selection for CaR
776 if accept_raptor_desktop_build(platform
) or accept_raptor_android_build(
779 if "browsertime" in try_name
and (
780 "custom-car" in try_name
or "cstm-car-m" in try_name
782 if "hw-s21" in platform
and "speedometer3" not in try_name
:
787 return [l
for l
, t
in full_task_graph
.tasks
.items() if filter(t
)]
790 @_target_task("general_perf_testing")
791 def target_tasks_general_perf_testing(full_task_graph
, parameters
, graph_config
):
793 Select tasks required for running performance tests 3 times a week.
797 platform
= task
.attributes
.get("test_platform")
798 attributes
= task
.attributes
799 if attributes
.get("unittest_suite") != "raptor":
802 try_name
= attributes
.get("raptor_try_name")
804 if "tp6-bench" in try_name
:
807 if "tp7" in try_name
:
810 # Bug 1867669 - Temporarily disable all live site tests
811 if "live" in try_name
and "sheriffed" not in try_name
:
815 if accept_raptor_desktop_build(platform
):
816 # Select some browsertime tasks as desktop smoke-tests
817 if "browsertime" in try_name
:
818 if "chrome" in try_name
:
819 if "tp6" in try_name
and "essential" not in try_name
:
822 # chromium-as-release has its own cron
823 if "custom-car" in try_name
:
825 if "-live" in try_name
:
827 if "-fis" in try_name
:
829 if "linux" in platform
:
830 if "speedometer" in try_name
:
832 if "safari" and "benchmark" in try_name
:
835 elif accept_raptor_android_build(platform
):
836 if "hw-s21" in platform
and "speedometer3" not in try_name
:
838 if "chrome-m" in try_name
and (
839 ("ebay" in try_name
and "live" not in try_name
)
842 and ("facebook" in try_name
or "dailymail" in try_name
)
846 # Ignore all fennec tests here, we run those weekly
847 if "fennec" in try_name
:
849 # Only run webrender tests
850 if "chrome-m" not in try_name
and "-qr" not in platform
:
852 # Select live site tests
853 if "-live" in try_name
:
855 # Select fenix resource usage tests
856 if "fenix" in try_name
:
857 # Bug 1816421 disable fission perf tests
858 if "-fis" in try_name
:
860 if "-power" in try_name
:
862 # Select geckoview resource usage tests
863 if "geckoview" in try_name
:
864 # Bug 1816421 disable fission perf tests
865 if "-fis" in try_name
:
867 # Run cpu+memory, and power tests
868 cpu_n_memory_task
= "-cpu" in try_name
and "-memory" in try_name
869 power_task
= "-power" in try_name
870 # Ignore cpu+memory+power tests
871 if power_task
and cpu_n_memory_task
:
873 if cpu_n_memory_task
:
876 return "browsertime" in try_name
877 # Select browsertime-specific tests
878 if "browsertime" in try_name
:
879 # Don't run android CaR sp tests as we already have a cron for this.
880 if "m-car" in try_name
:
882 if "fenix" in try_name
:
884 if "speedometer" in try_name
:
886 if "motionmark" in try_name
and "1-3" in try_name
:
887 if "chrome-m" in try_name
:
891 return [l
for l
, t
in full_task_graph
.tasks
.items() if filter(t
)]
894 def make_desktop_nightly_filter(platforms
):
895 """Returns a filter that gets all nightly tasks on the given platform."""
897 def filter(task
, parameters
):
900 filter_on_platforms(task
, platforms
),
901 filter_for_project(task
, parameters
),
902 task
.attributes
.get("shippable", False),
903 # Tests and nightly only builds don't have `shipping_product` set
904 task
.attributes
.get("shipping_product")
905 in {None, "firefox", "thunderbird"},
906 task
.kind
not in {"l10n"}, # no on-change l10n
913 @_target_task("sp-perftests")
914 def target_tasks_speedometer_tests(full_task_graph
, parameters
, graph_config
):
916 platform
= task
.attributes
.get("test_platform")
917 attributes
= task
.attributes
918 if attributes
.get("unittest_suite") != "raptor":
921 if accept_raptor_desktop_build(platform
) or accept_raptor_android_build(
924 try_name
= attributes
.get("raptor_try_name")
925 if "hw-s21" in platform
and "speedometer3" not in try_name
:
928 "browsertime" in try_name
929 and "speedometer" in try_name
930 and "chrome" in try_name
934 return [l
for l
, t
in full_task_graph
.tasks
.items() if filter(t
)]
937 @_target_task("nightly_linux")
938 def target_tasks_nightly_linux(full_task_graph
, parameters
, graph_config
):
939 """Select the set of tasks required for a nightly build of linux. The
940 nightly build process involves a pipeline of builds, signing,
941 and, eventually, uploading the tasks to balrog."""
942 filter = make_desktop_nightly_filter(
943 {"linux64-shippable", "linux-shippable", "linux64-aarch64-shippable"}
945 return [l
for l
, t
in full_task_graph
.tasks
.items() if filter(t
, parameters
)]
948 @_target_task("nightly_macosx")
949 def target_tasks_nightly_macosx(full_task_graph
, parameters
, graph_config
):
950 """Select the set of tasks required for a nightly build of macosx. The
951 nightly build process involves a pipeline of builds, signing,
952 and, eventually, uploading the tasks to balrog."""
953 filter = make_desktop_nightly_filter({"macosx64-shippable"})
954 return [l
for l
, t
in full_task_graph
.tasks
.items() if filter(t
, parameters
)]
957 @_target_task("nightly_win32")
958 def target_tasks_nightly_win32(full_task_graph
, parameters
, graph_config
):
959 """Select the set of tasks required for a nightly build of win32 and win64.
960 The nightly build process involves a pipeline of builds, signing,
961 and, eventually, uploading the tasks to balrog."""
962 filter = make_desktop_nightly_filter({"win32-shippable"})
963 return [l
for l
, t
in full_task_graph
.tasks
.items() if filter(t
, parameters
)]
966 @_target_task("nightly_win64")
967 def target_tasks_nightly_win64(full_task_graph
, parameters
, graph_config
):
968 """Select the set of tasks required for a nightly build of win32 and win64.
969 The nightly build process involves a pipeline of builds, signing,
970 and, eventually, uploading the tasks to balrog."""
971 filter = make_desktop_nightly_filter({"win64-shippable"})
972 return [l
for l
, t
in full_task_graph
.tasks
.items() if filter(t
, parameters
)]
975 @_target_task("nightly_win64_aarch64")
976 def target_tasks_nightly_win64_aarch64(full_task_graph
, parameters
, graph_config
):
977 """Select the set of tasks required for a nightly build of win32 and win64.
978 The nightly build process involves a pipeline of builds, signing,
979 and, eventually, uploading the tasks to balrog."""
980 filter = make_desktop_nightly_filter({"win64-aarch64-shippable"})
981 return [l
for l
, t
in full_task_graph
.tasks
.items() if filter(t
, parameters
)]
984 @_target_task("nightly_asan")
985 def target_tasks_nightly_asan(full_task_graph
, parameters
, graph_config
):
986 """Select the set of tasks required for a nightly build of asan. The
987 nightly build process involves a pipeline of builds, signing,
988 and, eventually, uploading the tasks to balrog."""
989 filter = make_desktop_nightly_filter(
990 {"linux64-asan-reporter-shippable", "win64-asan-reporter-shippable"}
992 return [l
for l
, t
in full_task_graph
.tasks
.items() if filter(t
, parameters
)]
995 @_target_task("daily_releases")
996 def target_tasks_daily_releases(full_task_graph
, parameters
, graph_config
):
997 """Select the set of tasks required to identify if we should release.
998 If we determine that we should the task will communicate to ship-it to
999 schedule the release itself."""
1002 return task
.kind
in ["maybe-release"]
1004 return [l
for l
, t
in full_task_graph
.tasks
.items() if filter(t
)]
1007 @_target_task("nightly_desktop")
1008 def target_tasks_nightly_desktop(full_task_graph
, parameters
, graph_config
):
1009 """Select the set of tasks required for a nightly build of linux, mac,
1012 f
"{graph_config['trust-domain']}.v2.{parameters['project']}.revision."
1013 f
"{parameters['head_rev']}.taskgraph.decision-nightly-desktop"
1015 if os
.environ
.get("MOZ_AUTOMATION") and retry(
1019 "reason": "to avoid triggering multiple nightlies off the same revision",
1024 # Tasks that aren't platform specific
1025 release_filter
= make_desktop_nightly_filter({None}
)
1027 l
for l
, t
in full_task_graph
.tasks
.items() if release_filter(t
, parameters
)
1029 # Avoid duplicate tasks.
1031 set(target_tasks_nightly_win32(full_task_graph
, parameters
, graph_config
))
1032 |
set(target_tasks_nightly_win64(full_task_graph
, parameters
, graph_config
))
1034 target_tasks_nightly_win64_aarch64(
1035 full_task_graph
, parameters
, graph_config
1038 |
set(target_tasks_nightly_macosx(full_task_graph
, parameters
, graph_config
))
1039 |
set(target_tasks_nightly_linux(full_task_graph
, parameters
, graph_config
))
1040 |
set(target_tasks_nightly_asan(full_task_graph
, parameters
, graph_config
))
1041 |
set(release_tasks
)
1045 @_target_task("nightly_all")
1046 def target_tasks_nightly_all(full_task_graph
, parameters
, graph_config
):
1047 """Select the set of tasks required for a nightly build of firefox desktop and android"""
1049 f
"{graph_config['trust-domain']}.v2.{parameters['project']}.revision."
1050 f
"{parameters['head_rev']}.taskgraph.decision-nightly-all"
1052 if os
.environ
.get("MOZ_AUTOMATION") and retry(
1056 "reason": "to avoid triggering multiple nightlies off the same revision",
1062 set(target_tasks_nightly_desktop(full_task_graph
, parameters
, graph_config
))
1063 |
set(target_tasks_nightly_android(full_task_graph
, parameters
, graph_config
))
1067 # Run Searchfox analysis once daily.
1068 @_target_task("searchfox_index")
1069 def target_tasks_searchfox(full_task_graph
, parameters
, graph_config
):
1070 """Select tasks required for indexing Firefox for Searchfox web site each day"""
1072 "searchfox-linux64-searchfox/debug",
1073 "searchfox-macosx64-searchfox/debug",
1074 "searchfox-win64-searchfox/debug",
1075 "searchfox-android-armv7-searchfox/debug",
1076 "searchfox-ios-searchfox/debug",
1077 "source-test-file-metadata-bugzilla-components",
1078 "source-test-file-metadata-test-info-all",
1079 "source-test-wpt-metadata-summary",
1083 # Run build linux64-plain-clang-trunk/opt on mozilla-central/beta with perf tests
1084 @_target_task("linux64_clang_trunk_perf")
1085 def target_tasks_build_linux64_clang_trunk_perf(
1086 full_task_graph
, parameters
, graph_config
1088 """Select tasks required to run perf test on linux64 build with clang trunk"""
1090 # Only keep tasks generated from platform `linux1804-64-clang-trunk-qr/opt`
1091 def filter(task_label
):
1092 if "linux1804-64-clang-trunk-qr/opt" in task_label
:
1096 return [l
for l
, t
in full_task_graph
.tasks
.items() if filter(t
.label
)]
1099 # Run Updatebot's cron job 4 times daily.
1100 @_target_task("updatebot_cron")
1101 def target_tasks_updatebot_cron(full_task_graph
, parameters
, graph_config
):
1102 """Select tasks required to run Updatebot's cron job"""
1103 return ["updatebot-cron"]
1106 @_target_task("customv8_update")
1107 def target_tasks_customv8_update(full_task_graph
, parameters
, graph_config
):
1108 """Select tasks required for building latest d8/v8 version."""
1109 return ["toolchain-linux64-custom-v8"]
1112 @_target_task("file_update")
1113 def target_tasks_file_update(full_task_graph
, parameters
, graph_config
):
1114 """Select the set of tasks required to perform nightly in-tree file updates"""
1117 # For now any task in the repo-update kind is ok
1118 return task
.kind
in ["repo-update"]
1120 return [l
for l
, t
in full_task_graph
.tasks
.items() if filter(t
)]
1123 @_target_task("l10n_bump")
1124 def target_tasks_l10n_bump(full_task_graph
, parameters
, graph_config
):
1125 """Select the set of tasks required to perform l10n bumping."""
1128 # For now any task in the repo-update kind is ok
1129 return task
.kind
in ["l10n-bump"]
1131 return [l
for l
, t
in full_task_graph
.tasks
.items() if filter(t
)]
1134 @_target_task("merge_automation")
1135 def target_tasks_merge_automation(full_task_graph
, parameters
, graph_config
):
1136 """Select the set of tasks required to perform repository merges."""
1139 # For now any task in the repo-update kind is ok
1140 return task
.kind
in ["merge-automation"]
1142 return [l
for l
, t
in full_task_graph
.tasks
.items() if filter(t
)]
1145 @_target_task("scriptworker_canary")
1146 def target_tasks_scriptworker_canary(full_task_graph
, parameters
, graph_config
):
1147 """Select the set of tasks required to run scriptworker canaries."""
1150 # For now any task in the repo-update kind is ok
1151 return task
.kind
in ["scriptworker-canary"]
1153 return [l
for l
, t
in full_task_graph
.tasks
.items() if filter(t
)]
1156 @_target_task("cron_bouncer_check")
1157 def target_tasks_bouncer_check(full_task_graph
, parameters
, graph_config
):
1158 """Select the set of tasks required to perform bouncer version verification."""
1161 if not filter_for_project(task
, parameters
):
1163 # For now any task in the repo-update kind is ok
1164 return task
.kind
in ["cron-bouncer-check"]
1166 return [l
for l
, t
in full_task_graph
.tasks
.items() if filter(t
)]
1169 @_target_task("staging_release_builds")
1170 def target_tasks_staging_release(full_task_graph
, parameters
, graph_config
):
1172 Select all builds that are part of releases.
1176 if not task
.attributes
.get("shipping_product"):
1178 if parameters
["release_type"].startswith(
1180 ) and "android" in task
.attributes
.get("build_platform", ""):
1182 if parameters
["release_type"] != "beta" and "devedition" in task
.attributes
.get(
1183 "build_platform", ""
1186 if task
.attributes
.get("shipping_phase") == "build":
1190 return [l
for l
, t
in full_task_graph
.tasks
.items() if filter(t
)]
1193 @_target_task("release_simulation")
1194 def target_tasks_release_simulation(full_task_graph
, parameters
, graph_config
):
1196 Select builds that would run on push on a release branch.
1198 project_by_release
= {
1199 "nightly": "mozilla-central",
1200 "beta": "mozilla-beta",
1201 "release": "mozilla-release",
1202 "esr115": "mozilla-esr115",
1204 target_project
= project_by_release
.get(parameters
["release_type"])
1205 if target_project
is None:
1206 raise Exception("Unknown or unspecified release type in simulation run.")
1208 def filter_for_target_project(task
):
1209 """Filter tasks by project. Optionally enable nightlies."""
1210 run_on_projects
= set(task
.attributes
.get("run_on_projects", []))
1211 return match_run_on_projects(target_project
, run_on_projects
)
1213 def filter_out_android_on_esr(task
):
1214 if parameters
["release_type"].startswith(
1216 ) and "android" in task
.attributes
.get("build_platform", ""):
1222 for l
, t
in full_task_graph
.tasks
.items()
1223 if filter_release_tasks(t
, parameters
)
1224 and filter_out_cron(t
, parameters
)
1225 and filter_for_target_project(t
)
1226 and filter_out_android_on_esr(t
)
1230 @_target_task("codereview")
1231 def target_tasks_codereview(full_task_graph
, parameters
, graph_config
):
1232 """Select all code review tasks needed to produce a report"""
1236 if task
.kind
in ["code-review"]:
1240 if task
.attributes
.get("code-review") is True:
1245 return [l
for l
, t
in full_task_graph
.tasks
.items() if filter(t
)]
1248 @_target_task("nothing")
1249 def target_tasks_nothing(full_task_graph
, parameters
, graph_config
):
1250 """Select nothing, for DONTBUILD pushes"""
1254 @_target_task("daily_beta_perf")
1255 def target_tasks_daily_beta_perf(full_task_graph
, parameters
, graph_config
):
1257 Select performance tests on the beta branch to be run daily
1260 f
"{graph_config['trust-domain']}.v2.{parameters['project']}.revision."
1261 f
"{parameters['head_rev']}.taskgraph.decision-daily-beta-perf"
1263 if os
.environ
.get("MOZ_AUTOMATION") and retry(
1267 "reason": "to avoid triggering multiple daily beta perftests off of the same revision",
1273 platform
= task
.attributes
.get("test_platform")
1274 attributes
= task
.attributes
1275 try_name
= attributes
.get("raptor_try_name") or task
.label
1277 unittest_suite
= attributes
.get("unittest_suite")
1278 if unittest_suite
not in ("raptor", "awsy", "talos"):
1283 # Select beta tasks for awsy
1284 if "awsy" in try_name
:
1285 if accept_awsy_task(try_name
, platform
):
1289 # Select beta tasks for talos
1290 if "talos" == unittest_suite
:
1291 if accept_raptor_desktop_build(platform
):
1292 if "windows11-64" in platform
:
1293 if "xperf" in try_name
:
1296 if ("mac" in platform
or "windows" in platform
) and "g3" in try_name
:
1298 if "-swr" in try_name
:
1299 if "dromaeo" in try_name
:
1301 if "perf-reftest-singletons" in try_name
:
1303 if "realworldweb" in try_name
:
1307 for x
in ("prof", "ipc", "gli", "sessionrestore", "tabswitch")
1313 if accept_raptor_desktop_build(platform
):
1314 if "browsertime" and "firefox" in try_name
:
1315 if "profiling" in try_name
:
1317 if "bytecode" in try_name
:
1319 if "live" in try_name
:
1321 if "webext" in try_name
:
1323 if "unity" in try_name
:
1325 if "wasm" in try_name
:
1327 if "tp6-bench" in try_name
:
1329 if "tp6" in try_name
:
1331 if "benchmark" in try_name
:
1333 elif accept_raptor_android_build(platform
):
1334 # Select browsertime & geckoview specific tests
1335 if "browsertime" and "geckoview" in try_name
:
1336 if "power" in try_name
:
1338 if "cpu" in try_name
:
1340 if "profiling" in try_name
:
1342 if "-live" in try_name
:
1344 if "speedometer" in try_name
:
1346 if "webgl" in try_name
:
1348 if "tp6m" in try_name
:
1353 return [l
for l
, t
in full_task_graph
.tasks
.items() if filter(t
)]
1356 @_target_task("weekly_release_perf")
1357 def target_tasks_weekly_release_perf(full_task_graph
, parameters
, graph_config
):
1359 Select performance tests on the release branch to be run weekly
1363 platform
= task
.attributes
.get("test_platform")
1364 attributes
= task
.attributes
1365 try_name
= attributes
.get("raptor_try_name") or task
.label
1367 if attributes
.get("unittest_suite") not in ("raptor", "awsy"):
1372 # Select release tasks for awsy
1373 if "awsy" in try_name
:
1374 if accept_awsy_task(try_name
, platform
):
1378 # Select browsertime tests
1379 if accept_raptor_desktop_build(platform
):
1380 if "browsertime" and "firefox" in try_name
:
1381 if "power" in try_name
:
1383 if "profiling" in try_name
:
1385 if "bytecode" in try_name
:
1387 if "live" in try_name
:
1389 if "webext" in try_name
:
1391 if "tp6-bench" in try_name
:
1393 if "tp6" in try_name
:
1395 if "benchmark" in try_name
:
1397 if "youtube-playback" in try_name
:
1399 elif accept_raptor_android_build(platform
):
1400 # Select browsertime & geckoview specific tests
1401 if "browsertime" and "geckoview" in try_name
:
1402 if "power" in try_name
:
1404 if "cpu" in try_name
:
1406 if "profiling" in try_name
:
1408 if "-live" in try_name
:
1410 if "speedometer" in try_name
:
1412 if "webgl" in try_name
:
1414 if "tp6m" in try_name
:
1416 if "youtube-playback" in try_name
:
1421 return [l
for l
, t
in full_task_graph
.tasks
.items() if filter(t
)]
1424 @_target_task("raptor_tp6m")
1425 def target_tasks_raptor_tp6m(full_task_graph
, parameters
, graph_config
):
1427 Select tasks required for running raptor cold page-load tests on fenix and refbrow
1431 platform
= task
.attributes
.get("build_platform")
1432 attributes
= task
.attributes
1434 if platform
and "android" not in platform
:
1436 if attributes
.get("unittest_suite") != "raptor":
1438 try_name
= attributes
.get("raptor_try_name")
1439 if "-cold" in try_name
and "shippable" in platform
:
1440 # Get browsertime amazon smoke tests
1442 "browsertime" in try_name
1443 and "amazon" in try_name
1444 and "search" not in try_name
1448 return [l
for l
, t
in full_task_graph
.tasks
.items() if filter(t
)]
1451 @_target_task("backfill_all_browsertime")
1452 def target_tasks_backfill_all_browsertime(full_task_graph
, parameters
, graph_config
):
1454 Search for revisions that contains patches that were reviewed by perftest reviewers
1455 and landed the day before the cron is running. Trigger backfill-all-browsertime action
1456 task on each of them.
1458 from gecko_taskgraph
.actions
.util
import get_decision_task_id
, get_pushes
1460 def date_is_yesterday(date
):
1461 yesterday
= datetime
.today() - timedelta(days
=1)
1462 date
= datetime
.fromtimestamp(date
)
1463 return date
.date() == yesterday
.date()
1465 def reviewed_by_perftest(push
):
1467 commit_message
= get_hg_commit_message(
1468 os
.path
.join(GECKO
, graph_config
["product-dir"]), rev
=push
1470 except Exception as e
:
1474 for line
in commit_message
.split("\n\n"):
1475 if line
.lower().startswith("bug ") and "r=" in line
:
1476 if "perftest-reviewers" in line
.split("r=")[-1]:
1481 pushes
= get_pushes(
1482 project
=parameters
["head_repository"],
1483 end_id
=int(parameters
["pushlog_id"]),
1487 for push_id
in sorted([int(p
) for p
in pushes
.keys()], reverse
=True):
1488 push_rev
= pushes
[str(push_id
)]["changesets"][-1]
1489 push_info
= find_hg_revision_push_info(
1490 "https://hg.mozilla.org/integration/" + parameters
["project"], push_rev
1492 pushdate
= int(push_info
["pushdate"])
1493 if date_is_yesterday(pushdate
) and reviewed_by_perftest(push_rev
):
1494 from gecko_taskgraph
.actions
.util
import trigger_action
1497 f
"Revision {push_rev} was created yesterday and was reviewed by "
1498 f
"#perftest-reviewers."
1501 push_decision_task_id
= get_decision_task_id(
1502 parameters
["project"], push_id
1505 print(f
"Could not find decision task for push {push_id}")
1509 action_name
="backfill-all-browsertime",
1510 # This lets the action know on which push we want to add a new task
1511 decision_task_id
=push_decision_task_id
,
1513 except Exception as e
:
1514 print(f
"Failed to trigger action for {push_rev}: {e}")
1519 @_target_task("condprof")
1520 def target_tasks_condprof(full_task_graph
, parameters
, graph_config
):
1522 Select tasks required for building conditioned profiles.
1524 for name
, task
in full_task_graph
.tasks
.items():
1525 if task
.kind
== "condprof":
1526 if "a51" not in name
: # bug 1765348
1530 @_target_task("system_symbols")
1531 def target_tasks_system_symbols(full_task_graph
, parameters
, graph_config
):
1533 Select tasks for scraping and uploading system symbols.
1535 for name
, task
in full_task_graph
.tasks
.items():
1538 "system-symbols-upload",
1539 "system-symbols-reprocess",
1544 @_target_task("perftest")
1545 def target_tasks_perftest(full_task_graph
, parameters
, graph_config
):
1547 Select perftest tasks we want to run daily
1549 for name
, task
in full_task_graph
.tasks
.items():
1550 if task
.kind
!= "perftest":
1552 if task
.attributes
.get("cron", False):
1556 @_target_task("perftest-on-autoland")
1557 def target_tasks_perftest_autoland(full_task_graph
, parameters
, graph_config
):
1559 Select perftest tasks we want to run daily
1561 for name
, task
in full_task_graph
.tasks
.items():
1562 if task
.kind
!= "perftest":
1564 if task
.attributes
.get("cron", False) and any(
1565 test_name
in name
for test_name
in ["view"]
1570 @_target_task("l10n-cross-channel")
1571 def target_tasks_l10n_cross_channel(full_task_graph
, parameters
, graph_config
):
1572 """Select the set of tasks required to run l10n cross-channel."""
1575 return task
.kind
in ["l10n-cross-channel"]
1577 return [l
for l
, t
in full_task_graph
.tasks
.items() if filter(t
)]
1580 @_target_task("eslint-build")
1581 def target_tasks_eslint_build(full_task_graph
, parameters
, graph_config
):
1582 """Select the task to run additional ESLint rules which require a build."""
1584 for name
, task
in full_task_graph
.tasks
.items():
1585 if task
.kind
!= "source-test":
1587 if "eslint-build" in name
:
1591 @_target_task("holly_tasks")
1592 def target_tasks_holly(full_task_graph
, parameters
, graph_config
):
1593 """Bug 1814661: only run updatebot tasks on holly"""
1596 return task
.kind
== "updatebot"
1598 return [l
for l
, t
in full_task_graph
.tasks
.items() if filter(t
)]
1601 @_target_task("snap_upstream_tests")
1602 def target_tasks_snap_upstream_tests(full_task_graph
, parameters
, graph_config
):
1604 Select tasks for testing Snap package built as upstream. Omit -try because
1605 it does not really make sense on a m-c cron
1607 for name
, task
in full_task_graph
.tasks
.items():
1608 if "snap-upstream-test" in name
and not "-try" in name
:
1612 @_target_task("nightly-android")
1613 def target_tasks_nightly_android(full_task_graph
, parameters
, graph_config
):
1614 def filter(task
, parameters
):
1616 if task
.attributes
.get("shipping_product") == "fennec" and task
.kind
in (
1617 "beetmover-geckoview",
1623 build_type
= task
.attributes
.get("build-type", "")
1624 return build_type
in (
1628 "fenix-nightly-firebase",
1629 "focus-nightly-firebase",
1633 f
"{graph_config['trust-domain']}.v2.{parameters['project']}.branch."
1634 f
"{parameters['head_ref']}.revision.{parameters['head_rev']}.taskgraph.decision-nightly-android"
1636 if os
.environ
.get("MOZ_AUTOMATION") and retry(
1640 "reason": "to avoid triggering multiple nightlies off the same revision",
1645 return [l
for l
, t
in full_task_graph
.tasks
.items() if filter(t
, parameters
)]
1648 @_target_task("android-l10n-import")
1649 def target_tasks_android_l10n_import(full_task_graph
, parameters
, graph_config
):
1650 return [l
for l
, t
in full_task_graph
.tasks
.items() if l
== "android-l10n-import"]
1653 @_target_task("android-l10n-sync")
1654 def target_tasks_android_l10n_sync(full_task_graph
, parameters
, graph_config
):
1655 return [l
for l
, t
in full_task_graph
.tasks
.items() if l
== "android-l10n-sync"]