summaryrefslogtreecommitdiffstats
path: root/comm/taskcluster/comm_taskgraph/transforms/job/toolchain.py
diff options
context:
space:
mode:
Diffstat (limited to 'comm/taskcluster/comm_taskgraph/transforms/job/toolchain.py')
-rw-r--r--comm/taskcluster/comm_taskgraph/transforms/job/toolchain.py165
1 files changed, 165 insertions, 0 deletions
diff --git a/comm/taskcluster/comm_taskgraph/transforms/job/toolchain.py b/comm/taskcluster/comm_taskgraph/transforms/job/toolchain.py
new file mode 100644
index 0000000000..a80c058a2b
--- /dev/null
+++ b/comm/taskcluster/comm_taskgraph/transforms/job/toolchain.py
@@ -0,0 +1,165 @@
+# 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/.
+"""
+Support for running toolchain-building jobs via dedicated scripts in comm-central
+"""
+
+import os.path
+
+import taskgraph
+import taskgraph.util.path as util_path
+from taskgraph.util.schema import resolve_keyed_by
+from voluptuous import Any, Optional, Required
+
+from gecko_taskgraph import GECKO
+from gecko_taskgraph.transforms.job import configure_taskdesc_for_run, run_job_using
+from gecko_taskgraph.transforms.job.common import docker_worker_add_artifacts
+from gecko_taskgraph.transforms.job.toolchain import toolchain_defaults, toolchain_run_schema
+from gecko_taskgraph.util.attributes import RELEASE_PROJECTS
+from gecko_taskgraph.util.hash import hash_paths as hash_paths_gecko_root
+
+from comm_taskgraph.util.hash import hash_paths_extended
+
+CACHE_TYPE = "toolchains.v3"
+
+TOOLCHAIN_SCRIPT_PATH = "comm/taskcluster/scripts"
+
+
+comm_toolchain_run_schema = toolchain_run_schema.extend(
+ {
+ Required("using"): Any("comm-toolchain-script"),
+ Optional("script"): str,
+ }
+)
+
+
+def hash_paths(*args):
+ """
+ Helper function while the single repository project is in development.
+ The extended version of hash_paths found in comm_taskgraph.util.hash is
+ not necessary (and does not work) with single-repo. This is a wrapper
+ function to pick the right function based on the presence of a comm/.hg
+ directory.
+ """
+ comm_hg_path = util_path.join(GECKO, "comm", ".hg")
+ if os.path.exists(comm_hg_path):
+ return hash_paths_extended(*args)
+ else:
+ return hash_paths_gecko_root(*args)
+
+
+def get_digest_data(config, run, taskdesc):
+ """
+ Copied from gecko_taskgraph.transforms.job.toolchain, with minor
+ modifications to support the required script path.
+ """
+ files = list(run.pop("resources", []))
+ # This file
+ files.append("comm/taskcluster/comm_taskgraph/transforms/job/toolchain.py")
+ # The script
+ if "script" in run:
+ files.append("{}/{}".format(TOOLCHAIN_SCRIPT_PATH, run["script"]))
+ # Tooltool manifest if any is defined:
+ tooltool_manifest = taskdesc["worker"]["env"].get("TOOLTOOL_MANIFEST")
+ if tooltool_manifest:
+ files.append(tooltool_manifest)
+
+ # Accumulate dependency hashes for index generation.
+ data = [hash_paths(GECKO, files)]
+
+ data.append(taskdesc["attributes"]["toolchain-artifact"])
+
+ # If the task uses an in-tree docker image, we want it to influence
+ # the index path as well. Ideally, the content of the docker image itself
+ # should have an influence, but at the moment, we can't get that
+ # information here. So use the docker image name as a proxy. Not a lot of
+ # changes to docker images actually have an impact on the resulting
+ # toolchain artifact, so we'll just rely on such important changes to be
+ # accompanied with a docker image name change.
+ image = taskdesc["worker"].get("docker-image", {}).get("in-tree")
+ if image:
+ data.append(image)
+
+ # Likewise script arguments should influence the index.
+ args = run.get("arguments")
+ if args:
+ data.extend(args)
+
+ if taskdesc["attributes"].get("rebuild-on-release"):
+ # Add whether this is a release branch or not
+ data.append(str(config.params["project"] in RELEASE_PROJECTS))
+ return data
+
+
+@run_job_using(
+ "docker-worker",
+ "comm-toolchain-script",
+ schema=comm_toolchain_run_schema,
+ defaults=toolchain_defaults,
+)
+def docker_worker_toolchain(config, job, taskdesc):
+ run = job["run"]
+ run["comm-checkout"] = True
+
+ worker = taskdesc["worker"] = job["worker"]
+ worker["chain-of-trust"] = True
+
+ # If the task doesn't have a docker-image, set a default
+ worker.setdefault("docker-image", {"in-tree": "deb11-toolchain-build"})
+
+ # Toolchain checkouts don't live under {workdir}/checkouts
+ workspace = "{workdir}/workspace/build".format(**run)
+ gecko_path = "{}/src".format(workspace)
+
+ env = worker.setdefault("env", {})
+ env.update(
+ {
+ "MOZ_BUILD_DATE": config.params["moz_build_date"],
+ "MOZ_SCM_LEVEL": config.params["level"],
+ "GECKO_PATH": gecko_path,
+ "TOOLCHAIN_ARTIFACT": run["toolchain-artifact"],
+ }
+ )
+
+ attributes = taskdesc.setdefault("attributes", {})
+ attributes["toolchain-artifact"] = run.pop("toolchain-artifact")
+ toolchain_artifact = attributes["toolchain-artifact"]
+ if not toolchain_artifact.startswith("public/build/"):
+ attributes["artifact_prefix"] = os.path.dirname(toolchain_artifact)
+
+ resolve_keyed_by(
+ run,
+ "toolchain-alias",
+ item_name=taskdesc["label"],
+ project=config.params["project"],
+ )
+ alias = run.pop("toolchain-alias", None)
+ if alias:
+ attributes["toolchain-alias"] = alias
+ if "toolchain-env" in run:
+ attributes["toolchain-env"] = run.pop("toolchain-env")
+
+ # Allow the job to specify where artifacts come from, but add
+ # public/build if it's not there already.
+ artifacts = worker.setdefault("artifacts", [])
+ if not artifacts:
+ docker_worker_add_artifacts(config, job, taskdesc)
+
+ digest_data = get_digest_data(config, run, taskdesc)
+
+ if job.get("attributes", {}).get("cached_task") is not False and not taskgraph.fast:
+ name = taskdesc["label"].replace(f"{config.kind}-", "", 1)
+ taskdesc["cache"] = {
+ "type": CACHE_TYPE,
+ "name": name,
+ "digest-data": digest_data,
+ }
+
+ run["using"] = "run-task"
+ run["cwd"] = run["workdir"]
+ run["command"] = [
+ "workspace/build/src/{}/{}".format(TOOLCHAIN_SCRIPT_PATH, run.pop("script"))
+ ] + run.pop("arguments", [])
+
+ configure_taskdesc_for_run(config, job, taskdesc, worker["implementation"])