diff --git a/taskcluster/ci/attribution-l10n/kind.yml b/taskcluster/ci/attribution-l10n/kind.yml new file mode 100644 index 000000000000..bd87f0d00378 --- /dev/null +++ b/taskcluster/ci/attribution-l10n/kind.yml @@ -0,0 +1,141 @@ +# 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: gecko_taskgraph.loader.transform:loader + +transforms: + - gecko_taskgraph.transforms.split_by_locale:transforms + - gecko_taskgraph.transforms.job:transforms + - gecko_taskgraph.transforms.task:transforms + +kind-dependencies: + # Windows + - repackage-signing-l10n + +job-defaults: + description: Attribute release builds + shipping-phase: promote + # never run as part of CI + run-on-projects: [] + worker-type: b-linux-gcp + locales-file: browser/locales/l10n-changesets.json + properties-with-locale: + - label + - dependencies.repackage-signing-l10n + - treeherder.symbol + - fetches.repackage-signing-l10n + attributes: + build_type: opt + treeherder: + symbol: Attr-L10n({locale}) + kind: other + tier: 1 + fetches: + repackage-signing-l10n: + - "{locale}/target.installer.exe" + worker: + artifacts: + - name: public/build + type: directory + path: /builds/worker/artifacts + docker-image: + in-tree: "partner-repack" + chain-of-trust: true + # Each task only processes one installer...this should be quick. + max-run-time: 600 + run: + using: run-task + cwd: "{checkout}" + command: + - ./mach + - python + - python/mozrelease/mozrelease/attribute_builds.py + - --attribution + - dlsource={attribution_code[json][dlsource]} + - --output + - /builds/worker/artifacts + # All jobs require attribution of target.installer.exe. Some may require + # attribution of other files, which they can append themselves. + - --input + - /builds/worker/fetches/target.installer.exe + command-context: + from-file: browser/installer/attribution.yml + +jobs: + win32-devedition/opt: + label: attribution-win32-{locale}-devedition/opt + shipping-product: devedition + attributes: + build_platform: win32-devedition + treeherder: + platform: win32-devedition/opt + fetches: + repackage-signing-l10n: + - "{locale}/target.stub-installer.exe" + dependencies: + repackage-signing-l10n: repackage-signing-l10n-{locale}-win32-devedition/opt + run: + command: + - --input + - /builds/worker/fetches/target.stub-installer.exe + + win32-shippable/opt: + label: attribution-win32-{locale}-shippable/opt + shipping-product: firefox + locale-file-platform: win32 + attributes: + build_platform: win32-shippable + treeherder: + platform: win32-shippable/opt + fetches: + repackage-signing-l10n: + - "{locale}/target.stub-installer.exe" + dependencies: + repackage-signing-l10n: repackage-signing-l10n-{locale}-win32-shippable/opt + run: + command: + - --input + - /builds/worker/fetches/target.stub-installer.exe + + win64-devedition/opt: + label: attribution-win64-{locale}-devedition/opt + shipping-product: devedition + attributes: + build_platform: win64-devedition + treeherder: + platform: win64-devedition/opt + dependencies: + repackage-signing-l10n: repackage-signing-l10n-{locale}-win64-devedition/opt + + win64-shippable/opt: + label: attribution-win64-{locale}-shippable/opt + shipping-product: firefox + locale-file-platform: win64 + attributes: + build_platform: win64-shippable + treeherder: + platform: win64-shippable/opt + dependencies: + repackage-signing-l10n: repackage-signing-l10n-{locale}-win64-shippable/opt + + win64-aarch64-shippable/opt: + label: attribution-win64-aarch64-{locale}-shippable/opt + shipping-product: firefox + locale-file-platform: win64-aarch64 + attributes: + build_platform: win64-aarch64-shippable + treeherder: + platform: win64-aarch64-shippable/opt + dependencies: + repackage-signing-l10n: repackage-signing-l10n-{locale}-win64-aarch64-shippable/opt + + win64-aarch64-devedition/opt: + label: attribution-win64-aarch64-{locale}-devedition/opt + shipping-product: devedition + attributes: + build_platform: win64-aarch64-devedition + treeherder: + platform: win64-aarch64-devedition/opt + dependencies: + repackage-signing-l10n: repackage-signing-l10n-{locale}-win64-aarch64-devedition/opt diff --git a/taskcluster/ci/config.yml b/taskcluster/ci/config.yml index 980c464498da..f86700d9b44f 100644 --- a/taskcluster/ci/config.yml +++ b/taskcluster/ci/config.yml @@ -204,6 +204,7 @@ treeherder: 'fxrec': 'Desktop startup recorder (fxrecord)' 'wc': 'webcompat' 'Boot': 'Bootstrap' + 'Attr-L10n': 'todo' index: products: diff --git a/taskcluster/docs/kinds.rst b/taskcluster/docs/kinds.rst index 19f47a975bc0..f5f8669c5d43 100644 --- a/taskcluster/docs/kinds.rst +++ b/taskcluster/docs/kinds.rst @@ -750,3 +750,7 @@ Collects data about the transition to ECMAScript Modules from JSMs. attribution ----------- Injects attribution information into en-US installers. + +attribution-l10n +---------------- +Injects attribution information into localized installers. diff --git a/taskcluster/gecko_taskgraph/transforms/split_by_locale.py b/taskcluster/gecko_taskgraph/transforms/split_by_locale.py new file mode 100644 index 000000000000..ae68ab505150 --- /dev/null +++ b/taskcluster/gecko_taskgraph/transforms/split_by_locale.py @@ -0,0 +1,79 @@ +# 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/. +""" +This transform splits the jobs it receives into per-locale tasks. Locales are +provided by the `locales-file`. +""" + +from copy import deepcopy +from pprint import pprint + +from taskgraph.transforms.base import TransformSequence +from taskgraph.util.schema import Schema +from voluptuous import Extra, Optional, Required + +from gecko_taskgraph.transforms.l10n import parse_locales_file + +transforms = TransformSequence() + +split_by_locale_schema = Schema( + { + # The file to pull locale information from. This should be a json file + # such as browser/locales/l10n-changesets.json. + Required("locales-file"): str, + # The platform name in the form used by the locales files. Defaults to + # attributes.build_platform if not provided. + Optional("locale-file-platform"): str, + # A list of properties elsewhere in the job that need to have the locale + # name substituted into them. The referenced properties may be strings + # or lists. In the case of the latter, all list values will have + # substitutions performed. + Optional("properties-with-locale"): [str], + Extra: object, + } +) + + +transforms.add_validate(split_by_locale_schema) + + +@transforms.add +def add_command(config, jobs): + for job in jobs: + locales_file = job.pop("locales-file") + properties_with_locale = job.pop("properties-with-locale") + build_platform = job.pop( + "locale-file-platform", job["attributes"]["build_platform"] + ) + + for locale in parse_locales_file(locales_file, build_platform): + locale_job = deepcopy(job) + locale_job["attributes"]["locale"] = locale + for prop in properties_with_locale: + container, subfield = locale_job, prop + while "." in subfield: + f, subfield = subfield.split(".", 1) + if f not in container: + raise Exception( + f"Unable to find property {prop} to perform locale substitution on. Job is:\n{pprint(job)}" + ) + container = container[f] + if not isinstance(container, dict): + raise Exception( + f"{container} is not a dict, cannot perform locale substitution. Job is:\n{pprint(job)}" + ) + + if isinstance(container[subfield], str): + container[subfield] = container[subfield].format(locale=locale) + elif isinstance(container[subfield], list): + for i in range(len(container[subfield])): + container[subfield][i] = container[subfield][i].format( + locale=locale + ) + else: + raise Exception( + f"Don't know how to subtitute locale for value of type: {type(container[subfield])}; value is: {container[subfield]}" + ) + + yield locale_job