зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1746414 - Use standalone taskgraph's parameters module in Gecko, r=taskgraph-reviewers,jmaher
Rather than defining a distinct `Parameter` class for Gecko, this now uses the `extend_parameters_schema` utility function (which mobile repos are already using). As a consequence, shared parameters are now defined in standalone taskgraph. And only Gecko-specific parameters are listed in `gecko_taskgraph/parameters.py` The only exception is `project` which gets redefined so we can override the standalone taskgraph default (since it derives `project` from the repo name, which doesn't work for Gecko). Differential Revision: https://phabricator.services.mozilla.com/D134515
This commit is contained in:
Родитель
72e6ce049b
Коммит
c2b9d1b50f
|
@ -442,7 +442,8 @@ task-priority:
|
|||
'mozilla-inbound': 'low'
|
||||
'default': 'very-low'
|
||||
|
||||
taskgraph: {}
|
||||
taskgraph:
|
||||
register: gecko_taskgraph:register
|
||||
|
||||
workers:
|
||||
aliases:
|
||||
|
|
|
@ -45,6 +45,9 @@ Push Information
|
|||
the symbolic ref containing ``head_rev`` that should be pulled from
|
||||
``head_repository``.
|
||||
|
||||
``head_tag``
|
||||
The tag attached to the revision, if any.
|
||||
|
||||
``owner``
|
||||
Email address indicating the person who made the push. Note that this
|
||||
value may be forged and *must not* be relied on for authentication.
|
||||
|
@ -70,6 +73,9 @@ Push Information
|
|||
A formatted timestamp of ``build_date``. Expressed as a string with the following
|
||||
format: %Y%m%d%H%M%S
|
||||
|
||||
``repository_type``
|
||||
The type of repository, either ``hg`` or ``git``.
|
||||
|
||||
``tasks_for``
|
||||
The ``tasks_for`` value used to generate the decision task.
|
||||
|
||||
|
|
|
@ -17,3 +17,14 @@ MAX_DEPENDENCIES = 99
|
|||
# This is normally switched on via the --fast/-F flag to `mach taskgraph`
|
||||
# Currently this skips toolchain task optimizations and schema validation
|
||||
fast = False
|
||||
|
||||
|
||||
def register(graph_config):
|
||||
"""Used to register Gecko specific extensions.
|
||||
|
||||
Args:
|
||||
graph_config: The graph configuration object.
|
||||
"""
|
||||
from gecko_taskgraph.parameters import register_parameters
|
||||
|
||||
register_parameters()
|
||||
|
|
|
@ -2,11 +2,10 @@
|
|||
# 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/.
|
||||
|
||||
from taskgraph.parameters import Parameters
|
||||
|
||||
from .registry import register_callback_action
|
||||
|
||||
from gecko_taskgraph.actions.registry import register_callback_action
|
||||
from gecko_taskgraph.decision import taskgraph_decision
|
||||
from gecko_taskgraph.parameters import Parameters
|
||||
from gecko_taskgraph.util.attributes import RELEASE_PROMOTION_PROJECTS
|
||||
|
||||
|
||||
|
|
|
@ -9,13 +9,13 @@ from types import FunctionType
|
|||
from collections import namedtuple
|
||||
|
||||
from mozbuild.util import memoize
|
||||
from taskgraph.parameters import Parameters
|
||||
from taskgraph.util import yaml
|
||||
|
||||
from gecko_taskgraph import create
|
||||
from gecko_taskgraph.config import load_graph_config
|
||||
from gecko_taskgraph.util import taskcluster, hash
|
||||
from gecko_taskgraph.util.python_path import import_sibling_modules
|
||||
from gecko_taskgraph.parameters import Parameters
|
||||
|
||||
|
||||
actions = []
|
||||
|
|
|
@ -6,8 +6,9 @@
|
|||
import json
|
||||
import os
|
||||
|
||||
from .registry import register_callback_action
|
||||
from taskgraph.parameters import Parameters
|
||||
|
||||
from gecko_taskgraph.actions.registry import register_callback_action
|
||||
from gecko_taskgraph.util.taskcluster import get_artifact
|
||||
from gecko_taskgraph.util.taskgraph import (
|
||||
find_decision_task,
|
||||
|
@ -22,7 +23,6 @@ from gecko_taskgraph.util.partners import (
|
|||
)
|
||||
from gecko_taskgraph.taskgraph import TaskGraph
|
||||
from gecko_taskgraph.decision import taskgraph_decision
|
||||
from gecko_taskgraph.parameters import Parameters
|
||||
from gecko_taskgraph.util.attributes import RELEASE_PROMOTION_PROJECTS, release_level
|
||||
|
||||
|
||||
|
|
|
@ -2,11 +2,10 @@
|
|||
# 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/.
|
||||
|
||||
from taskgraph.parameters import Parameters
|
||||
|
||||
from gecko_taskgraph.actions.registry import register_callback_action
|
||||
from gecko_taskgraph.decision import taskgraph_decision
|
||||
from gecko_taskgraph.parameters import Parameters
|
||||
|
||||
from .registry import register_callback_action
|
||||
|
||||
|
||||
@register_callback_action(
|
||||
|
|
|
@ -12,6 +12,7 @@ from collections import defaultdict
|
|||
|
||||
import yaml
|
||||
from redo import retry
|
||||
from taskgraph.parameters import Parameters
|
||||
from taskgraph.util.yaml import load_yaml
|
||||
from voluptuous import Required, Optional, Any
|
||||
|
||||
|
@ -19,7 +20,7 @@ from . import GECKO, create
|
|||
from .actions import render_actions_json
|
||||
from .create import create_tasks
|
||||
from .generator import TaskGraphGenerator
|
||||
from .parameters import Parameters, get_version, get_app_version
|
||||
from .parameters import get_version, get_app_version
|
||||
from .taskgraph import TaskGraph
|
||||
from .try_option_syntax import parse_message
|
||||
from .util.backstop import is_backstop, BACKSTOP_INDEX
|
||||
|
@ -274,11 +275,13 @@ def get_decision_parameters(graph_config, options):
|
|||
"head_repository",
|
||||
"head_rev",
|
||||
"head_ref",
|
||||
"head_tag",
|
||||
"project",
|
||||
"pushlog_id",
|
||||
"pushdate",
|
||||
"owner",
|
||||
"level",
|
||||
"repository_type",
|
||||
"target_tasks_method",
|
||||
"tasks_for",
|
||||
]
|
||||
|
|
|
@ -8,9 +8,10 @@ import os
|
|||
import tarfile
|
||||
from io import BytesIO
|
||||
|
||||
from taskgraph.parameters import Parameters
|
||||
|
||||
from gecko_taskgraph.generator import load_tasks_for_kind
|
||||
from gecko_taskgraph.optimize.strategies import IndexSearch
|
||||
from gecko_taskgraph.parameters import Parameters
|
||||
from gecko_taskgraph.util import docker
|
||||
from gecko_taskgraph.util.taskcluster import (
|
||||
get_artifact_url,
|
||||
|
|
|
@ -8,17 +8,17 @@ import copy
|
|||
|
||||
import attr
|
||||
from taskgraph.config import GraphConfig
|
||||
from taskgraph.parameters import parameters_loader
|
||||
from taskgraph.util.yaml import load_yaml
|
||||
|
||||
from . import filter_tasks
|
||||
from .graph import Graph
|
||||
from .taskgraph import TaskGraph
|
||||
from .task import Task
|
||||
from .optimize import optimize_task_graph
|
||||
from .morph import morph
|
||||
from .parameters import Parameters
|
||||
from .util.python_path import find_object
|
||||
from .optimize import optimize_task_graph
|
||||
from .task import Task
|
||||
from .taskgraph import TaskGraph
|
||||
from .transforms.base import TransformSequence, TransformConfig
|
||||
from .util.python_path import find_object
|
||||
from .util.verify import (
|
||||
verify_docs,
|
||||
verifications,
|
||||
|
@ -483,7 +483,7 @@ def load_tasks_for_kind(parameters, kind, root_dir=None):
|
|||
# make parameters read-write
|
||||
parameters = dict(parameters)
|
||||
parameters["target-kind"] = kind
|
||||
parameters = Parameters(strict=False, **parameters)
|
||||
parameters = parameters_loader(spec=None, strict=False, overrides=parameters)
|
||||
tgg = TaskGraphGenerator(root_dir=root_dir, parameters=parameters)
|
||||
return {
|
||||
task.task["metadata"]["name"]: task
|
||||
|
|
|
@ -106,7 +106,7 @@ def get_taskgraph_generator(root, parameters):
|
|||
|
||||
def format_taskgraph(options, parameters, logfile=None):
|
||||
import gecko_taskgraph
|
||||
from gecko_taskgraph.parameters import parameters_loader
|
||||
from taskgraph.parameters import parameters_loader
|
||||
|
||||
if logfile:
|
||||
oldhandler = logging.root.handlers[-1]
|
||||
|
@ -135,7 +135,7 @@ def format_taskgraph(options, parameters, logfile=None):
|
|||
|
||||
|
||||
def dump_output(out, path=None, params_spec=None):
|
||||
from gecko_taskgraph.parameters import Parameters
|
||||
from taskgraph.parameters import Parameters
|
||||
|
||||
params_name = Parameters.format_spec(params_spec)
|
||||
fh = None
|
||||
|
@ -157,7 +157,7 @@ def dump_output(out, path=None, params_spec=None):
|
|||
|
||||
|
||||
def generate_taskgraph(options, parameters, logdir):
|
||||
from gecko_taskgraph.parameters import Parameters
|
||||
from taskgraph.parameters import Parameters
|
||||
|
||||
def logfile(spec):
|
||||
"""Determine logfile given a parameters specification."""
|
||||
|
@ -315,7 +315,7 @@ def generate_taskgraph(options, parameters, logdir):
|
|||
)
|
||||
def show_taskgraph(options):
|
||||
from mozversioncontrol import get_repository_object as get_repository
|
||||
from gecko_taskgraph.parameters import Parameters
|
||||
from taskgraph.parameters import Parameters, parameters_loader
|
||||
|
||||
if options.pop("verbose", False):
|
||||
logging.root.setLevel(logging.DEBUG)
|
||||
|
@ -352,10 +352,12 @@ def show_taskgraph(options):
|
|||
|
||||
parameters: List[Any[str, Parameters]] = options.pop("parameters")
|
||||
if not parameters:
|
||||
kwargs = {
|
||||
overrides = {
|
||||
"target-kind": options.get("target_kind"),
|
||||
}
|
||||
parameters = [Parameters(strict=False, **kwargs)] # will use default values
|
||||
parameters = [
|
||||
parameters_loader(None, strict=False, overrides=overrides)
|
||||
] # will use default values
|
||||
|
||||
for param in parameters[:]:
|
||||
if isinstance(param, str) and os.path.isdir(param):
|
||||
|
|
|
@ -2,36 +2,47 @@
|
|||
# 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 hashlib
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
from datetime import datetime
|
||||
from pprint import pformat
|
||||
from urllib.parse import urlparse
|
||||
|
||||
from mozbuild.util import ReadOnlyDict, memoize
|
||||
from mozversioncontrol import get_repository_object
|
||||
from gecko_taskgraph.util.schema import validate_schema
|
||||
from taskgraph.parameters import extend_parameters_schema
|
||||
from voluptuous import (
|
||||
ALLOW_EXTRA,
|
||||
Any,
|
||||
Required,
|
||||
Schema,
|
||||
)
|
||||
|
||||
from . import GECKO
|
||||
from gecko_taskgraph import GECKO
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ParameterMismatch(Exception):
|
||||
"""Raised when a parameters.yml has extra or missing parameters."""
|
||||
|
||||
|
||||
@memoize
|
||||
def get_head_ref():
|
||||
return get_repository_object(GECKO).head_ref
|
||||
gecko_parameters_schema = {
|
||||
Required("app_version"): str,
|
||||
Required("backstop"): bool,
|
||||
Required("build_number"): int,
|
||||
Required("hg_branch"): str,
|
||||
Required("message"): str,
|
||||
Required("next_version"): Any(None, str),
|
||||
Required("optimize_strategies"): Any(None, str),
|
||||
Required("phabricator_diff"): Any(None, str),
|
||||
Required("release_enable_emefree"): bool,
|
||||
Required("release_enable_partner_repack"): bool,
|
||||
Required("release_enable_partner_attribution"): bool,
|
||||
Required("release_eta"): Any(None, str),
|
||||
Required("release_history"): {str: dict},
|
||||
Required("release_partners"): Any(None, [str]),
|
||||
Required("release_partner_config"): Any(None, dict),
|
||||
Required("release_partner_build_number"): int,
|
||||
Required("release_type"): str,
|
||||
Required("release_product"): Any(None, str),
|
||||
Required("required_signoffs"): [str],
|
||||
Required("signoff_urls"): dict,
|
||||
Required("test_manifest_loader"): str,
|
||||
Required("try_mode"): Any(None, str),
|
||||
Required("try_options"): Any(None, dict),
|
||||
Required("try_task_config"): dict,
|
||||
Required("version"): str,
|
||||
}
|
||||
|
||||
|
||||
def get_contents(path):
|
||||
|
@ -50,265 +61,36 @@ def get_app_version(product_dir="browser"):
|
|||
return get_contents(app_version_path)
|
||||
|
||||
|
||||
base_schema = Schema(
|
||||
{
|
||||
Required("app_version"): str,
|
||||
Required("backstop"): bool,
|
||||
Required("base_repository"): str,
|
||||
Required("build_date"): int,
|
||||
Required("build_number"): int,
|
||||
Required("do_not_optimize"): [str],
|
||||
Required("existing_tasks"): {str: str},
|
||||
Required("filters"): [str],
|
||||
Required("head_ref"): str,
|
||||
Required("head_repository"): str,
|
||||
Required("head_rev"): str,
|
||||
Required("hg_branch"): str,
|
||||
Required("level"): str,
|
||||
Required("message"): str,
|
||||
Required("moz_build_date"): str,
|
||||
Required("next_version"): Any(None, str),
|
||||
Required("optimize_strategies"): Any(None, str),
|
||||
Required("optimize_target_tasks"): bool,
|
||||
Required("owner"): str,
|
||||
Required("phabricator_diff"): Any(None, str),
|
||||
Required("project"): str,
|
||||
Required("pushdate"): int,
|
||||
Required("pushlog_id"): str,
|
||||
Required("release_enable_emefree"): bool,
|
||||
Required("release_enable_partner_repack"): bool,
|
||||
Required("release_enable_partner_attribution"): bool,
|
||||
Required("release_eta"): Any(None, str),
|
||||
Required("release_history"): {str: dict},
|
||||
Required("release_partners"): Any(None, [str]),
|
||||
Required("release_partner_config"): Any(None, dict),
|
||||
Required("release_partner_build_number"): int,
|
||||
Required("release_type"): str,
|
||||
Required("release_product"): Any(None, str),
|
||||
Required("required_signoffs"): [str],
|
||||
Required("signoff_urls"): dict,
|
||||
# target-kind is not included, since it should never be
|
||||
# used at run-time
|
||||
Required("target_tasks_method"): str,
|
||||
Required("tasks_for"): str,
|
||||
Required("test_manifest_loader"): str,
|
||||
Required("try_mode"): Any(None, str),
|
||||
Required("try_options"): Any(None, dict),
|
||||
Required("try_task_config"): dict,
|
||||
Required("version"): str,
|
||||
def get_defaults(repo_root=None):
|
||||
return {
|
||||
"app_version": get_app_version(),
|
||||
"backstop": False,
|
||||
"build_number": 1,
|
||||
"hg_branch": "default",
|
||||
"message": "",
|
||||
"next_version": None,
|
||||
"optimize_strategies": None,
|
||||
"phabricator_diff": None,
|
||||
"project": "mozilla-central",
|
||||
"release_enable_emefree": False,
|
||||
"release_enable_partner_repack": False,
|
||||
"release_enable_partner_attribution": False,
|
||||
"release_eta": "",
|
||||
"release_history": {},
|
||||
"release_partners": [],
|
||||
"release_partner_config": None,
|
||||
"release_partner_build_number": 1,
|
||||
"release_product": None,
|
||||
"release_type": "nightly",
|
||||
"required_signoffs": [],
|
||||
"signoff_urls": {},
|
||||
"test_manifest_loader": "default",
|
||||
"try_mode": None,
|
||||
"try_options": None,
|
||||
"try_task_config": {},
|
||||
"version": get_version(),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
class Parameters(ReadOnlyDict):
|
||||
"""An immutable dictionary with nicer KeyError messages on failure"""
|
||||
|
||||
def __init__(self, strict=True, **kwargs):
|
||||
self.strict = strict
|
||||
self.spec = kwargs.pop("spec", "defaults")
|
||||
self._id = None
|
||||
|
||||
if not self.strict:
|
||||
# apply defaults to missing parameters
|
||||
kwargs = Parameters._fill_defaults(**kwargs)
|
||||
|
||||
ReadOnlyDict.__init__(self, **kwargs)
|
||||
|
||||
@property
|
||||
def id(self):
|
||||
if not self._id:
|
||||
self._id = hashlib.sha256(
|
||||
json.dumps(self, sort_keys=True).encode("utf-8")
|
||||
).hexdigest()[:12]
|
||||
|
||||
return self._id
|
||||
|
||||
@staticmethod
|
||||
def format_spec(spec):
|
||||
"""
|
||||
Get a friendly identifier from a parameters specifier.
|
||||
|
||||
Args:
|
||||
spec (str): Parameters specifier.
|
||||
|
||||
Returns:
|
||||
str: Name to identify parameters by.
|
||||
"""
|
||||
if spec is None:
|
||||
return "defaults"
|
||||
|
||||
if any(spec.startswith(s) for s in ("task-id=", "project=")):
|
||||
return spec
|
||||
|
||||
result = urlparse(spec)
|
||||
if result.scheme in ("http", "https"):
|
||||
spec = result.path
|
||||
|
||||
return os.path.splitext(os.path.basename(spec))[0]
|
||||
|
||||
@staticmethod
|
||||
def _fill_defaults(**kwargs):
|
||||
now = datetime.utcnow()
|
||||
epoch = datetime.utcfromtimestamp(0)
|
||||
seconds_from_epoch = int((now - epoch).total_seconds())
|
||||
|
||||
defaults = {
|
||||
"app_version": get_app_version(),
|
||||
"backstop": False,
|
||||
"base_repository": "https://hg.mozilla.org/mozilla-unified",
|
||||
"build_date": seconds_from_epoch,
|
||||
"build_number": 1,
|
||||
"do_not_optimize": [],
|
||||
"existing_tasks": {},
|
||||
"filters": ["target_tasks_method"],
|
||||
"head_ref": get_head_ref(),
|
||||
"head_repository": "https://hg.mozilla.org/mozilla-central",
|
||||
"head_rev": get_head_ref(),
|
||||
"hg_branch": "default",
|
||||
"level": "3",
|
||||
"message": "",
|
||||
"moz_build_date": now.strftime("%Y%m%d%H%M%S"),
|
||||
"next_version": None,
|
||||
"optimize_strategies": None,
|
||||
"optimize_target_tasks": True,
|
||||
"owner": "nobody@mozilla.com",
|
||||
"phabricator_diff": None,
|
||||
"project": "mozilla-central",
|
||||
"pushdate": seconds_from_epoch,
|
||||
"pushlog_id": "0",
|
||||
"release_enable_emefree": False,
|
||||
"release_enable_partner_repack": False,
|
||||
"release_enable_partner_attribution": False,
|
||||
"release_eta": "",
|
||||
"release_history": {},
|
||||
"release_partners": [],
|
||||
"release_partner_config": None,
|
||||
"release_partner_build_number": 1,
|
||||
"release_product": None,
|
||||
"release_type": "nightly",
|
||||
"required_signoffs": [],
|
||||
"signoff_urls": {},
|
||||
"target_tasks_method": "default",
|
||||
"tasks_for": "hg-push",
|
||||
"test_manifest_loader": "default",
|
||||
"try_mode": None,
|
||||
"try_options": None,
|
||||
"try_task_config": {},
|
||||
"version": get_version(),
|
||||
}
|
||||
|
||||
for name, default in defaults.items():
|
||||
if name not in kwargs:
|
||||
kwargs[name] = default
|
||||
|
||||
return kwargs
|
||||
|
||||
def check(self):
|
||||
schema = (
|
||||
base_schema if self.strict else base_schema.extend({}, extra=ALLOW_EXTRA)
|
||||
)
|
||||
validate_schema(schema, self.copy(), "Invalid parameters:")
|
||||
|
||||
def __getitem__(self, k):
|
||||
try:
|
||||
return super().__getitem__(k)
|
||||
except KeyError:
|
||||
raise KeyError(f"taskgraph parameter {k!r} not found")
|
||||
|
||||
def file_url(self, path, pretty=False):
|
||||
"""
|
||||
Determine the VCS URL for viewing a file in the tree, suitable for
|
||||
viewing by a human.
|
||||
|
||||
:param text_type path: The path, relative to the root of the repository.
|
||||
:param bool pretty: Whether to return a link to a formatted version of the
|
||||
file, or the raw file version.
|
||||
:return text_type: The URL displaying the given path.
|
||||
"""
|
||||
if path.startswith("comm/"):
|
||||
path = path[len("comm/") :]
|
||||
repo = self["comm_head_repository"]
|
||||
rev = self["comm_head_rev"]
|
||||
else:
|
||||
repo = self["head_repository"]
|
||||
rev = self["head_rev"]
|
||||
|
||||
endpoint = "file" if pretty else "raw-file"
|
||||
return f"{repo}/{endpoint}/{rev}/{path}"
|
||||
|
||||
def __str__(self):
|
||||
return f"Parameters(id={self.id}) (from {self.format_spec(self.spec)})"
|
||||
|
||||
def __repr__(self):
|
||||
return pformat(dict(self), indent=2)
|
||||
|
||||
|
||||
def load_parameters_file(spec, strict=True, overrides=None, trust_domain=None):
|
||||
"""
|
||||
Load parameters from a path, url, decision task-id or project.
|
||||
|
||||
Examples:
|
||||
task-id=fdtgsD5DQUmAQZEaGMvQ4Q
|
||||
project=mozilla-central
|
||||
"""
|
||||
import requests
|
||||
from taskgraph.util import yaml
|
||||
from gecko_taskgraph.util.taskcluster import get_artifact_url, find_task_id
|
||||
|
||||
if overrides is None:
|
||||
overrides = {}
|
||||
|
||||
if not spec:
|
||||
return Parameters(strict=strict, **overrides)
|
||||
|
||||
try:
|
||||
# reading parameters from a local parameters.yml file
|
||||
f = open(spec)
|
||||
except OSError:
|
||||
# fetching parameters.yml using task task-id, project or supplied url
|
||||
task_id = None
|
||||
if spec.startswith("task-id="):
|
||||
task_id = spec.split("=")[1]
|
||||
elif spec.startswith("project="):
|
||||
if trust_domain is None:
|
||||
raise ValueError(
|
||||
"Can't specify parameters by project "
|
||||
"if trust domain isn't supplied.",
|
||||
)
|
||||
index = "{trust_domain}.v2.{project}.latest.taskgraph.decision".format(
|
||||
trust_domain=trust_domain,
|
||||
project=spec.split("=")[1],
|
||||
)
|
||||
task_id = find_task_id(index)
|
||||
|
||||
if task_id:
|
||||
spec = get_artifact_url(task_id, "public/parameters.yml")
|
||||
logger.info(f"Loading parameters from {spec}")
|
||||
resp = requests.get(spec, stream=True)
|
||||
resp.raise_for_status()
|
||||
f = resp.raw
|
||||
|
||||
if spec.endswith(".yml"):
|
||||
kwargs = yaml.load_stream(f)
|
||||
elif spec.endswith(".json"):
|
||||
kwargs = json.load(f)
|
||||
else:
|
||||
raise TypeError(f"Parameters file `{spec}` is not JSON or YAML")
|
||||
|
||||
kwargs.update(overrides)
|
||||
|
||||
return Parameters(strict=strict, **kwargs)
|
||||
|
||||
|
||||
def parameters_loader(spec, strict=True, overrides=None):
|
||||
def get_parameters(graph_config):
|
||||
parameters = load_parameters_file(
|
||||
spec,
|
||||
strict=strict,
|
||||
overrides=overrides,
|
||||
trust_domain=graph_config["trust-domain"],
|
||||
)
|
||||
parameters.check()
|
||||
return parameters
|
||||
|
||||
return get_parameters
|
||||
def register_parameters():
|
||||
extend_parameters_schema(gecko_parameters_schema, defaults_fn=get_defaults)
|
||||
|
|
|
@ -8,8 +8,9 @@ import os
|
|||
import re
|
||||
|
||||
from redo import retry
|
||||
from taskgraph.parameters import Parameters
|
||||
|
||||
from gecko_taskgraph import try_option_syntax
|
||||
from gecko_taskgraph.parameters import Parameters
|
||||
from gecko_taskgraph.util.attributes import (
|
||||
match_run_on_projects,
|
||||
match_run_on_hg_branches,
|
||||
|
|
|
@ -8,6 +8,8 @@ from mach.logging import LoggingManager
|
|||
from responses import RequestsMock
|
||||
from taskgraph.config import GraphConfig
|
||||
|
||||
from taskgraph.parameters import Parameters
|
||||
|
||||
from gecko_taskgraph import (
|
||||
GECKO,
|
||||
generator,
|
||||
|
@ -18,7 +20,6 @@ from gecko_taskgraph.actions import render_actions_json
|
|||
from gecko_taskgraph.config import load_graph_config
|
||||
from gecko_taskgraph.generator import TaskGraphGenerator, Kind
|
||||
from gecko_taskgraph.optimize import OptimizationStrategy
|
||||
from gecko_taskgraph.parameters import Parameters
|
||||
from gecko_taskgraph.util.templates import merge
|
||||
|
||||
|
||||
|
|
|
@ -11,7 +11,6 @@ subsuite = taskgraph
|
|||
[test_morph.py]
|
||||
[test_optimize.py]
|
||||
[test_optimize_strategies.py]
|
||||
[test_parameters.py]
|
||||
[test_target_tasks.py]
|
||||
[test_taskgraph.py]
|
||||
[test_taskcluster_yml.py]
|
||||
|
|
|
@ -9,16 +9,23 @@ import shutil
|
|||
import unittest
|
||||
import tempfile
|
||||
|
||||
import pytest
|
||||
from mozunit import main, MockedOpen
|
||||
from taskgraph.util.yaml import load_yaml
|
||||
from unittest.mock import patch
|
||||
|
||||
from gecko_taskgraph import decision
|
||||
from gecko_taskgraph.parameters import register_parameters
|
||||
|
||||
|
||||
FAKE_GRAPH_CONFIG = {"product-dir": "browser", "taskgraph": {}}
|
||||
|
||||
|
||||
@pytest.fixture(scope="module", autouse=True)
|
||||
def register():
|
||||
register_parameters()
|
||||
|
||||
|
||||
class TestDecision(unittest.TestCase):
|
||||
def test_write_artifact_json(self):
|
||||
data = [{"some": "data"}]
|
||||
|
@ -56,11 +63,13 @@ class TestGetDecisionParameters(unittest.TestCase):
|
|||
"head_repository": "https://hg.mozilla.org/mozilla-central",
|
||||
"head_rev": "abcd",
|
||||
"head_ref": "ef01",
|
||||
"head_tag": "",
|
||||
"message": "",
|
||||
"project": "mozilla-central",
|
||||
"pushlog_id": "143",
|
||||
"pushdate": 1503691511,
|
||||
"owner": "nobody@mozilla.com",
|
||||
"repository_type": "hg",
|
||||
"tasks_for": "hg-push",
|
||||
"level": "3",
|
||||
}
|
||||
|
|
|
@ -4,10 +4,10 @@
|
|||
|
||||
|
||||
import pytest
|
||||
from taskgraph.parameters import Parameters
|
||||
|
||||
from gecko_taskgraph import morph
|
||||
from gecko_taskgraph.graph import Graph
|
||||
from gecko_taskgraph.parameters import Parameters
|
||||
from gecko_taskgraph.taskgraph import TaskGraph
|
||||
from gecko_taskgraph.task import Task
|
||||
|
||||
|
|
|
@ -1,131 +0,0 @@
|
|||
# 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 unittest
|
||||
|
||||
from gecko_taskgraph.parameters import (
|
||||
Parameters,
|
||||
load_parameters_file,
|
||||
)
|
||||
from mozunit import main, MockedOpen
|
||||
|
||||
|
||||
class TestParameters(unittest.TestCase):
|
||||
|
||||
vals = {
|
||||
"app_version": "app_version",
|
||||
"backstop": False,
|
||||
"base_repository": "base_repository",
|
||||
"build_date": 0,
|
||||
"build_number": 0,
|
||||
"do_not_optimize": [],
|
||||
"existing_tasks": {},
|
||||
"filters": [],
|
||||
"head_ref": "head_ref",
|
||||
"head_repository": "head_repository",
|
||||
"head_rev": "head_rev",
|
||||
"hg_branch": "hg_branch",
|
||||
"level": "level",
|
||||
"message": "message",
|
||||
"moz_build_date": "moz_build_date",
|
||||
"next_version": "next_version",
|
||||
"optimize_strategies": None,
|
||||
"optimize_target_tasks": False,
|
||||
"owner": "owner",
|
||||
"phabricator_diff": "phabricator_diff",
|
||||
"project": "project",
|
||||
"pushdate": 0,
|
||||
"pushlog_id": "pushlog_id",
|
||||
"release_enable_emefree": False,
|
||||
"release_enable_partner_repack": False,
|
||||
"release_enable_partner_attribution": False,
|
||||
"release_eta": None,
|
||||
"release_history": {},
|
||||
"release_partners": [],
|
||||
"release_partner_config": None,
|
||||
"release_partner_build_number": 1,
|
||||
"release_type": "release_type",
|
||||
"release_product": None,
|
||||
"required_signoffs": [],
|
||||
"signoff_urls": {},
|
||||
"target_tasks_method": "target_tasks_method",
|
||||
"test_manifest_loader": "default",
|
||||
"tasks_for": "tasks_for",
|
||||
"try_mode": "try_mode",
|
||||
"try_options": None,
|
||||
"try_task_config": {},
|
||||
"version": "version",
|
||||
}
|
||||
|
||||
def test_Parameters_immutable(self):
|
||||
p = Parameters(**self.vals)
|
||||
|
||||
def assign():
|
||||
p["head_ref"] = 20
|
||||
|
||||
self.assertRaises(Exception, assign)
|
||||
|
||||
def test_Parameters_missing_KeyError(self):
|
||||
p = Parameters(**self.vals)
|
||||
self.assertRaises(KeyError, lambda: p["z"])
|
||||
|
||||
def test_Parameters_invalid_KeyError(self):
|
||||
"""even if the value is present, if it's not a valid property, raise KeyError"""
|
||||
p = Parameters(xyz=10, strict=True, **self.vals)
|
||||
self.assertRaises(Exception, lambda: p.check())
|
||||
|
||||
def test_Parameters_get(self):
|
||||
p = Parameters(head_ref=10, level=20)
|
||||
self.assertEqual(p["head_ref"], 10)
|
||||
|
||||
def test_Parameters_check(self):
|
||||
p = Parameters(**self.vals)
|
||||
p.check() # should not raise
|
||||
|
||||
def test_Parameters_check_missing(self):
|
||||
p = Parameters()
|
||||
self.assertRaises(Exception, lambda: p.check())
|
||||
|
||||
p = Parameters(strict=False)
|
||||
p.check() # should not raise
|
||||
|
||||
def test_Parameters_check_extra(self):
|
||||
p = Parameters(xyz=10, **self.vals)
|
||||
self.assertRaises(Exception, lambda: p.check())
|
||||
|
||||
p = Parameters(strict=False, xyz=10, **self.vals)
|
||||
p.check() # should not raise
|
||||
|
||||
def test_load_parameters_file_yaml(self):
|
||||
with MockedOpen({"params.yml": "some: data\n"}):
|
||||
self.assertEqual(load_parameters_file("params.yml"), {"some": "data"})
|
||||
|
||||
def test_load_parameters_file_json(self):
|
||||
with MockedOpen({"params.json": '{"some": "data"}'}):
|
||||
self.assertEqual(load_parameters_file("params.json"), {"some": "data"})
|
||||
|
||||
def test_load_parameters_override(self):
|
||||
"""
|
||||
When ``load_parameters_file`` is passed overrides, they are included in
|
||||
the generated parameters.
|
||||
"""
|
||||
self.assertEqual(
|
||||
load_parameters_file("", overrides={"some": "data"}), {"some": "data"}
|
||||
)
|
||||
|
||||
def test_load_parameters_override_file(self):
|
||||
"""
|
||||
When ``load_parameters_file`` is passed overrides, they overwrite data
|
||||
loaded from a file.
|
||||
"""
|
||||
with MockedOpen({"params.json": '{"some": "data"}'}):
|
||||
self.assertEqual(
|
||||
load_parameters_file("params.json", overrides={"some": "other"}),
|
||||
{"some": "other"},
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
|
@ -5,8 +5,8 @@
|
|||
|
||||
import attr
|
||||
from taskgraph.config import GraphConfig
|
||||
from taskgraph.parameters import Parameters
|
||||
|
||||
from ..parameters import Parameters
|
||||
from ..util.schema import Schema, validate_schema
|
||||
|
||||
|
||||
|
|
|
@ -360,13 +360,13 @@ def show_actions(command_context, options):
|
|||
import gecko_taskgraph
|
||||
import gecko_taskgraph.actions
|
||||
import gecko_taskgraph.generator
|
||||
import gecko_taskgraph.parameters
|
||||
from taskgraph.parameters import parameters_loader
|
||||
|
||||
try:
|
||||
setup_logging(
|
||||
command_context, quiet=options["quiet"], verbose=options["verbose"]
|
||||
)
|
||||
parameters = gecko_taskgraph.parameters.parameters_loader(options["parameters"])
|
||||
parameters = parameters_loader(options["parameters"])
|
||||
|
||||
tgg = gecko_taskgraph.generator.TaskGraphGenerator(
|
||||
root_dir=options.get("root"),
|
||||
|
|
|
@ -9,9 +9,9 @@ import os
|
|||
|
||||
import pytest
|
||||
from responses import RequestsMock, logger as rsps_logger
|
||||
from taskgraph.parameters import parameters_loader
|
||||
|
||||
from gecko_taskgraph.generator import TaskGraphGenerator
|
||||
from gecko_taskgraph.parameters import parameters_loader
|
||||
from gecko_taskgraph.util.hg import PUSHLOG_PUSHES_TMPL
|
||||
from gecko_taskgraph.util.bugbug import BUGBUG_BASE_URL
|
||||
|
||||
|
|
|
@ -14,13 +14,10 @@ from mach.util import get_state_dir
|
|||
from mozbuild.base import MozbuildObject
|
||||
from mozpack.files import FileFinder
|
||||
from moztest.resolve import TestResolver, TestManifestLoader, get_suite_definition
|
||||
from taskgraph.parameters import ParameterMismatch, parameters_loader
|
||||
|
||||
import gecko_taskgraph
|
||||
from gecko_taskgraph.generator import TaskGraphGenerator
|
||||
from gecko_taskgraph.parameters import (
|
||||
ParameterMismatch,
|
||||
parameters_loader,
|
||||
)
|
||||
from gecko_taskgraph.taskgraph import TaskGraph
|
||||
|
||||
here = os.path.abspath(os.path.dirname(__file__))
|
||||
|
|
Загрузка…
Ссылка в новой задаче