1
0
Fork 0
firefox/taskcluster/gecko_taskgraph/transforms/partner_attribution.py
Daniel Baumann 5e9a113729
Adding upstream version 140.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
2025-06-25 09:37:52 +02:00

187 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/.
"""
Transform the partner attribution task into an actual task description.
"""
import json
import logging
from collections import defaultdict
from taskgraph.transforms.base import TransformSequence
from taskgraph.util.taskcluster import get_artifact_prefix
from gecko_taskgraph.util.partners import (
apply_partner_priority,
build_macos_attribution_dmg_command,
check_if_partners_enabled,
generate_attribution_code,
get_ftp_platform,
get_partner_config_by_kind,
)
log = logging.getLogger(__name__)
transforms = TransformSequence()
transforms.add(check_if_partners_enabled)
transforms.add(apply_partner_priority)
@transforms.add
def add_command_arguments(config, tasks):
enabled_partners = config.params.get("release_partners")
attribution_config = get_partner_config_by_kind(config, config.kind)
for task in tasks:
dependencies = {}
fetches = defaultdict(set)
attributions = []
release_artifacts = []
task_platforms = task.pop("platforms", [])
for partner_config in attribution_config.get("configs", []):
# we might only be interested in a subset of all partners, eg for a respin
if enabled_partners and partner_config["campaign"] not in enabled_partners:
continue
attribution_code = generate_attribution_code(
attribution_config["defaults"], partner_config
)
for platform in partner_config["platforms"]:
if platform not in task_platforms:
continue
for locale in partner_config["locales"]:
attributed_build_config = _get_attributed_build_configuration(
task, partner_config, platform, locale
)
upstream_label = attributed_build_config["upstream_label"]
if upstream_label not in config.kind_dependencies_tasks:
raise Exception(
f"Can't find upstream task for {platform} {locale}"
)
upstream = config.kind_dependencies_tasks[upstream_label]
# set the dependencies to just what we need rather than all of l10n
dependencies.update({upstream.label: upstream.label})
fetches[upstream_label].add(attributed_build_config["fetch_config"])
attributions.append(
{
"input": attributed_build_config["input_path"],
"output": attributed_build_config["output_path"],
"attribution": attribution_code,
}
)
release_artifacts.append(
attributed_build_config["release_artifact"]
)
if attributions:
worker = task.get("worker", {})
worker["chain-of-trust"] = True
task.setdefault("dependencies", {}).update(dependencies)
task.setdefault("fetches", {})
for upstream_label, upstream_artifacts in fetches.items():
task["fetches"][upstream_label] = [
{
"artifact": upstream_artifact,
"dest": f"{platform}/{locale}",
"extract": False,
"verify-hash": True,
}
for upstream_artifact, platform, locale in upstream_artifacts
]
task.setdefault("attributes", {})["release_artifacts"] = release_artifacts
_build_attribution_config(task, task_platforms, attributions)
yield task
def _get_attributed_build_configuration(task, partner_config, platform, locale):
stage_platform = platform.replace("-shippable", "")
artifact_file_name = _get_artifact_file_name(platform)
output_artifact = _get_output_path(
get_artifact_prefix(task), partner_config, platform, locale, artifact_file_name
)
return {
"fetch_config": (
_get_upstream_artifact_path(artifact_file_name, locale),
stage_platform,
locale,
),
"input_path": _get_input_path(stage_platform, locale, artifact_file_name),
"output_path": f"/builds/worker/artifacts/{output_artifact}",
"release_artifact": output_artifact,
"upstream_label": _get_upstream_task_label(platform, locale),
}
def _get_input_path(stage_platform, locale, artifact_file_name):
return f"/builds/worker/fetches/{stage_platform}/{locale}/{artifact_file_name}"
def _get_output_path(
artifact_prefix, partner_config, platform, locale, artifact_file_name
):
return "{artifact_prefix}/{partner}/{sub_partner}/{ftp_platform}/{locale}/{artifact_file_name}".format(
artifact_prefix=artifact_prefix,
partner=partner_config["campaign"],
sub_partner=partner_config["content"],
ftp_platform=get_ftp_platform(platform),
locale=locale,
artifact_file_name=artifact_file_name,
)
def _get_artifact_file_name(platform):
if platform.startswith("win32"):
return "target.stub-installer.exe"
elif platform.startswith("macos"):
return "target.dmg"
else:
raise NotImplementedError(f'Case for platform "{platform}" is not implemented')
def _get_upstream_task_label(platform, locale):
if platform.startswith("win"):
if locale == "en-US":
upstream_label = f"repackage-signing-{platform}/opt"
else:
upstream_label = f"repackage-signing-l10n-{locale}-{platform}/opt"
elif platform.startswith("macos"):
if locale == "en-US":
upstream_label = f"repackage-{platform}/opt"
else:
upstream_label = f"repackage-l10n-{locale}-{platform}/opt"
else:
raise NotImplementedError(f'Case for platform "{platform}" is not implemented')
return upstream_label
def _get_upstream_artifact_path(artifact_file_name, locale):
return artifact_file_name if locale == "en-US" else f"{locale}/{artifact_file_name}"
def _build_attribution_config(task, task_platforms, attributions):
if any(p.startswith("win") for p in task_platforms):
worker = task.get("worker", {})
worker.setdefault("env", {})["ATTRIBUTION_CONFIG"] = json.dumps(
attributions, sort_keys=True
)
elif any(p.startswith("macos") for p in task_platforms):
run = task.setdefault("run", {})
run["command"] = build_macos_attribution_dmg_command(
"/builds/worker/fetches/dmg/dmg", attributions
)
else:
raise NotImplementedError(
f"Case for platforms {task_platforms} is not implemented"
)