bug 1383771 - reland e3c51a9aa108 for b7. p=jlorenzo r=me a=ritu
authorAki Sasaki <asasaki@mozilla.com>
Fri, 25 Aug 2017 17:36:41 -0700
changeset 423802 a933f4ce887f3d1c27dd836ea4e92c157eb33259
parent 423801 e876eac82b0f803bc51f5ef0ebada2652e4a2325
child 423803 9097842054e4c849051307993001d78d8e443d3f
push id1517
push userjlorenzo@mozilla.com
push dateThu, 14 Sep 2017 16:50:54 +0000
treeherdermozilla-release@3b41fd564418 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersme, ritu
bugs1383771
milestone56.0
bug 1383771 - reland e3c51a9aa108 for b7. p=jlorenzo r=me a=ritu
python/mozbuild/mozbuild/repackaging/dmg.py
taskcluster/ci/beetmover-l10n/kind.yml
taskcluster/ci/beetmover-repackage/kind.yml
taskcluster/ci/beetmover/kind.yml
taskcluster/ci/repackage-l10n/kind.yml
taskcluster/ci/repackage-signing/kind.yml
taskcluster/ci/repackage/kind.yml
taskcluster/taskgraph/transforms/beetmover_repackage.py
taskcluster/taskgraph/transforms/build_signing.py
taskcluster/taskgraph/transforms/gecko_v2_whitelist.py
taskcluster/taskgraph/transforms/nightly_l10n_signing.py
taskcluster/taskgraph/transforms/repackage.py
taskcluster/taskgraph/transforms/repackage_signing.py
taskcluster/taskgraph/transforms/signing.py
testing/mozharness/configs/repackage/win32_signed.py
testing/mozharness/configs/repackage/win64_signed.py
--- a/python/mozbuild/mozbuild/repackaging/dmg.py
+++ b/python/mozbuild/mozbuild/repackaging/dmg.py
@@ -1,12 +1,13 @@
 # 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 errno
 import os
 import tempfile
 import tarfile
 import shutil
 import mozpack.path as mozpath
 from mozpack.dmg import create_dmg
 from application_ini import get_application_ini_value
 
--- a/taskcluster/ci/beetmover-l10n/kind.yml
+++ b/taskcluster/ci/beetmover-l10n/kind.yml
@@ -11,11 +11,13 @@ transforms:
 
 kind-dependencies:
   - nightly-l10n-signing
 
 only-for-attributes:
   - nightly
 
 not-for-build-platforms:
-   - macosx64-nightly/opt
-   - win32-nightly/opt
-   - win64-nightly/opt
+  - linux-nightly/opt
+  - linux64-nightly/opt
+  - macosx64-nightly/opt
+  - win32-nightly/opt
+  - win64-nightly/opt
--- a/taskcluster/ci/beetmover-repackage/kind.yml
+++ b/taskcluster/ci/beetmover-repackage/kind.yml
@@ -8,11 +8,13 @@ transforms:
    - taskgraph.transforms.beetmover_repackage_l10n:transforms
    - taskgraph.transforms.beetmover_repackage:transforms
    - taskgraph.transforms.task:transforms
 
 kind-dependencies:
   - repackage-signing
 
 only-for-build-platforms:
+  - linux-nightly/opt
+  - linux64-nightly/opt
   - macosx64-nightly/opt
   - win32-nightly/opt
   - win64-nightly/opt
--- a/taskcluster/ci/beetmover/kind.yml
+++ b/taskcluster/ci/beetmover/kind.yml
@@ -10,11 +10,13 @@ transforms:
 
 kind-dependencies:
   - build-signing
 
 only-for-attributes:
   - nightly
 
 not-for-build-platforms:
-   - macosx64-nightly/opt
-   - win32-nightly/opt
-   - win64-nightly/opt
+  - linux-nightly/opt
+  - linux64-nightly/opt
+  - macosx64-nightly/opt
+  - win32-nightly/opt
+  - win64-nightly/opt
--- a/taskcluster/ci/repackage-l10n/kind.yml
+++ b/taskcluster/ci/repackage-l10n/kind.yml
@@ -9,11 +9,13 @@ transforms:
    - taskgraph.transforms.repackage:transforms
    - taskgraph.transforms.job:transforms
    - taskgraph.transforms.task:transforms
 
 kind-dependencies:
   - nightly-l10n-signing
 
 only-for-build-platforms:
+  - linux-nightly/opt
+  - linux64-nightly/opt
   - macosx64-nightly/opt
   - win32-nightly/opt
   - win64-nightly/opt
--- a/taskcluster/ci/repackage-signing/kind.yml
+++ b/taskcluster/ci/repackage-signing/kind.yml
@@ -9,14 +9,18 @@ transforms:
    - taskgraph.transforms.repackage_routes:transforms
    - taskgraph.transforms.task:transforms
 
 kind-dependencies:
   - repackage
   - repackage-l10n
 
 only-for-build-platforms:
+  - linux-nightly/opt
+  - linux-devedition-nightly/opt
+  - linux64-nightly/opt
+  - linux64-devedition-nightly/opt
   - macosx64-nightly/opt
   - macosx64-devedition-nightly/opt
   - win32-nightly/opt
   - win32-devedition-nightly/opt
   - win64-nightly/opt
   - win64-devedition-nightly/opt
--- a/taskcluster/ci/repackage/kind.yml
+++ b/taskcluster/ci/repackage/kind.yml
@@ -9,14 +9,18 @@ transforms:
    - taskgraph.transforms.repackage_routes:transforms
    - taskgraph.transforms.job:transforms
    - taskgraph.transforms.task:transforms
 
 kind-dependencies:
   - build-signing
 
 only-for-build-platforms:
+  - linux-nightly/opt
+  - linux-devedition-nightly/opt
+  - linux64-nightly/opt
+  - linux64-devedition-nightly/opt
   - macosx64-nightly/opt
   - macosx64-devedition-nightly/opt
   - win32-nightly/opt
   - win32-devedition-nightly/opt
   - win64-nightly/opt
   - win64-devedition-nightly/opt
--- a/taskcluster/taskgraph/transforms/beetmover_repackage.py
+++ b/taskcluster/taskgraph/transforms/beetmover_repackage.py
@@ -11,16 +11,18 @@ from taskgraph.transforms.base import Tr
 from taskgraph.util.attributes import copy_attributes_from_dependent_job
 from taskgraph.util.schema import validate_schema, Schema
 from taskgraph.util.scriptworker import (get_beetmover_bucket_scope,
                                          get_beetmover_action_scope)
 from taskgraph.transforms.task import task_description_schema
 from voluptuous import Any, Required, Optional
 
 import logging
+import re
+
 logger = logging.getLogger(__name__)
 
 
 _WINDOWS_BUILD_PLATFORMS = [
     'win64-nightly',
     'win32-nightly'
 ]
 
@@ -58,73 +60,67 @@ logger = logging.getLogger(__name__)
     "balrog_props.json",
 ]
 
 # Until bug 1331141 is fixed, if you are adding any new artifacts here that
 # need to be transfered to S3, please be aware you also need to follow-up
 # with a beetmover patch in https://github.com/mozilla-releng/beetmoverscript/.
 # See example in bug 1348286
 UPSTREAM_ARTIFACT_UNSIGNED_PATHS = {
-    'macosx64-nightly': _DESKTOP_UPSTREAM_ARTIFACTS_UNSIGNED_EN_US + [
-        "host/bin/mar",
-        "host/bin/mbsdiff",
+    r'^(linux(|64)|macosx64)-nightly$': _DESKTOP_UPSTREAM_ARTIFACTS_UNSIGNED_EN_US + [
+        'host/bin/mar',
+        'host/bin/mbsdiff',
     ],
-    'macosx64-nightly-l10n': _DESKTOP_UPSTREAM_ARTIFACTS_UNSIGNED_L10N,
-    'win64-nightly': _DESKTOP_UPSTREAM_ARTIFACTS_UNSIGNED_EN_US + [
+    r'^win(32|64)-nightly$': _DESKTOP_UPSTREAM_ARTIFACTS_UNSIGNED_EN_US + [
         "host/bin/mar.exe",
         "host/bin/mbsdiff.exe",
     ],
-    'win64-nightly-l10n': _DESKTOP_UPSTREAM_ARTIFACTS_UNSIGNED_L10N,
-    'win32-nightly': _DESKTOP_UPSTREAM_ARTIFACTS_UNSIGNED_EN_US + [
-        "host/bin/mar.exe",
-        "host/bin/mbsdiff.exe",
-    ],
-    'win32-nightly-l10n': _DESKTOP_UPSTREAM_ARTIFACTS_UNSIGNED_L10N,
+    r'^(linux(|64)|macosx64|win(32|64))-nightly-l10n$': _DESKTOP_UPSTREAM_ARTIFACTS_UNSIGNED_L10N,
 }
 
 # Until bug 1331141 is fixed, if you are adding any new artifacts here that
 # need to be transfered to S3, please be aware you also need to follow-up
 # with a beetmover patch in https://github.com/mozilla-releng/beetmoverscript/.
 # See example in bug 1348286
 UPSTREAM_ARTIFACT_SIGNED_PATHS = {
-    'win64-nightly': ['target.zip'],
-    'win64-nightly-l10n': ['target.zip'],
-    'win32-nightly': ['target.zip'],
-    'win32-nightly-l10n': ['target.zip'],
+    r'^linux(|64)-nightly(|-l10n)$': ['target.tar.bz2', 'target.tar.bz2.asc'],
+    r'^win(32|64)-nightly(|-l10n)$': ['target.zip'],
 }
 
 # Until bug 1331141 is fixed, if you are adding any new artifacts here that
 # need to be transfered to S3, please be aware you also need to follow-up
 # with a beetmover patch in https://github.com/mozilla-releng/beetmoverscript/.
 # See example in bug 1348286
 UPSTREAM_ARTIFACT_REPACKAGE_PATHS = {
-    'macosx64-nightly': ['target.dmg'],
-    'macosx64-nightly-l10n': ['target.dmg'],
+    r'^macosx64-nightly(|-l10n)$': ['target.dmg'],
 }
 # Until bug 1331141 is fixed, if you are adding any new artifacts here that
 # need to be transfered to S3, please be aware you also need to follow-up
 # with a beetmover patch in https://github.com/mozilla-releng/beetmoverscript/.
 # See example in bug 1348286
 UPSTREAM_ARTIFACT_SIGNED_REPACKAGE_PATHS = {
-    'macosx64-nightly': ['target.complete.mar'],
-    'macosx64-nightly-l10n': ['target.complete.mar'],
-    'win64-nightly': ['target.complete.mar', 'target.installer.exe'],
-    'win64-nightly-l10n': ['target.complete.mar', 'target.installer.exe'],
-    'win32-nightly': [
-        'target.complete.mar',
-        'target.installer.exe',
-        'target.stub-installer.exe'
-    ],
-    'win32-nightly-l10n': [
+    r'^(linux(|64)|macosx64)-nightly(|-l10n)$': ['target.complete.mar'],
+    r'^win64-nightly(|-l10n)$': ['target.complete.mar', 'target.installer.exe'],
+    r'^win32-nightly(|-l10n)$': [
         'target.complete.mar',
         'target.installer.exe',
         'target.stub-installer.exe'
     ],
 }
 
+# Compile every regex once at import time
+for dict_ in (
+    UPSTREAM_ARTIFACT_UNSIGNED_PATHS, UPSTREAM_ARTIFACT_SIGNED_PATHS,
+    UPSTREAM_ARTIFACT_REPACKAGE_PATHS, UPSTREAM_ARTIFACT_SIGNED_REPACKAGE_PATHS,
+):
+    for uncompiled_regex, value in dict_.iteritems():
+        compiled_regex = re.compile(uncompiled_regex)
+        del dict_[uncompiled_regex]
+        dict_[compiled_regex] = value
+
 # Voluptuous uses marker objects as dictionary *keys*, but they are not
 # comparable, so we cast all of the keys back to regular strings
 task_description_schema = {str(k): v for k, v in task_description_schema.schema.iteritems()}
 
 transforms = TransformSequence()
 
 # shortcut for a string where task references are allowed
 taskref_or_string = Any(
@@ -258,28 +254,47 @@ def generate_upstream_artifacts(build_ta
     mapping = [
         build_mapping,
         build_signing_mapping,
         repackage_mapping,
         repackage_signing_mapping
     ]
 
     for ref, tasktype, mapping in zip(task_refs, tasktypes, mapping):
-        if platform in mapping:
-            upstream_artifacts.append({
-                "taskId": {"task-reference": ref},
-                "taskType": tasktype,
-                "paths": ["{}/{}".format(artifact_prefix, p)
-                          for p in mapping[platform]],
-                "locale": locale or "en-US",
-            })
+        plarform_was_previously_matched_by_regex = None
+        for platform_regex, paths in mapping.iteritems():
+            if platform_regex.match(platform) is not None:
+                _check_platform_matched_only_one_regex(
+                    tasktype, platform, plarform_was_previously_matched_by_regex, platform_regex
+                )
+
+                upstream_artifacts.append({
+                    "taskId": {"task-reference": ref},
+                    "taskType": tasktype,
+                    "paths": ["{}/{}".format(artifact_prefix, path) for path in paths],
+                    "locale": locale or "en-US",
+                })
+                plarform_was_previously_matched_by_regex = platform_regex
 
     return upstream_artifacts
 
 
+def _check_platform_matched_only_one_regex(
+    task_type, platform, plarform_was_previously_matched_by_regex, platform_regex
+):
+    if plarform_was_previously_matched_by_regex is not None:
+        raise Exception('In task type "{task_type}", platform "{platform}" matches at \
+least 2 regular expressions. First matched: "{first_matched}". Second matched: \
+"{second_matched}"'.format(
+            task_type=task_type, platform=platform,
+            first_matched=plarform_was_previously_matched_by_regex.pattern,
+            second_matched=platform_regex.pattern
+        ))
+
+
 def is_valid_beetmover_job(job):
     # windows builds don't have docker-image, so fewer dependencies
     if any(b in job['attributes']['build_platform'] for b in _WINDOWS_BUILD_PLATFORMS):
         expected_dep_count = 4
     else:
         expected_dep_count = 5
 
     return (len(job["dependencies"]) == expected_dep_count and
--- a/taskcluster/taskgraph/transforms/build_signing.py
+++ b/taskcluster/taskgraph/transforms/build_signing.py
@@ -3,16 +3,18 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 """
 Transform the signing task into an actual task description.
 """
 
 from __future__ import absolute_import, print_function, unicode_literals
 
 from taskgraph.transforms.base import TransformSequence
+from taskgraph.util.signed_artifacts import generate_specifications_of_artifacts_to_sign
+
 
 transforms = TransformSequence()
 
 
 @transforms.add
 def add_signed_routes(config, jobs):
     """Add routes corresponding to the routes of the build task
        this corresponds to, with .signed inserted, for all gecko.v2 routes"""
@@ -29,73 +31,34 @@ def add_signed_routes(config, jobs):
                 rest = ".".join(dep_route.split(".")[4:])
                 job['routes'].append(
                     'index.gecko.v2.{}.signed-nightly.{}'.format(branch, rest))
 
         yield job
 
 
 @transforms.add
-def make_signing_description(config, jobs):
+def define_upstream_artifacts(config, jobs):
     for job in jobs:
         dep_job = job['dependent-task']
+        build_platform = dep_job.attributes.get('build_platform')
 
-        job['upstream-artifacts'] = _generate_upstream_artifacts(
-            dep_job.attributes.get('build_platform'),
-            dep_job.attributes.get('nightly')
+        artifacts_specifications = generate_specifications_of_artifacts_to_sign(
+            build_platform,
+            dep_job.attributes.get('nightly'),
+            keep_locale_template=False
         )
+
+        if 'android' in build_platform:
+            # We're in the job that creates both multilocale and en-US APKs
+            artifacts_specifications[0]['artifacts'].append('public/build/en-US/target.apk')
+
+        job['upstream-artifacts'] = [{
+            'taskId': {'task-reference': '<build>'},
+            'taskType': 'build',
+            'paths': spec['artifacts'],
+            'formats': spec['formats'],
+        } for spec in artifacts_specifications]
+
         label = dep_job.label.replace("build-", "signing-")
         job['label'] = label
 
         yield job
-
-
-def _generate_upstream_artifacts(build_platform, is_nightly=False):
-    if 'android' in build_platform:
-        artifacts_specificities = [{
-            'artifacts': [
-                'public/build/target.apk',
-                'public/build/en-US/target.apk'
-            ],
-            'format': 'jar',
-        }]
-    # XXX: Mac and Windows don't sign mars because internal aren't signed at
-    # this stage of the release
-    elif 'macosx' in build_platform:
-        artifacts_specificities = [{
-            'artifacts': ['public/build/target.dmg'],
-            'format': 'macapp',
-        }]
-    elif 'win64' in build_platform:
-        artifacts_specificities = [{
-            'artifacts': [
-                'public/build/target.zip',
-                'public/build/setup.exe'
-            ],
-            'format': 'sha2signcode',
-        }]
-    elif 'win32' in build_platform:
-        artifacts_specificities = [{
-            'artifacts': [
-                'public/build/target.zip',
-                'public/build/setup.exe',
-                ],
-            'format': 'sha2signcode',
-        }]
-        if is_nightly:
-            artifacts_specificities[0]['artifacts'] += ['public/build/setup-stub.exe']
-    elif 'linux' in build_platform:
-        artifacts_specificities = [{
-            'artifacts': ['public/build/target.tar.bz2'],
-            'format': 'gpg',
-        }, {
-            'artifacts': ['public/build/update/target.complete.mar'],
-            'format': 'mar_sha384',
-        }]
-    else:
-        raise Exception("Platform not implemented for signing")
-
-    return [{
-        'taskId': {'task-reference': '<build>'},
-        'taskType': 'build',
-        'paths': specificity['artifacts'],
-        'formats': [specificity['format']],
-    } for specificity in artifacts_specificities]
--- a/taskcluster/taskgraph/transforms/gecko_v2_whitelist.py
+++ b/taskcluster/taskgraph/transforms/gecko_v2_whitelist.py
@@ -22,30 +22,38 @@ JOB_NAME_WHITELIST = set([
     'android-api-15-gradle-opt',
     'android-api-15-opt',
     'android-api-15-old-id-opt',
     'android-x86-opt',
     'android-x86-old-id-opt',
     'browser-haz-debug',
     'linux-debug',
     'linux-devedition',
+    'linux-devedition-nightly-repackage',
+    'linux-devedition-nightly-repackage-signing',
+    'linux-nightly-repackage',
+    'linux-nightly-repackage-signing',
     'linux-opt',
     'linux-pgo',
     'linux64-add-on-devel',
     'linux64-artifact-opt',
     'linux64-asan-debug',
     'linux64-asan-opt',
     'linux64-base-toolchains-debug',
     'linux64-base-toolchains-opt',
     'linux64-fuzzing-asan-opt',
     'linux64-ccov-opt',
     'linux64-clang-tidy',
     'linux64-debug',
     'linux64-devedition',
+    'linux64-devedition-nightly-repackage',
+    'linux64-devedition-nightly-repackage-signing',
     'linux64-jsdcov-opt',
+    'linux64-nightly-repackage',
+    'linux64-nightly-repackage-signing',
     'linux64-noopt-debug',
     'linux64-opt',
     'linux64-pgo',
     'linux64-st-an-debug',
     'linux64-st-an-opt',
     'linux64-stylo-debug',
     'linux64-stylo-opt',
     'linux64-valgrind-opt',
--- a/taskcluster/taskgraph/transforms/nightly_l10n_signing.py
+++ b/taskcluster/taskgraph/transforms/nightly_l10n_signing.py
@@ -3,98 +3,64 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 """
 Transform the signing task into an actual task description.
 """
 
 from __future__ import absolute_import, print_function, unicode_literals
 
 from taskgraph.transforms.base import TransformSequence
+from taskgraph.util.signed_artifacts import generate_specifications_of_artifacts_to_sign
 from taskgraph.util.treeherder import join_symbol
 
 transforms = TransformSequence()
 
 
 @transforms.add
 def make_signing_description(config, jobs):
     for job in jobs:
         job['depname'] = 'unsigned-repack'
 
         dep_job = job['dependent-task']
-        dep_platform = dep_job.attributes.get('build_platform')
-
-        job['upstream-artifacts'] = []
-        if 'android' in dep_platform:
-            job_specs = [
-                {
-                    'artifacts': ['public/build/{locale}/target.apk'],
-                    'format': 'jar',
-                },
-            ]
-        elif 'macosx' in dep_platform:
-            job_specs = [
-                {
-                    'artifacts': ['public/build/{locale}/target.dmg'],
-                    'format': 'macapp',
-                }
-            ]
-        elif 'win32' in dep_platform:
-            job_specs = [
-                {
-                    'artifacts': [
-                        'public/build/{locale}/target.zip',
-                        'public/build/{locale}/setup.exe',
-                        'public/build/{locale}/setup-stub.exe'
-                    ],
-                    'format': 'sha2signcode',
-                }
-            ]
-        elif 'win64' in dep_platform:
-            job_specs = [
-                {
-                    'artifacts': [
-                        'public/build/{locale}/target.zip',
-                        'public/build/{locale}/setup.exe',
-                    ],
-                    'format': 'sha2signcode',
-                }
-            ]
-        elif 'linux' in dep_platform:
-            job_specs = [
-                {
-                    'artifacts': ['public/build/{locale}/target.tar.bz2'],
-                    'format': 'gpg',
-                }, {
-                    'artifacts': ['public/build/{locale}/target.complete.mar'],
-                    'format': 'mar_sha384',
-                }
-            ]
-        else:
-            raise Exception("Platform not implemented for signing")
-
-        upstream_artifacts = []
-        for spec in job_specs:
-            fmt = spec['format']
-            upstream_artifacts.append({
-                "taskId": {"task-reference": "<unsigned-repack>"},
-                "taskType": "l10n",
-                # Set paths based on artifacts in the specs (above) one per
-                # locale present in the chunk this is signing stuff for.
-                "paths": [f.format(locale=l)
-                          for l in dep_job.attributes.get('chunk_locales', [])
-                          for f in spec['artifacts']],
-                "formats": [fmt]
-            })
-
-        job['upstream-artifacts'] = upstream_artifacts
 
         label = dep_job.label.replace("nightly-l10n-", "signing-l10n-")
         job['label'] = label
 
         # add the chunk number to the TH symbol
         symbol = 'Ns{}'.format(dep_job.attributes.get('l10n_chunk'))
         group = 'tc-L10n'
 
         job['treeherder'] = {
             'symbol': join_symbol(group, symbol),
         }
 
         yield job
+
+
+@transforms.add
+def define_upstream_artifacts(config, jobs):
+    for job in jobs:
+        dep_job = job['dependent-task']
+
+        locale_specifications = generate_specifications_of_artifacts_to_sign(
+            dep_job.attributes.get('build_platform'),
+            is_nightly=True,
+            keep_locale_template=True
+        )
+
+        upstream_artifacts = []
+        for spec in locale_specifications:
+            upstream_artifacts.append({
+                'taskId': {'task-reference': '<unsigned-repack>'},
+                'taskType': 'l10n',
+                # Set paths based on artifacts in the specs (above) one per
+                # locale present in the chunk this is signing stuff for.
+                'paths': [
+                    path_template.format(locale=locale)
+                    for locale in dep_job.attributes.get('chunk_locales', [])
+                    for path_template in spec['artifacts']
+                ],
+                'formats': spec['formats']
+            })
+
+        job['upstream-artifacts'] = upstream_artifacts
+
+        yield job
--- a/taskcluster/taskgraph/transforms/repackage.py
+++ b/taskcluster/taskgraph/transforms/repackage.py
@@ -143,18 +143,25 @@ def make_job_description(config, jobs):
 
         if locale:
             # Make sure we specify the locale-specific upload dir
             worker['env'].update(LOCALE=locale)
 
         if build_platform.startswith('win'):
             worker_type = 'aws-provisioner-v1/gecko-%s-b-win2012' % level
             run['use-magic-mh-args'] = False
-        elif build_platform.startswith('macosx'):
-            worker_type = 'aws-provisioner-v1/gecko-%s-b-macosx64' % level
+        else:
+            if build_platform.startswith('macosx'):
+                worker_type = 'aws-provisioner-v1/gecko-%s-b-macosx64' % level
+            elif build_platform.startswith('linux'):
+                worker_type = 'aws-provisioner-v1/gecko-%s-b-linux' % level
+            else:
+                raise NotImplementedError(
+                    'Unsupported build_platform: "{}"'.format(build_platform)
+                )
 
             run['tooltool-downloads'] = 'internal'
             worker['docker-image'] = {"in-tree": "desktop-build"},
 
             cot = job.setdefault('extra', {}).setdefault('chainOfTrust', {})
             cot.setdefault('inputs', {})['docker-image'] = {"task-reference": "<docker-image>"}
 
         task = {
@@ -172,71 +179,81 @@ def make_job_description(config, jobs):
             'run': run,
         }
         yield task
 
 
 def _generate_task_mozharness_config(build_platform):
     if build_platform.startswith('macosx'):
         return ['repackage/osx_signed.py']
-    elif build_platform.startswith('win'):
-        return ['repackage/win32_signed.py'] if '32' in build_platform \
-            else ['repackage/win64_signed.py']
     else:
-        raise NotImplemented('Unsupported build_platform: "{}"'.format(build_platform))
+        bits = 32 if '32' in build_platform else 64
+        if build_platform.startswith('linux'):
+            return ['repackage/linux{}_signed.py'.format(bits)]
+        elif build_platform.startswith('win'):
+            return ['repackage/win{}_signed.py'.format(bits)]
+
+    raise NotImplementedError('Unsupported build_platform: "{}"'.format(build_platform))
 
 
 def _generate_task_env(build_platform, build_task_ref, signing_task_ref, locale=None):
     mar_prefix = _generate_taskcluster_prefix(build_task_ref, postfix='host/bin/', locale=None)
     signed_prefix = _generate_taskcluster_prefix(signing_task_ref, locale=locale)
 
-    if build_platform.startswith('macosx'):
+    if build_platform.startswith('linux') or build_platform.startswith('macosx'):
+        tarball_extension = 'bz2' if build_platform.startswith('linux') else 'gz'
         return {
-            'SIGNED_INPUT': {'task-reference': '{}target.tar.gz'.format(signed_prefix)},
+            'SIGNED_INPUT': {'task-reference': '{}target.tar.{}'.format(
+                signed_prefix, tarball_extension
+            )},
             'UNSIGNED_MAR': {'task-reference': '{}mar'.format(mar_prefix)},
         }
     elif build_platform.startswith('win'):
         task_env = {
             'SIGNED_ZIP': {'task-reference': '{}target.zip'.format(signed_prefix)},
             'SIGNED_SETUP': {'task-reference': '{}setup.exe'.format(signed_prefix)},
             'UNSIGNED_MAR': {'task-reference': '{}mar.exe'.format(mar_prefix)},
         }
 
         # Stub installer is only generated on win32
         if '32' in build_platform:
             task_env['SIGNED_SETUP_STUB'] = {
                 'task-reference': '{}setup-stub.exe'.format(signed_prefix),
             }
         return task_env
 
-    else:
-        raise NotImplemented('Unsupported build_platform: "{}"'.format(build_platform))
+    raise NotImplementedError('Unsupported build_platform: "{}"'.format(build_platform))
 
 
 def _generate_taskcluster_prefix(task_id, postfix='', locale=None):
     if locale:
         postfix = '{}/{}'.format(locale, postfix)
 
     return _TC_ARTIFACT_LOCATION.format(task_id=task_id, postfix=postfix)
 
 
 def _generate_task_output_files(build_platform, locale=None):
     locale_output_path = '{}/'.format(locale) if locale else ''
-    if build_platform.startswith('macosx'):
-        return [{
-            'type': 'file',
-            'path': '/home/worker/workspace/build/artifacts/{}target.dmg'
-                    .format(locale_output_path),
-            'name': 'public/build/{}target.dmg'.format(locale_output_path),
-        }, {
+
+    if build_platform.startswith('linux') or build_platform.startswith('macosx'):
+        output_files = [{
             'type': 'file',
             'path': '/home/worker/workspace/build/artifacts/{}target.complete.mar'
                     .format(locale_output_path),
             'name': 'public/build/{}target.complete.mar'.format(locale_output_path),
         }]
+
+        if build_platform.startswith('macosx'):
+            output_files.append({
+                'type': 'file',
+                'path': '/home/worker/workspace/build/artifacts/{}target.dmg'
+                        .format(locale_output_path),
+                'name': 'public/build/{}target.dmg'.format(locale_output_path),
+            })
+
     elif build_platform.startswith('win'):
         output_files = [{
             'type': 'file',
             'path': 'public/build/{}target.installer.exe'.format(locale_output_path),
             'name': 'public/build/{}target.installer.exe'.format(locale_output_path),
         }, {
             'type': 'file',
             'path': 'public/build/{}target.complete.mar'.format(locale_output_path),
@@ -246,11 +263,12 @@ def _generate_task_output_files(build_pl
         # Stub installer is only generated on win32
         if '32' in build_platform:
             output_files.append({
                 'type': 'file',
                 'path': 'public/build/{}target.stub-installer.exe'.format(locale_output_path),
                 'name': 'public/build/{}target.stub-installer.exe'.format(locale_output_path),
             })
 
+    if output_files:
         return output_files
-    else:
-        raise NotImplemented('Unsupported build_platform: "{}"'.format(build_platform))
+
+    raise NotImplementedError('Unsupported build_platform: "{}"'.format(build_platform))
--- a/taskcluster/taskgraph/transforms/repackage_signing.py
+++ b/taskcluster/taskgraph/transforms/repackage_signing.py
@@ -116,16 +116,18 @@ def make_repackage_signing_description(c
             'scopes': scopes,
             'dependencies': dependencies,
             'attributes': attributes,
             'run-on-projects': dep_job.attributes.get('run_on_projects'),
             'treeherder': treeherder,
         }
 
         funsize_platforms = [
+            'linux-nightly',
+            'linux64-nightly',
             'macosx64-nightly',
             'win32-nightly',
             'win64-nightly'
         ]
         if build_platform in funsize_platforms and is_nightly:
             route_template = "project.releng.funsize.level-{level}.{project}"
             task['routes'] = [
                 route_template.format(project=config.params['project'],
--- a/taskcluster/taskgraph/transforms/signing.py
+++ b/taskcluster/taskgraph/transforms/signing.py
@@ -123,21 +123,16 @@ def make_task_description(config, jobs):
             'scopes': [signing_cert_scope] + signing_format_scopes,
             'dependencies': {job['depname']: dep_job.label},
             'attributes': attributes,
             'run-on-projects': dep_job.attributes.get('run_on_projects'),
             'treeherder': treeherder,
             'routes': job.get('routes', []),
         }
 
-        if 'linux' in dep_job.attributes.get('build_platform') and \
-                dep_job.attributes.get('nightly'):
-            task['routes'].append("project.releng.funsize.level-{level}.{project}".format(
-                project=config.params['project'], level=config.params['level']))
-
         yield task
 
 
 def _generate_treeherder_platform(dep_th_platform, build_platform, build_type):
     actual_build_type = 'pgo' if '-pgo' in build_platform else build_type
     return '{}/{}'.format(dep_th_platform, actual_build_type)
 
 
--- a/testing/mozharness/configs/repackage/win32_signed.py
+++ b/testing/mozharness/configs/repackage/win32_signed.py
@@ -27,17 +27,16 @@ repackage_config = [[
         "--tag", "{abs_mozilla_dir}\\browser\\installer\\windows\\stub.tag",
          "--setupexe", "{abs_work_dir}\\inputs\\setup-stub.exe",
          "-o", "{output_home}\\target.stub-installer.exe"
     ]]
 
 config = {
     "input_home": "{abs_work_dir}\\inputs",
     "output_home": "{base_work_dir}\\public\\build{locale}",
-    "src_mozconfig": "browser/config/mozconfigs/{}/repack".format(platform),
 
     "locale": os.environ.get("LOCALE"),
 
     "download_config": download_config,
 
     "repackage_config": repackage_config,
 
     # ToolTool
--- a/testing/mozharness/configs/repackage/win64_signed.py
+++ b/testing/mozharness/configs/repackage/win64_signed.py
@@ -20,17 +20,16 @@ repackage_config = [[
         "-i", "{abs_work_dir}\\inputs\\target.zip",
         "--mar", "{abs_work_dir}\\inputs\\mar.exe",
         "-o", "{output_home}\\target.complete.mar"
     ]]
 
 config = {
     "input_home": "{abs_work_dir}\\inputs",
     "output_home": "{base_work_dir}\\public\\build{locale}",
-    "src_mozconfig": "browser/config/mozconfigs/{}/repack".format(platform),
 
     "locale": os.environ.get("LOCALE"),
 
     "download_config": download_config,
 
     "repackage_config": repackage_config,
 
     # ToolTool