summaryrefslogtreecommitdiffstats
path: root/comm/taskcluster/comm_taskgraph/decision.py
diff options
context:
space:
mode:
Diffstat (limited to 'comm/taskcluster/comm_taskgraph/decision.py')
-rw-r--r--comm/taskcluster/comm_taskgraph/decision.py162
1 files changed, 162 insertions, 0 deletions
diff --git a/comm/taskcluster/comm_taskgraph/decision.py b/comm/taskcluster/comm_taskgraph/decision.py
new file mode 100644
index 0000000000..a075b47cf5
--- /dev/null
+++ b/comm/taskcluster/comm_taskgraph/decision.py
@@ -0,0 +1,162 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+import logging
+import os
+import sys
+
+from redo import retry
+from taskgraph.decision import (
+ _determine_more_accurate_base_ref,
+ _determine_more_accurate_base_rev,
+ _get_env_prefix,
+)
+from taskgraph.taskgraph import TaskGraph
+from taskgraph.util.taskcluster import get_artifact
+from taskgraph.util.vcs import get_repository
+
+from gecko_taskgraph.util.backstop import is_backstop
+from gecko_taskgraph.util.partials import populate_release_history
+from gecko_taskgraph.util.taskgraph import (
+ find_decision_task,
+ find_existing_tasks_from_previous_kinds,
+)
+
+from . import COMM
+from comm_taskgraph.parameters import get_defaults
+
+logger = logging.getLogger(__name__)
+
+BALROG_PRODUCT = "Thunderbird"
+
+# Backstop defaults
+BACKSTOP_TIME_INTERVAL = 60 * 22 # minutes
+INTEGRATION_PROJECTS = {"comm-central"}
+
+PER_PROJECT_PARAMETERS = {
+ "ash": {
+ "target_tasks_method": "ash_tasks",
+ },
+ "jamun": {
+ "target_tasks_method": "nightly_desktop",
+ "release_type": "nightly",
+ },
+ "try-comm-central": {
+ "enable_always_target": True,
+ "target_tasks_method": "try_cc_tasks",
+ },
+ "comm-central": {
+ "target_tasks_method": "comm_central_tasks",
+ "release_type": "nightly",
+ },
+ "comm-beta": {
+ "target_tasks_method": "mozilla_beta_tasks",
+ "release_type": "beta",
+ },
+ "comm-esr115": {
+ "target_tasks_method": "mozilla_esr115_tasks",
+ "release_type": "release",
+ },
+}
+
+CRON_OPTIONS = {
+ "nightly_desktop": {
+ "existing_tasks": lambda parameters, graph_config: get_existing_tasks(
+ parameters, graph_config
+ ),
+ "release_history": lambda parameters, graph_config: populate_release_history(
+ BALROG_PRODUCT, parameters["project"]
+ ),
+ }
+}
+
+
+def get_decision_parameters(graph_config, parameters):
+ logger.info("{}.get_decision_parameters called".format(__name__))
+
+ # Apply default values for all Thunderbird CI projects
+ parameters.update(get_defaults(graph_config.vcs_root))
+
+ # If the target method is nightly, we should build partials. This means
+ # knowing what has been released previously.
+ # An empty release_history is fine, it just means no partials will be built
+ project = parameters["project"]
+
+ if project in PER_PROJECT_PARAMETERS:
+ # Upstream will set target_tasks_method to "default" when nothing is set
+ if parameters["target_tasks_method"] == "default":
+ del parameters["target_tasks_method"]
+
+ # If running from .cron.yml, do not overwrite existing parameters
+ update_parameters = [
+ (_k, _v)
+ for _k, _v in PER_PROJECT_PARAMETERS[project].items()
+ if _k not in parameters or not parameters[_k]
+ ]
+ parameters.update(update_parameters)
+ logger.info("project parameters set for project {} from {}.".format(project, __file__))
+ else:
+ # Projects without a target_tasks_method should not exist for Thunderbird CI
+ raise Exception("No target_tasks_method is defined for project {}.".format(project))
+
+ del parameters["backstop"]
+ parameters["backstop"] = is_backstop(
+ parameters,
+ trust_domain="comm",
+ time_interval=BACKSTOP_TIME_INTERVAL,
+ integration_projects=INTEGRATION_PROJECTS,
+ )
+ for n in (
+ "COMM_BASE_REPOSITORY",
+ "COMM_BASE_REV",
+ "COMM_HEAD_REPOSITORY",
+ "COMM_HEAD_REV",
+ "COMM_HEAD_REF",
+ ):
+ val = os.environ.get(n, "")
+ parameters[n.lower()] = val
+
+ repo_path = COMM
+ repo = get_repository(repo_path)
+ logger.info("Determining comm_base_ref...")
+ parameters["comm_base_ref"] = _determine_more_accurate_base_ref(
+ repo,
+ candidate_base_ref="",
+ head_ref=parameters.get("comm_head_ref"),
+ base_rev=parameters.get("comm_base_rev"),
+ )
+ logger.info("Determining comm_base_rev...")
+ parameters["comm_base_rev"] = _determine_more_accurate_base_rev(
+ repo,
+ base_ref=parameters["comm_base_ref"],
+ candidate_base_rev=parameters.get("comm_base_rev"),
+ head_rev=parameters.get("comm_head_rev"),
+ env_prefix=_get_env_prefix(graph_config),
+ )
+
+ parameters.setdefault("release_history", dict())
+ if parameters.get("tasks_for", "") == "cron":
+ for key, _callable in CRON_OPTIONS.get(parameters["target_tasks_method"], {}).items():
+ result = _callable(parameters, graph_config)
+ parameters[key] = result
+
+
+def get_existing_tasks(parameters, graph_config):
+ """
+ Find the decision task corresponding to the on-push graph, and return
+ a mapping of labels to task-ids from it.
+ """
+ try:
+ decision_task = retry(
+ find_decision_task,
+ args=(parameters, graph_config),
+ attempts=4,
+ sleeptime=5 * 60,
+ )
+ except Exception:
+ logger.exception("Didn't find existing push task.")
+ sys.exit(1)
+
+ _, task_graph = TaskGraph.from_json(get_artifact(decision_task, "public/full-task-graph.json"))
+ return find_existing_tasks_from_previous_kinds(task_graph, [decision_task], [])