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
253 changes: 252 additions & 1 deletion .taskcluster.yml

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions python/mozbuild/mozbuild/action/test_archive.py
Original file line number Diff line number Diff line change
Expand Up @@ -761,7 +761,17 @@
"source": buildconfig.topsrcdir,
"base": "testing/enterprise/",
"patterns": ["**"],
"dest": "marionette/tests",
})
if buildconfig.substs.get("commtopsrcdir"):
commtopsrcdir = buildconfig.substs.get("commtopsrcdir")
thunderbirdinstance = {
"source": commtopsrcdir,
"base": "mail/test/marionette/enterprise",
"pattern": "**",
"dest": "marionette/tests/comm",
}
ARCHIVE_FILES["enterprise"].append(thunderbirdinstance)

# "common" is our catch all archive and it ignores things from other archives.
# Verify nothing sneaks into ARCHIVE_FILES without a corresponding exclusion
Expand Down
37 changes: 28 additions & 9 deletions python/mozbuild/mozbuild/artifacts.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,23 @@ class ThunderbirdJobConfiguration:
try_tree = "try-comm-central"


class EnterpriseThunderbirdJobConfiguration:
trust_domain = "enterprise"
product = "thunderbird"
default_candidate_trees = [
"enterprise-thunderbird.branch.enterprise-release",
]
nightly_candidate_trees = [
"enterprise-thunderbird.branch.enterprise-main",
]
beta_candidate_trees = [
"enterprise-thunderbird.branch.enterprise-beta",
]
# The list below list should be updated when we have new ESRs.
esr_candidate_trees = []
try_tree = "try"


class ArtifactJob:
def _get_orig_basename(self, filename):
"""Extract the original basename from a filename, removing hash prefixes if present."""
Expand Down Expand Up @@ -1306,13 +1323,15 @@ def __init__(
self._no_process = no_process
self._unfiltered_project_package = unfiltered_project_package

job_configuration = (
ThunderbirdJobConfiguration
if substs.get("MOZ_BUILD_APP") == "comm/mail"
else EnterpriseJobConfiguration
if substs.get("MOZ_ENTERPRISE") == "1"
else None
)
if substs.get("MOZ_BUILD_APP") == "comm/mail": # and substs.get("MOZ_ENTERPRISE") != "1":
job_configuration = ThunderbirdJobConfiguration
# elif substs.get("MOZ_BUILD_APP") == "comm/mail" and substs.get("MOZ_ENTERPRISE") == "1":
# job_configuration = EnterpriseThunderbirdJobConfiguration
elif substs.get("MOZ_ENTERPRISE") == "1":
job_configuration = EnterpriseJobConfiguration
else:
job_configuration = None

if not self._unfiltered_project_package:
try:
cls = JOB_DETAILS[self._job]
Expand Down Expand Up @@ -1432,8 +1451,8 @@ def _guess_artifact_job(self):
else:
target_suffix = "-opt"

if self._substs.get("MOZ_ENTERPRISE"):
target_suffix = "-enterprise" + target_suffix
if self._substs.get("MOZ_ENTERPRISE") and not self._substs.get("MOZ_BUILD_APP", "") == "comm/mail":
target_suffix = "-enteprise" + target_suffix

if self._substs.get("MOZ_BUILD_APP", "") == "mobile/android":
if self._substs["ANDROID_CPU_ARCH"] == "x86_64":
Expand Down
1 change: 1 addition & 0 deletions python/mozbuild/mozbuild/toolchains.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ def toolchain_task_definitions():
"head_repository": "https://github.com/mozilla/enterprise-firefox",
"repository_type": "git",
"pull_request_number": 0,
"trigger_project": "enterprise-firefox",
}

import sys
Expand Down
39 changes: 28 additions & 11 deletions python/mozrelease/mozrelease/partner_repack.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,6 @@
UPSTREAM_ENUS_PATH = "public/build/{filename}"
UPSTREAM_L10N_PATH = "public/build/{locale}/{filename}"

WINDOWS_DEST_DIR = Path("firefox")
MAC_DEST_DIR = Path("Contents/Resources")
LINUX_DEST_DIR = Path("firefox")

BOUNCER_PRODUCT_TEMPLATE = (
"partner-firefox-{release_type}-{partner}-{partner_distro}-latest"
)
Expand Down Expand Up @@ -327,6 +323,7 @@ def __init__(
final_dir: Path,
ftp_platform: str,
repack_info,
dest_dir,
file_mode=0o644,
quiet=False,
source_locale=None,
Expand All @@ -348,6 +345,7 @@ def __init__(
self.source_locale = source_locale
self.locale = locale
self.working_dir.mkdir(mode=0o755, exist_ok=True, parents=True)
self.dest_dir = dest_dir

def announceStart(self):
log.info(
Expand Down Expand Up @@ -462,14 +460,14 @@ def unpackBuild(self):
sys.exit(1)

def copyFiles(self):
super().copyFiles(LINUX_DEST_DIR)
super().copyFiles(self.dest_dir)

def repackBuild(self):
if options.quiet:
tar_flags = "rf"
else:
tar_flags = "rvf"
tar_cmd = "tar %s %s %s" % (tar_flags, self.uncompressed_build, LINUX_DEST_DIR)
tar_cmd = "tar %s %s %s" % (tar_flags, self.uncompressed_build, self.dest_dir)
shellCommand(tar_cmd)
compress_cmd = "xz -f -z -e -9 %s" % self.uncompressed_build
shellCommand(compress_cmd)
Expand Down Expand Up @@ -520,7 +518,7 @@ def getAppName(self):
sys.exit(1)

def copyFiles(self):
super().copyFiles(Path(self.appName) / MAC_DEST_DIR)
super().copyFiles(Path(self.appName) / self.dest_dir)

def repackBuild(self):
if options.quiet:
Expand All @@ -531,7 +529,7 @@ def repackBuild(self):
tar_cmd = "tar %s %s '%s'" % (
tar_flags,
self.uncompressed_build,
Path(self.appName) / MAC_DEST_DIR,
Path(self.appName) / self.dest_dir,
)
shellCommand(tar_cmd)
gzip_command = "gzip %s" % self.uncompressed_build
Expand Down Expand Up @@ -560,14 +558,14 @@ def __init__(
)

def copyFiles(self):
super().copyFiles(WINDOWS_DEST_DIR)
super().copyFiles(self.dest_dir)

def repackBuild(self):
if options.quiet:
zip_flags = "-rq"
else:
zip_flags = "-r"
zip_cmd = f"zip {zip_flags} {self.build} {WINDOWS_DEST_DIR}"
zip_cmd = f"zip {zip_flags} {self.build} {self.dest_dir}"
shellCommand(zip_cmd)

# we generate the stub installer during the win32 build, so repack it on win32 too
Expand All @@ -585,7 +583,7 @@ def repackBuild(self):
partner_ini += l
z.writestr("partner.ini", partner_ini)
# we need an empty firefox directory to use the repackage code
d = zipfile.ZipInfo("firefox/")
d = zipfile.ZipInfo(f"{self.dest_dir}/")
# https://stackoverflow.com/a/6297838, zip's representation of drwxr-xr-x permissions
# is 040755 << 16L, bitwise OR with 0x10 for the MS-DOS directory flag
d.external_attr = 1106051088
Expand Down Expand Up @@ -688,6 +686,14 @@ def stage(self):
default=[],
)

parser.add_option(
"--windows-dest-dir", dest="windows_dest_dir", help="Windows dest dir"
)
parser.add_option("--mac-dest-dir", dest="mac_dest_dir", help="Windows dest dir")
parser.add_option(
"--linux-dest-dir", dest="linux_dest_dir", help="Windows dest dir"
)

(options, args) = parser.parse_args()

if not options.quiet:
Expand Down Expand Up @@ -877,13 +883,24 @@ def stage(self):
log.info(f"Error: Unable to retrieve {file_name}\n")
sys.exit(1)

dest_dir = None
if "win" in ftp_platform:
dest_dir = Path(options.windows_dest_dir)
elif "mac" in ftp_platform:
dest_dir = Path(options.mac_dest_dir)
elif "linux" in ftp_platform:
dest_dir = Path(options.linux_dest_dir)
else:
raise ValueError(f"Unsupported platform: {ftp_platform}")

repackObj = repack_build[ftp_platform](
file_name,
full_partner_dir,
local_filepath,
final_dir,
ftp_platform,
repack_info,
dest_dir=dest_dir,
locale=locale,
source_locale=source_locale,
)
Expand Down
4 changes: 4 additions & 0 deletions taskcluster/docs/parameters.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,10 @@ topic.

: The GitHub pull request number, if any.

`trigger_project`

: The name of the GitHub repo, distinct from --project CLI parameter

`dontbuild`

: Set (to `true`) when the commit message requested that no tasks run on this push.
Expand Down
10 changes: 10 additions & 0 deletions taskcluster/gecko_taskgraph/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

from gecko_taskgraph.config import GraphConfigSchema

from taskgraph.parameters import Parameters

GECKO = os.path.normpath(os.path.realpath(os.path.join(__file__, "..", "..", "..")))
TEST_CONFIGS = os.path.join(GECKO, "taskcluster", "test_configs")

Expand Down Expand Up @@ -75,6 +77,14 @@ def _represent_ro_dict(dumper, data):
del payload_builders["docker-worker"]
del payload_builders["generic-worker"]

orig_file_url = Parameters.file_url
def local_file_url(self, path, pretty=False):
value = orig_file_url(self, path, pretty)
if self["trigger_project"] == self["project"]:
return value
return value.replace(self["comm_head_repository"], self["head_repository"])

Parameters.file_url = local_file_url

def register(graph_config):
"""Used to register Gecko specific extensions.
Expand Down
2 changes: 2 additions & 0 deletions taskcluster/gecko_taskgraph/decision.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
from .parameters import (
get_app_version,
get_release_type,
get_trigger_project,
get_version,
)
from .util.backstop import ANDROID_PERFTEST_BACKSTOP_INDEX, BACKSTOP_INDEX, is_backstop
Expand Down Expand Up @@ -380,6 +381,7 @@ def get_decision_parameters(graph_config, options):
parameters["test_manifest_loader"] = "default"
parameters["try_mode"] = None
parameters["try_task_config"] = {}
parameters["trigger_project"] = get_trigger_project(parameters)

# owner must be an email, but sometimes (e.g., for ffxbld) it is not, in which
# case, fake it
Expand Down
6 changes: 6 additions & 0 deletions taskcluster/gecko_taskgraph/parameters.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ class GeckoParametersSchema(Schema, kw_only=True, rename=None):
head_git_repository: Optional[str] = None
head_git_rev: Optional[str] = None
pull_request_number: Optional[int] = None
trigger_project: Optional[str] = None


def get_contents(path):
Expand Down Expand Up @@ -121,6 +122,11 @@ def get_release_type(parameters):
else:
return "nightly-enterprise"

def get_trigger_project(parameters):
if trigger_project := os.environ.get("TRIGGER_PROJECT", None):
return trigger_project
return parameters["project"]


def get_defaults(repo_root=None):
return {
Expand Down
10 changes: 8 additions & 2 deletions taskcluster/gecko_taskgraph/target_tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -514,12 +514,15 @@ def filter(task):
return False

# Only keep builds that have been explicitely flagged
if task.kind == "build" and not "enterprise-firefox" in task.attributes.get(
if task.kind == "build" and not parameters["project"] in task.attributes.get(
"run_on_projects"
):
return False

if task.attributes.get("shipping_product") not in (None, "firefox-enterprise"):
if task.attributes.get("shipping_product") not in (
None,
parameters["release_product"],
):
return False

build_platform = task.attributes.get("build_platform")
Expand All @@ -529,6 +532,9 @@ def filter(task):

level = int(parameters["level"])
if level < 3:
if "thunderbird-enterprise" == task.attributes.get("shipping_product"):
return True

if "shippable" in task.label or shippable:
return False

Expand Down
12 changes: 10 additions & 2 deletions taskcluster/gecko_taskgraph/transforms/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,9 @@ def add_signing_artifacts(config, jobs):
elif "enterprise-firefox" == config.params["project"]:
# Firefox Enterprise
browser_entitlement = "firefoxenterprise.browser"
elif "enterprise-thunderbird" == config.params["project"]:
# Thunderbird Enterprise
browser_entitlement = "thunderbirdenterprise.browser"
else:
# Release and Beta
browser_entitlement = "firefox.browser"
Expand All @@ -322,7 +325,8 @@ def add_signing_artifacts(config, jobs):
# For builds using docker-worker we can't use relative paths
# Once we switch builds to generic-worker, this can be removed
for entry in job.get("worker", {}).get("artifacts", []):
if entry.get("path", "").startswith("checkouts/gecko/security"):
entry_path = entry.get("path", "")
if entry_path.startswith("checkouts/gecko/security") or entry_path.startswith("checkouts/gecko/comm/build/macosx/hardenedruntime/v2"):
entry["path"] = "/builds/worker/" + entry["path"]
yield job

Expand All @@ -332,7 +336,11 @@ def add_enterprise_secret_scopes(config, jobs):
"""Enterprise builds re-use some secrets from the Gecko trust domain."""
level = config.params["level"]
for job in jobs:
if config.params["project"] in ("enterprise-firefox", "enterprise-firefox-try"):
if config.params["project"] in (
"enterprise-firefox",
"enterprise-firefox-try",
"enterprise-thunderbird",
):
job.setdefault("scopes", []).extend([
f"secrets:get:project/releng/gecko/build/level-{level}/gls-gapi.data",
f"secrets:get:project/releng/gecko/build/level-{level}/sb-gapi.data",
Expand Down
5 changes: 5 additions & 0 deletions taskcluster/gecko_taskgraph/transforms/job/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,12 @@ def support_vcs_checkout(config, job, taskdesc, repo_configs):
"COMM_BASE_REPOSITORY": config.params["comm_base_repository"],
"COMM_HEAD_REPOSITORY": config.params["comm_head_repository"],
"COMM_HEAD_REV": config.params["comm_head_rev"],
"COMM_REPOSITORY_TYPE": "git",
})

repos = json.loads(taskdesc["worker"]["env"].get("REPOSITORIES", {}))
repos.update({"comm": "Mozilla Thunderbird"})
taskdesc["worker"]["env"]["REPOSITORIES"] = json.dumps(repos)
elif job["run"].get("comm-checkout", False):
raise Exception(
"Can't checkout from comm-* repository if not given a repository."
Expand Down
7 changes: 5 additions & 2 deletions taskcluster/gecko_taskgraph/transforms/repackage_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,13 @@ def add_indexes(config, jobs):
if repackage_type and job["attributes"]["build_type"] != "debug":
build_platform = job["attributes"]["build_platform"]
job_name = f"{build_platform}-{repackage_type}"
if job.get("shipping-product", "").startswith("thunderbird"):
if "thunderbird" in job.get("shipping-product", ""):
product = job.get("index", {}).get("product", "thunderbird")
else:
elif "firefox" in config.params["project"]:
product = job.get("index", {}).get("product", "firefox")
else:
yield job
continue
index_type = "generic"
if job["attributes"].get("shippable") and job["attributes"].get("locale"):
index_type = "shippable-l10n"
Expand Down
Loading