207 lines
6.9 KiB
Python
207 lines
6.9 KiB
Python
# 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 datetime
|
|
|
|
from mozilla_version.mobile import GeckoVersion
|
|
from taskgraph.transforms.base import TransformSequence
|
|
from taskgraph.util.schema import resolve_keyed_by
|
|
|
|
from ..build_config import get_extensions, get_path
|
|
|
|
transforms = TransformSequence()
|
|
|
|
|
|
@transforms.add
|
|
def resolve_keys(config, tasks):
|
|
for task in tasks:
|
|
for field in (
|
|
"include-coverage",
|
|
"run-on-projects",
|
|
"shipping-phase",
|
|
"run.gradlew",
|
|
"treeherder.symbol",
|
|
"dependencies.build-fat-aar",
|
|
):
|
|
resolve_keyed_by(
|
|
task,
|
|
field,
|
|
item_name=task["name"],
|
|
**{
|
|
"build-type": task["attributes"]["build-type"],
|
|
"component": task["attributes"]["component"],
|
|
},
|
|
)
|
|
|
|
yield task
|
|
|
|
|
|
@transforms.add
|
|
def handle_update_channel(config, tasks):
|
|
for task in tasks:
|
|
build_fat_aar = config.kind_dependencies_tasks[
|
|
task["dependencies"]["build-fat-aar"]
|
|
]
|
|
if build_fat_aar.attributes.get("shippable"):
|
|
task["worker"].setdefault("env", {}).setdefault(
|
|
"MOZ_UPDATE_CHANNEL",
|
|
build_fat_aar.attributes.get("update-channel", "default"),
|
|
)
|
|
yield task
|
|
|
|
|
|
@transforms.add
|
|
def handle_coverage(config, tasks):
|
|
for task in tasks:
|
|
if task.pop("include-coverage", False):
|
|
task["run"]["gradlew"].insert(0, "-Pcoverage")
|
|
yield task
|
|
|
|
|
|
@transforms.add
|
|
def interpolate_missing_values(config, tasks):
|
|
timestamp = _get_timestamp(config)
|
|
version = config.params["version"]
|
|
nightly_version = get_nightly_version(config, version)
|
|
|
|
for task in tasks:
|
|
for field in ("description", "run.gradlew", "treeherder.symbol"):
|
|
component = task["attributes"]["component"]
|
|
_deep_format(
|
|
task,
|
|
field,
|
|
component=component,
|
|
nightlyVersion=nightly_version,
|
|
timestamp=timestamp,
|
|
treeherder_group=component[:25],
|
|
)
|
|
|
|
yield task
|
|
|
|
|
|
def _get_timestamp(config):
|
|
push_date_string = config.params["moz_build_date"]
|
|
push_date_time = datetime.datetime.strptime(push_date_string, "%Y%m%d%H%M%S")
|
|
return push_date_time.strftime("%Y%m%d.%H%M%S-1")
|
|
|
|
|
|
def _get_buildid(config):
|
|
return config.params.moz_build_date.strftime("%Y%m%d%H%M%S")
|
|
|
|
|
|
def get_nightly_version(config, version):
|
|
buildid = _get_buildid(config)
|
|
parsed_version = GeckoVersion.parse(version)
|
|
return f"{parsed_version.major_number}.{parsed_version.minor_number}.{buildid}"
|
|
|
|
|
|
def craft_path_version(version, build_type, nightly_version):
|
|
"""Helper function to craft the correct version to bake in the artifacts full
|
|
path section"""
|
|
path_version = version
|
|
# XXX: for nightly releases we need to s/X.0.0/X.0.<buildid>/g in versions
|
|
if build_type == "nightly":
|
|
path_version = path_version.replace(version, nightly_version)
|
|
return path_version
|
|
|
|
|
|
def _deep_format(object, field, **format_kwargs):
|
|
keys = field.split(".")
|
|
last_key = keys[-1]
|
|
for key in keys[:-1]:
|
|
object = object[key]
|
|
|
|
one_before_last_object = object
|
|
object = object[last_key]
|
|
|
|
if isinstance(object, str):
|
|
one_before_last_object[last_key] = object.format(**format_kwargs)
|
|
elif isinstance(object, list):
|
|
one_before_last_object[last_key] = [
|
|
item.format(**format_kwargs) for item in object
|
|
]
|
|
else:
|
|
raise ValueError(f"Unsupported type for object: {object}")
|
|
|
|
|
|
@transforms.add
|
|
def add_artifacts(config, tasks):
|
|
_get_timestamp(config)
|
|
version = config.params["version"]
|
|
nightly_version = get_nightly_version(config, version)
|
|
|
|
for task in tasks:
|
|
artifact_template = task.pop("artifact-template", {})
|
|
task["attributes"]["artifacts"] = artifacts = {}
|
|
|
|
component = task["attributes"]["component"]
|
|
build_artifact_definitions = task.setdefault("worker", {}).setdefault(
|
|
"artifacts", []
|
|
)
|
|
|
|
for key in [
|
|
"tests-artifact-template",
|
|
"lint-artifact-template",
|
|
"jacoco-coverage-template",
|
|
]:
|
|
if key in task:
|
|
optional_artifact_template = task.pop(key, {})
|
|
build_artifact_definitions.append(
|
|
{
|
|
"type": optional_artifact_template["type"],
|
|
"name": optional_artifact_template["name"],
|
|
"path": optional_artifact_template["path"].format(
|
|
component_path=get_path(component)
|
|
),
|
|
}
|
|
)
|
|
|
|
if artifact_template:
|
|
all_extensions = get_extensions(component)
|
|
artifact_file_names_per_extension = {
|
|
extension: "{component}-{version}{timestamp}{extension}".format(
|
|
component=component,
|
|
version=version,
|
|
timestamp="",
|
|
extension=extension,
|
|
)
|
|
for extension in all_extensions
|
|
}
|
|
# XXX: rather than adding more complex logic above, we simply post-adjust the
|
|
# dictionary for `nightly` types of graphs
|
|
if task["attributes"]["build-type"] == "nightly":
|
|
for ext, path in artifact_file_names_per_extension.items():
|
|
if version in path:
|
|
artifact_file_names_per_extension[ext] = path.replace(
|
|
version, nightly_version
|
|
)
|
|
|
|
for (
|
|
extension,
|
|
artifact_file_name,
|
|
) in artifact_file_names_per_extension.items():
|
|
artifact_full_name = artifact_template["name"].format(
|
|
artifact_file_name=artifact_file_name,
|
|
)
|
|
build_artifact_definitions.append(
|
|
{
|
|
"type": artifact_template["type"],
|
|
"name": artifact_full_name,
|
|
"path": artifact_template["path"].format(
|
|
component_path=get_path(component),
|
|
component=component,
|
|
version=craft_path_version(
|
|
version,
|
|
task["attributes"]["build-type"],
|
|
nightly_version,
|
|
),
|
|
artifact_file_name=artifact_file_name,
|
|
),
|
|
}
|
|
)
|
|
|
|
artifacts[extension] = artifact_full_name
|
|
|
|
yield task
|