commit ceba5314bbe164360d211ed816d29b20e4294e34
parent 00f0efca2df30c6c2e602506444541d227c77c4f
Author: Bastien Orivel <borivel@mozilla.com>
Date: Fri, 28 Nov 2025 09:44:36 +0000
Bug 1999650 - Add support for moving RPM package into candidates. r=releng-reviewers,taskgraph-reviewers,bhearsum
This matches what we do with deb packages but there's one major
difference in that the rpm building happens in a single task, building
langpacks for all locales instead of having one task per. That means
that we can't just have beetmover-repackage pull in the rpm repackage
task as a dependency for each locale from the `group-by: single-locale`
since the rpm repackaging task doesn't have any locale related
attribute.
To work around the issue, we create a task that uploads everything RPM
related at once. That of course created its own challenge because we
now needed to add `en-US` in the list of languages to pull in the actual
firefox package but we don't want to upload a langpack for that, hence
the `not_for_locales`.
The last tidbit is that we don't want to upload langpacks twice, so we
only take them from linux64- tasks.
Differential Revision: https://phabricator.services.mozilla.com/D272615
Diffstat:
7 files changed, 215 insertions(+), 7 deletions(-)
diff --git a/python/mozbuild/mozbuild/repackaging/rpm.py b/python/mozbuild/mozbuild/repackaging/rpm.py
@@ -158,8 +158,12 @@ def _generate_rpm_archive(
os.mkdir(upload_dir)
l10n_rpm_directory = pathlib.Path(target_dir, "noarch")
- for filename in l10n_rpm_directory.glob("*.rpm"):
- shutil.copy(filename, upload_dir)
+ for locale in build_variables["LANGUAGES"]:
+ source_filename = f"{build_variables['PKG_NAME']}-l10n-{locale}-{build_variables['PKG_VERSION']}-{build_variables['PKG_BUILD_NUMBER']}.noarch.rpm"
+ new_filename = f"langpack-{locale}.noarch.rpm"
+
+ source_path = l10n_rpm_directory / source_filename
+ shutil.copy(source_path, os.path.join(upload_dir, new_filename))
def _get_build_variables(
diff --git a/python/mozbuild/mozbuild/test/repackaging/test_rpm.py b/python/mozbuild/mozbuild/test/repackaging/test_rpm.py
@@ -343,6 +343,7 @@ def test_generate_rpm_archive(monkeypatch, does_rpm_package_exist, expectation):
"PKG_NAME": "firefox",
"PKG_VERSION": "111.0",
"PKG_BUILD_NUMBER": 1,
+ "LANGUAGES": ["dummy"],
},
arch="x86",
)
@@ -365,14 +366,17 @@ def test_generate_rpm_archive(monkeypatch, does_rpm_package_exist, expectation):
)
assert ("copy", expected_rpm_path, "target.rpm") in copy_call_history
- # Finally, it copies any additional RPM files from the noarch directory.
- # Since our pathlib.Path.glob returns one dummy file from the noarch dir:
+ # Finally, it copies any langpack RPM files from the noarch directory based on the LANGUAGES build variable.
expected_dummy_path = mozpath.join(
- temp_testing_dir_name, "target_dir", "noarch", "langpack.dummy.rpm"
+ temp_testing_dir_name,
+ "target_dir",
+ "noarch",
+ "firefox-l10n-dummy-111.0-1.noarch.rpm",
)
- # Look for a call that copies the dummy file to the upload dir:
+ expected_dest = mozpath.join(upload_dir, "langpack-dummy.noarch.rpm")
+ # Look for a call that copies the langpack file to the upload dir:
found = any(
- src == expected_dummy_path and dst == upload_dir
+ str(src) == expected_dummy_path and dst == expected_dest
for _, src, dst in copy_call_history
)
assert found, "The dummy langpack RPM file was not copied to the upload_dir."
diff --git a/taskcluster/docs/kinds.rst b/taskcluster/docs/kinds.rst
@@ -312,6 +312,10 @@ beetmover-apt
-------------------
Beetmover-apt publishes Linux .deb packages from the Mozilla archive to our APT repositories.
+beetmover-repackage-rpm
+-----------------------
+Beetmover-repackage-rpm publishes Linux .rpm packages (main package and all langpacks) to the candidates directory.
+
condprof
--------
condprof creates and updates realistic profiles.
diff --git a/taskcluster/gecko_taskgraph/manifests/firefox_candidates.yml b/taskcluster/gecko_taskgraph/manifests/firefox_candidates.yml
@@ -50,6 +50,7 @@ tasktype_map:
repackage: repackage
repackage-deb: repackage
repackage-deb-l10n: repackage
+ repackage-rpm: repackage
repackage-signing: repackage
repackage-signing-msi: repackage
repackage-signing-shippable-l10n-msix: signing
@@ -398,6 +399,42 @@ mapping:
- repackage-deb
update_balrog_manifest: false
expiry: "1 year"
+ target.rpm:
+ <<: *default
+ description: "Firefox as a .rpm package"
+ locale_prefix: ''
+ only_for_platforms:
+ - linux64-shippable
+ - linux64-aarch64-shippable
+ - linux64-devedition
+ - linux64-aarch64-devedition
+ pretty_name: firefox-${version}.rpm
+ checksums_path: ${path_platform}/rpm/firefox-${version}.rpm
+ from:
+ - repackage-rpm
+ destinations:
+ - ${version}-candidates/build${build_number}/${path_platform}/rpm
+ update_balrog_manifest: false
+ expiry: "1 year"
+ langpack-${locale}.noarch.rpm:
+ <<: *default
+ description: "langpack.xpi repackaged as a .rpm"
+ all_locales: true
+ locale_prefix: ''
+ source_path_modifier: ''
+ from:
+ - repackage-rpm
+ not_for_locales:
+ - en-US
+ only_for_platforms:
+ - linux64-shippable
+ - linux64-devedition
+ pretty_name: firefox-l10n-${locale}-${version}.noarch.rpm
+ checksums_path: ${path_platform}/rpm/firefox-l10n-${locale}-${version}.noarch.rpm
+ destinations:
+ - ${version}-candidates/build${build_number}/${path_platform}/rpm
+ update_balrog_manifest: false
+ expiry: "1 year"
${partial}:
<<: *default
description: "Partials MAR files to serve as updates"
diff --git a/taskcluster/gecko_taskgraph/manifests/firefox_nightly.yml b/taskcluster/gecko_taskgraph/manifests/firefox_nightly.yml
@@ -45,6 +45,7 @@ tasktype_map:
repackage: repackage
repackage-deb: repackage
repackage-deb-l10n: repackage
+ repackage-rpm: repackage
repackage-signing: repackage
repackage-signing-msi: repackage
repackage-signing-shippable-l10n-msix: signing
@@ -463,6 +464,40 @@ mapping:
destinations:
- ${year}/${month}/${upload_date}-${branch}
- latest-${branch}
+ target.rpm:
+ <<: *default
+ description: "Firefox as a .rpm package"
+ only_for_platforms:
+ - linux64-shippable
+ - linux64-aarch64-shippable
+ - linux64-devedition
+ - linux64-aarch64-devedition
+ pretty_name: firefox-${version}.${filename_platform}.rpm
+ checksums_path: ${filename_platform}/rpm/firefox-${version}.rpm
+ from:
+ - repackage-rpm
+ destinations:
+ - ${year}/${month}/${upload_date}-${branch}
+ - latest-${branch}
+ update_balrog_manifest: false
+ langpack-${locale}.noarch.rpm:
+ <<: *default
+ description: "langpack.xpi repackaged as a .rpm"
+ all_locales: true
+ locale_prefix: ''
+ from:
+ - repackage-rpm
+ not_for_locales:
+ - en-US
+ only_for_platforms:
+ - linux64-shippable
+ - linux64-devedition
+ pretty_name: firefox-l10n-${locale}-${version}.noarch.rpm
+ checksums_path: ${filename_platform}/rpm/firefox-l10n-${locale}-${version}.noarch.rpm
+ destinations:
+ - ${year}/${month}/${upload_date}-${branch}-l10n/${filename_platform}/rpm
+ - latest-${branch}-l10n/${filename_platform}/rpm
+ update_balrog_manifest: false
${partial}:
<<: *default
description: "Partials MAR files to serve as updates"
diff --git a/taskcluster/gecko_taskgraph/transforms/beetmover_repackage_rpm.py b/taskcluster/gecko_taskgraph/transforms/beetmover_repackage_rpm.py
@@ -0,0 +1,89 @@
+# 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 beetmover-repackage-rpm task into an actual task description.
+"""
+
+from taskgraph.transforms.base import TransformSequence
+from taskgraph.util.dependencies import get_primary_dependency
+from taskgraph.util.schema import Schema
+from taskgraph.util.treeherder import inherit_treeherder_from_dep, replace_group
+from voluptuous import Required
+
+from gecko_taskgraph.transforms.beetmover import craft_release_properties
+from gecko_taskgraph.transforms.task import task_description_schema
+from gecko_taskgraph.util.scriptworker import (
+ generate_beetmover_artifact_map,
+ generate_beetmover_upstream_artifacts,
+ get_beetmover_action_scope,
+ get_beetmover_bucket_scope,
+)
+
+transforms = TransformSequence()
+
+beetmover_description_schema = Schema(
+ {
+ Required("attributes"): task_description_schema["attributes"],
+ Required("dependencies"): task_description_schema["dependencies"],
+ Required("label"): str,
+ Required("name"): str,
+ Required("shipping-phase"): task_description_schema["shipping-phase"],
+ Required("task-from"): task_description_schema["task-from"],
+ }
+)
+
+transforms.add_validate(beetmover_description_schema)
+
+
+@transforms.add
+def make_beetmover_rpm_task(config, jobs):
+ for job in jobs:
+ dep_job = get_primary_dependency(config, job)
+ assert dep_job
+
+ attributes = job["attributes"]
+ platform = attributes["build_platform"]
+
+ bucket_scope = get_beetmover_bucket_scope(config)
+ action_scope = get_beetmover_action_scope(config)
+
+ dependencies = {"repackage-rpm": dep_job.label}
+ treeherder = inherit_treeherder_from_dep(job, dep_job)
+ upstream_symbol = dep_job.task["extra"]["treeherder"]["symbol"]
+ treeherder.setdefault("symbol", replace_group(upstream_symbol, "BMR"))
+
+ task = {
+ "label": job["label"],
+ "description": f"Publish RPM packages for {platform}",
+ "worker-type": "beetmover",
+ "scopes": [bucket_scope, action_scope],
+ "dependencies": dependencies,
+ "attributes": attributes,
+ "run-on-projects": dep_job.attributes.get("run_on_projects"),
+ "treeherder": treeherder,
+ "shipping-phase": job["shipping-phase"],
+ "shipping-product": job.get("shipping-product"),
+ }
+
+ locales = ["en-US"]
+ for dep_task in config.kind_dependencies_tasks.values():
+ if dep_task.kind in ("shippable-l10n-signing", "l10n"):
+ if dep_task.attributes.get("build_platform") == platform:
+ task_locales = dep_task.attributes.get(
+ "chunk_locales", dep_task.attributes.get("all_locales", [])
+ )
+ locales.extend(task_locales)
+
+ task["worker"] = {
+ "implementation": "beetmover",
+ "release-properties": craft_release_properties(config, task),
+ "upstream-artifacts": generate_beetmover_upstream_artifacts(
+ config, task, platform=platform, locale=locales
+ ),
+ "artifact-map": generate_beetmover_artifact_map(
+ config, task, platform=platform, locale=locales
+ ),
+ }
+
+ yield task
diff --git a/taskcluster/kinds/beetmover-repackage-rpm/kind.yml b/taskcluster/kinds/beetmover-repackage-rpm/kind.yml
@@ -0,0 +1,35 @@
+# 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/.
+---
+loader: taskgraph.loader.transform:loader
+
+transforms:
+ - taskgraph.transforms.from_deps
+ - gecko_taskgraph.transforms.name_sanity
+ - gecko_taskgraph.transforms.beetmover_repackage_rpm
+ - gecko_taskgraph.transforms.task
+
+kind-dependencies:
+ - repackage-rpm
+ - shippable-l10n-signing
+ - l10n
+
+only-for-build-platforms:
+ - linux64-shippable/opt
+ - linux64-aarch64-shippable/opt
+ - linux64-devedition/opt
+ - linux64-aarch64-devedition/opt
+
+tasks:
+ beetmover-repackage-rpm:
+ from-deps:
+ group-by: platform
+ unique-kinds: false
+ copy-attributes: true
+ shipping-phase: promote
+ attributes:
+ artifact_map:
+ by-release-type:
+ beta|release.*|esr.*: taskcluster/gecko_taskgraph/manifests/firefox_candidates.yml
+ default: taskcluster/gecko_taskgraph/manifests/firefox_nightly.yml