tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

attributes.py (5497B)


      1 # This Source Code Form is subject to the terms of the Mozilla Public
      2 # License, v. 2.0. If a copy of the MPL was not distributed with this
      3 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
      4 
      5 
      6 import re
      7 from typing import Literal, Union
      8 
      9 from taskgraph.util.attributes import _match_run_on
     10 
     11 INTEGRATION_PROJECTS = {
     12    "autoland",
     13 }
     14 
     15 TRUNK_PROJECTS = INTEGRATION_PROJECTS | {"mozilla-central", "comm-central"}
     16 
     17 # Mapping of project to list of branches that should be considered "release"
     18 # level. A value of `True` means all branches are considered release
     19 # (used by hg.mozilla.org based projects).
     20 PROJECT_RELEASE_BRANCHES: dict[str, Union[list[str], Literal[True]]] = {
     21    # https://github.com/mozilla-firefox/firefox
     22    "firefox": [
     23        "main",
     24        "beta",
     25        "release",
     26        "esr115",
     27        "esr128",
     28        "esr140",
     29    ],
     30    "mozilla-central": True,
     31    "mozilla-beta": True,
     32    "mozilla-release": True,
     33    "mozilla-esr115": True,
     34    "mozilla-esr128": True,
     35    "mozilla-esr140": True,
     36    "comm-central": True,
     37    "comm-beta": True,
     38    "comm-release": True,
     39    "comm-esr115": True,
     40    "comm-esr128": True,
     41    "comm-esr140": True,
     42    # bug 1845368: pine is a permanent project branch used for testing
     43    # nightly updates
     44    "pine": True,
     45    # bug 1877483: larch has similar needs for nightlies
     46    "larch": True,
     47    # maple is also an L3 branch: https://phabricator.services.mozilla.com/D184833
     48    "maple": True,
     49    # bug 1988213: cypress project branch
     50    "cypress": True,
     51 }
     52 RELEASE_PROJECTS = set(PROJECT_RELEASE_BRANCHES)
     53 RELEASE_PROMOTION_PROJECTS = {
     54    "jamun",
     55    "maple",
     56    "try",
     57    "try-comm-central",
     58 } | RELEASE_PROJECTS
     59 
     60 TEMPORARY_PROJECTS = set({
     61    # When using a "Disposable Project Branch" you can specify your branch here. e.g.:
     62    "oak",
     63 })
     64 
     65 TRY_PROJECTS = {
     66    "staging-firefox",  # https://github.com/mozilla-releng/staging-firefox
     67    "try",
     68    "try-comm-central",
     69 }
     70 
     71 ALL_PROJECTS = RELEASE_PROMOTION_PROJECTS | TRUNK_PROJECTS | TEMPORARY_PROJECTS
     72 
     73 RUN_ON_PROJECT_ALIASES = {
     74    # key is alias, value is lambda to test it against
     75    "all": lambda params: True,
     76    "integration": lambda params: (
     77        params["project"] in INTEGRATION_PROJECTS or params["project"] == "toolchains"
     78    ),
     79    "release": lambda params: (
     80        release_level(params) == "production" or params["project"] == "toolchains"
     81    ),
     82    "trunk": lambda params: (
     83        params["project"] in TRUNK_PROJECTS or params["project"] == "toolchains"
     84    ),
     85    "trunk-only": lambda params: params["project"] in TRUNK_PROJECTS,
     86    "autoland": lambda params: params["project"] in ("autoland", "toolchains"),
     87    "autoland-only": lambda params: params["project"] == "autoland",
     88    "mozilla-central": lambda params: params["project"]
     89    in ("mozilla-central", "toolchains"),
     90    "mozilla-central-only": lambda params: params["project"] == "mozilla-central",
     91 }
     92 
     93 _COPYABLE_ATTRIBUTES = (
     94    "accepted-mar-channel-ids",
     95    "artifact_map",
     96    "artifact_prefix",
     97    "build_platform",
     98    "build_type",
     99    "l10n_chunk",
    100    "locale",
    101    "mar-channel-id",
    102    "maven_packages",
    103    "nightly",
    104    "required_signoffs",
    105    "shippable",
    106    "shipping_phase",
    107    "shipping_product",
    108    "signed",
    109    "stub-installer",
    110    "update-channel",
    111 )
    112 
    113 
    114 def match_run_on_projects(params, run_on_projects):
    115    """Determine whether the given project is included in the `run-on-projects`
    116    parameter, applying expansions for things like "integration" mentioned in
    117    the attribute documentation."""
    118    aliases = RUN_ON_PROJECT_ALIASES.keys()
    119    run_aliases = set(aliases) & set(run_on_projects)
    120    if run_aliases:
    121        if any(RUN_ON_PROJECT_ALIASES[alias](params) for alias in run_aliases):
    122            return True
    123 
    124    return params["project"] in run_on_projects
    125 
    126 
    127 def match_run_on_hg_branches(hg_branch, run_on_hg_branches):
    128    """Determine whether the given project is included in the `run-on-hg-branches`
    129    parameter. Allows 'all'."""
    130    if "all" in run_on_hg_branches:
    131        return True
    132 
    133    for expected_hg_branch_pattern in run_on_hg_branches:
    134        if re.match(expected_hg_branch_pattern, hg_branch):
    135            return True
    136 
    137    return False
    138 
    139 
    140 match_run_on_repo_type = _match_run_on
    141 
    142 
    143 def copy_attributes_from_dependent_job(dep_job, denylist=()):
    144    return {
    145        attr: dep_job.attributes[attr]
    146        for attr in _COPYABLE_ATTRIBUTES
    147        if attr in dep_job.attributes and attr not in denylist
    148    }
    149 
    150 
    151 def sorted_unique_list(*args):
    152    """Join one or more lists, and return a sorted list of unique members"""
    153    combined = set().union(*args)
    154    return sorted(combined)
    155 
    156 
    157 def release_level(params):
    158    """
    159    Whether this is a staging release or not.
    160 
    161    :return str: One of "production" or "staging".
    162    """
    163    if branches := PROJECT_RELEASE_BRANCHES.get(params.get("project")):
    164        if branches is True:
    165            return "production"
    166 
    167        m = re.match(r"refs/heads/(\S+)$", params["head_ref"])
    168        if m is not None and m.group(1) in branches:
    169            return "production"
    170 
    171    return "staging"
    172 
    173 
    174 def is_try(params):
    175    """
    176    Determine whether this graph is being built on a try project or for
    177    `mach try fuzzy`.
    178    """
    179    return "try" in params["project"] or params["try_mode"] == "try_select"
    180 
    181 
    182 def task_name(task):
    183    if task.label.startswith(task.kind + "-"):
    184        return task.label[len(task.kind) + 1 :]
    185    raise AttributeError(f"Task {task.label} does not have a name.")