Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions taskcluster/kinds/integration-test/kind.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,25 @@ tasks:
- android-hw
- macosx

gecko-builds:
description: "Run Gecko build tasks on alpha worker pools"
# Map build worker pools to their alpha equivalents.
# Non-mapped pools pass through unchanged.
worker-pool-mappings:
gecko-3/b-win2022: gecko-1/b-win2022-alpha
replicate:
target:
- gecko.v2.mozilla-central.latest.taskgraph.decision
include-attrs:
kind:
- build
# Exclude builds that don't have alpha pools configured
exclude-attrs:
build_platform:
- android
- macosx
- linux

translations:
description: "Run translations pipeline integration tests"
replicate:
Expand Down
89 changes: 85 additions & 4 deletions taskcluster/worker_images_taskgraph/transforms/integration_test.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,106 @@
import logging

from taskgraph.transforms.base import TransformSequence
from voluptuous import ALLOW_EXTRA, Optional, Schema

from worker_images_taskgraph.util.fxci import get_worker_pool_images

logger = logging.getLogger(__name__)
transforms = TransformSequence()


INTEGRATION_TEST_SCHEMA = Schema(
{
# Explicit worker pool mappings: old-pool -> new-pool
# Use this for cross-provisioner mappings like:
# gecko-3/b-win2022 -> gecko-1/b-win2022-alpha
Optional("worker-pool-mappings"): {str: str},
},
extra=ALLOW_EXTRA,
)


transforms.add_validate(INTEGRATION_TEST_SCHEMA)


def _get_pool_mappings_for_task(config, task_label):
"""
Get pool mappings for a task based on its label prefix.

Task labels from replicate transform are prefixed with the original task name,
e.g., "gecko-builds-build-win64/opt" came from "gecko-builds" task definition.
"""
tasks_config = config.config.get("tasks", {})

# Sort by task name length (longest first) to match most specific prefix
# This ensures "gecko-builds" matches before "gecko" for labels like
# "gecko-builds-build-win64/opt"
for task_name, task_def in sorted(
tasks_config.items(), key=lambda x: len(x[0]), reverse=True
):
# Check if the label starts with this task name
prefix = f"{task_name}-"
if task_label.startswith(prefix):
mappings = task_def.get("worker-pool-mappings", {})
logger.info(f"Label '{task_label}' matches '{task_name}', mappings: {mappings}")
return mappings

logger.info(f"No task definition match for label: {task_label}")
return {}


@transforms.add
def change_worker_pool_to_alpha(config, tasks):
pools = get_worker_pool_images().keys()

# Log available task definitions once
tasks_config = config.config.get("tasks", {})
logger.info(f"Available task definitions: {list(tasks_config.keys())}")
for tn, td in tasks_config.items():
if "worker-pool-mappings" in td:
logger.info(f"Task {tn} has worker-pool-mappings: {td['worker-pool-mappings']}")

for task in tasks:
old_pool = f"{task['task']['provisionerId']}/{task['task']['workerType']}"
new_worker_type = f"{task['task']['workerType']}-alpha"
new_pool = f"{task['task']['provisionerId']}/{new_worker_type}"
task_label = task.get("label", "")
logger.debug(f"Processing task with label: {task_label}")

# Get pool mappings based on which original task definition this came from
pool_mappings = _get_pool_mappings_for_task(config, task_label)

old_provisioner = task["task"]["provisionerId"]
old_worker_type = task["task"]["workerType"]
old_pool = f"{old_provisioner}/{old_worker_type}"

# If explicit pool mappings are defined for this task definition,
# only remap pools that match a mapping; pass others through unchanged.
if pool_mappings:
if old_pool in pool_mappings:
new_pool = pool_mappings[old_pool]
if new_pool not in pools:
logger.debug(
f"skipping {config.kind} task because mapped pool {new_pool} "
f"is not configured!"
)
continue
new_provisioner, new_worker_type = new_pool.split("/", 1)
task["task"]["provisionerId"] = new_provisioner
task["task"]["workerType"] = new_worker_type
logger.debug(f"Mapped {old_pool} -> {new_pool}")
else:
logger.debug(
f"No pool mapping for {old_pool}, passing through unchanged"
)
yield task
continue

# Default behavior: add -alpha suffix to worker type
new_worker_type = f"{old_worker_type}-alpha"
new_pool = f"{old_provisioner}/{new_worker_type}"

if new_pool not in pools:
logger.debug(
f"skipping {config.kind} task because {old_pool} does not have a corresponding `-alpha` pool configured!"
f"skipping {config.kind} task because {old_pool} does not have "
f"a corresponding `-alpha` pool configured!"
)
continue

Expand Down