backed out Bug 1277595, revs d5d26aa0f369, 42ab74605817, c1aa2a15b4eb, 32a569f4df06, dee2532bdc95, 5809a56922ed CLOSED TREE
authorJordan Lund <jlund@mozilla.com>
Thu, 01 Sep 2016 09:56:54 -0700
changeset 312305 e7dd86addfd5606de5e6236f4241e8942c14d048
parent 312304 9beac1f92bd0b559e46039061a3ce9a09350ce96
child 312306 a05befbd1d5c1a09b70fca4cac5ce20692bd7c2d
push id20443
push userkwierso@gmail.com
push dateFri, 02 Sep 2016 00:55:23 +0000
treeherderfx-team@4f8bafdd88dc [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1277595
milestone51.0a1
backed out Bug 1277595, revs d5d26aa0f369, 42ab74605817, c1aa2a15b4eb, 32a569f4df06, dee2532bdc95, 5809a56922ed CLOSED TREE * backed out Bug 1277595 - rev: d5d26aa0f369 * backed out Bug 1277595 - rev: 42ab74605817 * backed out Bug 1277595 - rev: c1aa2a15b4eb * backed out Bug 1277595 - rev: 32a569f4df06 * backed out Bug 1277595 - rev: dee2532bdc95 * backed out Bug 1277595 - rev: 5809a56922ed
taskcluster/ci/nightly-fennec/android-api-15-nightly-build.yml
taskcluster/ci/nightly-fennec/build.yml
taskcluster/ci/nightly-fennec/docker_build.yml
taskcluster/ci/nightly-fennec/kind.yml
taskcluster/ci/nightly-fennec/mobile_base.yml
taskcluster/ci/nightly-fennec/routes.json
taskcluster/ci/signing/kind.yml
taskcluster/ci/signing/signing.yml
taskcluster/mach_commands.py
taskcluster/taskgraph/decision.py
taskcluster/taskgraph/target_tasks.py
taskcluster/taskgraph/task/nightly_fennec.py
taskcluster/taskgraph/task/signing.py
testing/mozharness/configs/taskcluster_nightly.py
testing/mozharness/mozharness/mozilla/building/buildbase.py
testing/mozharness/mozharness/mozilla/updates/balrog.py
deleted file mode 100644
--- a/taskcluster/ci/nightly-fennec/android-api-15-nightly-build.yml
+++ /dev/null
@@ -1,66 +0,0 @@
-$inherits:
-  from: 'mobile_base.yml'
-  variables:
-    build_name: 'android'
-    build_type: 'opt'
-task:
-  metadata:
-      name: '[TC] Android armv7 API 15+'
-      description: 'Android armv7 API 15+'
-
-  workerType: android-api-15
-
-  routes:
-    - 'index.buildbot.branches.{{project}}.android-api-15'
-    - 'index.buildbot.revisions.{{head_rev}}.{{project}}.android-api-15'
-
-  scopes:
-    - 'docker-worker:cache:level-{{level}}-{{project}}-build-android-api-15-workspace'
-    - 'docker-worker:cache:tooltool-cache'
-    - 'docker-worker:relengapi-proxy:tooltool.download.internal'
-    - 'docker-worker:relengapi-proxy:tooltool.download.public'
-
-  payload:
-    cache:
-      level-{{level}}-{{project}}-build-android-api-15-workspace: '/home/worker/workspace'
-      tooltool-cache: '/home/worker/tooltool-cache'
-
-    features:
-      relengAPIProxy: true
-
-    env:
-      # inputs to mozharness
-      MOZHARNESS_SCRIPT: 'mozharness/scripts/fx_desktop_build.py'
-      # TODO: make these additional configuration files go away
-      MOZHARNESS_CONFIG: >
-          builds/releng_base_android_64_builds.py
-          disable_signing.py
-          platform_supports_post_upload_to_latest.py
-          taskcluster_nightly.py
-      MOZHARNESS_ACTIONS: "get-secrets build multi-l10n update"
-      MH_CUSTOM_BUILD_VARIANT_CFG: api-15
-      MH_BRANCH: {{project}}
-      MH_BUILD_POOL: taskcluster
-      TOOLTOOL_CACHE: '/home/worker/tooltool-cache'
-
-    command: ["/bin/bash", "bin/build.sh"]
-
-  extra:
-    treeherderEnv:
-      - production
-      - staging
-    treeherder:
-      machine:
-        # see https://github.com/mozilla/treeherder/blob/master/ui/js/values.js
-        platform: android-4-0-armv7-api15
-      groupSymbol: tc
-      groupName: Submitted by taskcluster
-      symbol: B
-      tier: 2
-    # Rather then enforcing particular conventions we require that all build
-    # tasks provide the "build" extra field to specify where the build and tests
-    # files are located.
-    locations:
-      build: 'public/build/target.apk'
-      mozharness: 'public/build/mozharness.zip'
-      test_packages: 'public/build/target.test_packages.json'
deleted file mode 100644
--- a/taskcluster/ci/nightly-fennec/build.yml
+++ /dev/null
@@ -1,46 +0,0 @@
-# This is the "base" task which contains the common values all builds must
-# provide.
----
-taskId: {{build_slugid}}
-
-task:
-  created:
-    relative-datestamp: "0 seconds"
-  deadline:
-    relative-datestamp: "24 hours"
-  metadata:
-    source: '{{source}}'
-    owner: mozilla-taskcluster-maintenance@mozilla.com
-
-  tags:
-    createdForUser: {{owner}}
-
-  provisionerId: aws-provisioner-v1
-  schedulerId: task-graph-scheduler
-
-  payload:
-    # Two hours is long but covers edge cases (and matches bb based infra)
-    maxRunTime: 7200
-
-    env:
-      # Common environment variables for checking out gecko
-      GECKO_BASE_REPOSITORY: '{{base_repository}}'
-      GECKO_HEAD_REPOSITORY: '{{head_repository}}'
-      GECKO_HEAD_REV: '{{head_rev}}'
-      GECKO_HEAD_REF: '{{head_ref}}'
-      TOOLTOOL_REPO: 'https://github.com/mozilla/build-tooltool'
-      TOOLTOOL_REV: 'master'
-      MOZ_BUILD_DATE: '{{pushdate}}'
-      MOZ_SCM_LEVEL: '{{level}}'
-
-  extra:
-    build_product: '{{build_product}}'
-    build_name: '{{build_name}}'
-    build_type: '{{build_type}}'
-    index:
-      rank: {{rank}}
-    treeherder:
-      jobKind: build
-      groupSymbol: tc
-      groupName: Submitted by taskcluster
-      symbol: B
deleted file mode 100644
--- a/taskcluster/ci/nightly-fennec/docker_build.yml
+++ /dev/null
@@ -1,27 +0,0 @@
-$inherits:
-  from: 'build.yml'
-
-
-task:
-  workerType: b2gbuild
-
-  routes:
-    - 'index.gecko.v1.{{project}}.revision.linux.{{head_rev}}.{{build_name}}.{{build_type}}'
-    - 'index.gecko.v1.{{project}}.latest.linux.{{build_name}}.{{build_type}}'
-
-  scopes:
-    # docker build tasks use tc-vcs so include the scope.
-    - 'docker-worker:cache:level-{{level}}-{{project}}-tc-vcs'
-
-  payload:
-
-    cache:
-      level-{{level}}-{{project}}-tc-vcs: '/home/worker/.tc-vcs'
-
-    # All docker builds share a common artifact directory for ease of uploading.
-    artifacts:
-      'public/build':
-        type: directory
-        path: '/home/worker/artifacts/'
-        expires:
-          relative-datestamp: '1 year'
deleted file mode 100644
--- a/taskcluster/ci/nightly-fennec/kind.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-# 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/.
-
-implementation: 'taskgraph.task.nightly_fennec:NightlyFennecTask'
-nightly_fennec_path: '.'
-
deleted file mode 100644
--- a/taskcluster/ci/nightly-fennec/mobile_base.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-$inherits:
-  from: 'docker_build.yml'
-  variables:
-    build_product: 'mobile'
-docker-image: desktop-build
-task:
-  payload:
-    image:
-      type: 'task-image'
-      path: 'public/image.tar'
-      taskId:
-        task-reference: "<docker-image>"
-
deleted file mode 100644
--- a/taskcluster/ci/nightly-fennec/routes.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
-    "routes": [
-        "{index}.gecko.v2.{project}.revision.{head_rev}.{build_product}.{build_name}-{build_type}",
-        "{index}.gecko.v2.{project}.pushdate.{year}.{month}.{day}.{pushdate}.{build_product}.{build_name}-{build_type}",
-        "{index}.gecko.v2.{project}.latest.{build_product}.{build_name}-{build_type}"
-    ],
-    "nightly": [
-        "{index}.gecko.v2.{project}.nightly.{year}.{month}.{day}.revision.{head_rev}.{build_product}.{build_name}-{build_type}",
-        "{index}.gecko.v2.{project}.nightly.{year}.{month}.{day}.latest.{build_product}.{build_name}-{build_type}",
-        "{index}.gecko.v2.{project}.nightly.revision.{head_rev}.{build_product}.{build_name}-{build_type}",
-        "{index}.gecko.v2.{project}.nightly.latest.{build_product}.{build_name}-{build_type}"
-    ],
-    "l10n": [
-        "{index}.gecko.v2.{project}.revision.{head_rev}.{build_product}-l10n.{build_name}-{build_type}.{locale}",
-        "{index}.gecko.v2.{project}.pushdate.{year}.{month}.{day}.{pushdate}.{build_product}-l10n.{build_name}-{build_type}.{locale}",
-        "{index}.gecko.v2.{project}.latest.{build_product}-l10n.{build_name}-{build_type}.{locale}"
-    ]
-}
deleted file mode 100644
--- a/taskcluster/ci/signing/kind.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-# 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/.
-
-implementation: 'taskgraph.task.signing:SigningTask'
-signing_path: '.'
-kind-dependencies:
-  - nightly-fennec
deleted file mode 100644
--- a/taskcluster/ci/signing/signing.yml
+++ /dev/null
@@ -1,18 +0,0 @@
-task:
-  provisionerId: "scriptworker-prov-v1"
-  workerType: "signing-linux-v1"
-  scopes:
-    - "project:releng:signing:cert:dep-signing"
-    - "project:releng:signing:format:jar"
-  created:
-    relative-datestamp: "0 seconds"
-  deadline:
-    relative-datestamp: "24 hours"
-  payload:
-    unsignedArtifacts: []
-    maxRunTime: 600
-  metadata:
-    name: "Signing Scriptworker Task"
-    description: "Testing the signing scriptworker"
-    owner: "amiyaguchi@mozilla.com"
-    source: "https://tools.taskcluster.net/task-creator/"
--- a/taskcluster/mach_commands.py
+++ b/taskcluster/mach_commands.py
@@ -139,22 +139,16 @@ class MachCommands(MachCommandBase):
                      type=int,
                      default=0)
     @CommandArgument('--owner',
                      required=True,
                      help='email address of who owns this graph')
     @CommandArgument('--level',
                      required=True,
                      help='SCM level of this repository')
-    @CommandArgument('--triggered-by',
-                     choices=['nightly', 'push'],
-                     default='push',
-                     help='Source of execution of the decision graph')
-    @CommandArgument('--target-tasks-method',
-                     help='method for selecting the target tasks to generate')
     def taskgraph_decision(self, **options):
         """Run the decision task: generate a task graph and submit to
         TaskCluster.  This is only meant to be called within decision tasks,
         and requires a great many arguments.  Commands like `mach taskgraph
         optimized` are better suited to use on the command line, and can take
         the parameters file generated by a decision task.  """
 
         import taskgraph.decision
--- a/taskcluster/taskgraph/decision.py
+++ b/taskcluster/taskgraph/decision.py
@@ -105,33 +105,28 @@ def get_decision_parameters(options):
         'head_rev',
         'head_ref',
         'message',
         'project',
         'pushlog_id',
         'pushdate',
         'owner',
         'level',
-        'triggered_by',
         'target_tasks_method',
     ] if n in options}
 
     project = parameters['project']
     try:
         parameters.update(PER_PROJECT_PARAMETERS[project])
     except KeyError:
         logger.warning("using default project parameters; add {} to "
                        "PER_PROJECT_PARAMETERS in {} to customize behavior "
                        "for this project".format(project, __file__))
         parameters.update(PER_PROJECT_PARAMETERS['default'])
 
-    # `target_tasks_method` has higher precedence than `project` parameters
-    if 'target_tasks_method' in options:
-        parameters['target_tasks_method'] = options['target_tasks_method']
-
     return Parameters(parameters)
 
 
 def write_artifact(filename, data):
     logger.info('writing artifact file `{}`'.format(filename))
     if not os.path.isdir(ARTIFACTS_DIR):
         os.mkdir(ARTIFACTS_DIR)
     path = os.path.join(ARTIFACTS_DIR, filename)
--- a/taskcluster/taskgraph/target_tasks.py
+++ b/taskcluster/taskgraph/target_tasks.py
@@ -79,18 +79,8 @@ def target_tasks_ash_tasks(full_task_gra
             'linux64-asan',
             'linux64-pgo',
         ])):
             return False
         if not attrmatch(attrs, e10s=True):
             return False
         return True
     return [l for l, t in full_task_graph.tasks.iteritems() if filter(t)]
-
-
-@_target_task('nightly_fennec')
-def target_tasks_nightly(full_task_graph, parameters):
-    """Select the set of tasks required for a nightly build of fennec. The
-    nightly build process involves a pipeline of builds, signing,
-    and, eventually, uploading the tasks to balrog."""
-    return [t.label for t in full_task_graph.tasks.itervalues()
-            if t.attributes.get('kind') in ['nightly-fennec', 'signing']]
-
deleted file mode 100644
--- a/taskcluster/taskgraph/task/nightly_fennec.py
+++ /dev/null
@@ -1,113 +0,0 @@
-# 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/.
-
-from __future__ import absolute_import, print_function, unicode_literals
-
-import logging
-import json
-import os
-import time
-
-from . import base
-from .legacy import query_vcs_info, decorate_task_json_routes, gaia_info, \
-    mklabel
-from taskgraph.util.templates import Templates
-from taskgraph.util.docker import docker_image
-
-
-logger = logging.getLogger(__name__)
-GECKO = os.path.realpath(os.path.join(__file__, '..', '..', '..', '..'))
-ARTIFACT_URL = 'https://queue.taskcluster.net/v1/task/{}/artifacts/{}'
-INDEX_URL = 'https://index.taskcluster.net/v1/task/{}'
-
-class NightlyFennecTask(base.Task):
-
-    def __init__(self, *args, **kwargs):
-        self.task_dict = kwargs.pop('task_dict')
-        super(NightlyFennecTask, self).__init__(*args, **kwargs)
-
-    @classmethod
-    def load_tasks(cls, kind, path, config, params, loaded_tasks):
-        root = os.path.abspath(os.path.join(path, config[
-            'nightly_fennec_path']))
-
-        project = params['project']
-
-        # Set up the parameters, including the time of the build
-        push_epoch = int(time.time())
-        vcs_info = query_vcs_info(params['head_repository'], params['head_rev'])
-        changed_files = set()
-        if vcs_info:
-            push_epoch = vcs_info.pushdate
-
-            logger.debug(
-                '{} commits influencing task scheduling:'.format(len(vcs_info.changesets)))
-            for c in vcs_info.changesets:
-                logger.debug("{cset} {desc}".format(
-                    cset=c['node'][0:12],
-                    desc=c['desc'].splitlines()[0].encode('ascii', 'ignore')))
-                changed_files |= set(c['files'])
-
-        pushdate = time.strftime('%Y%m%d%H%M%S', time.gmtime(push_epoch))
-
-        # Template parameters used when expanding the graph
-        parameters = dict(gaia_info().items() + {
-            'index': 'index',
-            'project': project,
-            'pushlog_id': params.get('pushlog_id', 0),
-            'base_repository': params['base_repository'] or
-                params['head_repository'],
-            'docker_image': docker_image,
-            'head_repository': params['head_repository'],
-            'head_ref': params['head_ref'] or params['head_rev'],
-            'head_rev': params['head_rev'],
-            'pushdate': pushdate,
-            'pushtime': pushdate[8:],
-            'year': pushdate[0:4],
-            'month': pushdate[4:6],
-            'day': pushdate[6:8],
-            'rank': push_epoch,
-            'owner': params['owner'],
-            'level': params['level'],
-            'build_slugid': mklabel(),
-            'source': '{repo}file/{rev}/taskcluster/ci/nightly-fennec'.format(
-                repo=params['head_repository'], rev=params['head_rev']),
-            'build_name': 'android',
-            'build_type': 'opt',
-            'build_product': 'mobile'
-        }.items())
-
-        routes_file = os.path.join(root, 'routes.json')
-        with open(routes_file) as f:
-            contents = json.load(f)
-            json_routes = contents['routes']
-
-        tasks = []
-        templates = Templates(root)
-
-        task = templates.load('android-api-15-nightly-build.yml', parameters)
-        decorate_task_json_routes(task['task'], json_routes, parameters)
-
-        attributes = {'kind': 'nightly-fennec'}
-        tasks.append(cls(kind, 'build-nightly-fennec',
-                     task=task['task'], attributes=attributes,
-                         task_dict=task))
-
-        # Convert to a dictionary of tasks.  The process above has invented a
-        # taskId for each task, and we use those as the *labels* for the tasks;
-        # taskgraph will later assign them new taskIds.
-        return tasks
-
-    def get_dependencies(self, taskgraph):
-        deps = [(label, label) for label in self.task_dict.get('requires', [])]
-
-        # add a dependency on an image task, if needed
-        if 'docker-image' in self.task_dict:
-            deps.append(('build-docker-image-{docker-image}'.format(**self.task_dict),
-                         'docker-image'))
-
-        return deps
-
-    def optimize(self):
-        return False, None
deleted file mode 100644
--- a/taskcluster/taskgraph/task/signing.py
+++ /dev/null
@@ -1,57 +0,0 @@
-# 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/.
-
-from __future__ import absolute_import, print_function, unicode_literals
-
-import logging
-import json
-import os
-import time
-
-from . import base
-from taskgraph.util.templates import Templates
-
-
-logger = logging.getLogger(__name__)
-GECKO = os.path.realpath(os.path.join(__file__, '..', '..', '..', '..'))
-ARTIFACT_URL = 'https://queue.taskcluster.net/v1/task/{}/artifacts/{}'
-INDEX_URL = 'https://index.taskcluster.net/v1/task/{}'
-
-class SigningTask(base.Task):
-
-    def __init__(self, *args, **kwargs):
-        super(SigningTask, self).__init__(*args, **kwargs)
-
-    @classmethod
-    def load_tasks(cls, kind, path, config, params, loaded_tasks):
-        root = os.path.abspath(os.path.join(path, config['signing_path']))
-
-        # get each nightly-fennec and add its name to this task
-        fennec_tasks = [t for t in loaded_tasks if t.attributes.get('kind')
-                        == 'nightly-fennec']
-
-        tasks = []
-        for fennec_task in fennec_tasks:
-            templates = Templates(root)
-            task = templates.load('signing.yml', {})
-
-            artifacts = ['public/build/target.apk',
-                         'public/build/en-US/target.apk']
-            for artifact in artifacts:
-                url = ARTIFACT_URL.format('<build-nightly-fennec>', artifact)
-                task['task']['payload']['unsignedArtifacts'].append({
-                    'task-reference': url
-                })
-
-            attributes = {'kind': 'signing'}
-            tasks.append(cls(kind, 'signing-nightly-fennec', task=task['task'],
-                             attributes=attributes))
-
-        return tasks
-
-    def get_dependencies(self, taskgraph):
-        return [('build-nightly-fennec', 'build-nightly-fennec')]
-
-    def optimize(self):
-        return False, None
deleted file mode 100644
--- a/testing/mozharness/configs/taskcluster_nightly.py
+++ /dev/null
@@ -1,5 +0,0 @@
-config = {
-    'nightly_build': True,
-    'taskcluster_nightly': True,
-}
-
--- a/testing/mozharness/mozharness/mozilla/building/buildbase.py
+++ b/testing/mozharness/mozharness/mozilla/building/buildbase.py
@@ -913,24 +913,16 @@ or run without that action (ie: --no-{ac
                     'stage_ssh_key': c['stage_ssh_key']
                 }
 
         if self.query_is_nightly():
             mach_env['LATEST_MAR_DIR'] = c['latest_mar_dir'] % {
                 'branch': self.branch
             }
 
-        # this prevents taskcluster from overwriting the target files with
-        # the multilocale files. Put everything from the en-US build in a
-        # separate folder.
-        if multiLocale and self.config.get('taskcluster_nightly'):
-            if 'UPLOAD_PATH' in mach_env:
-                mach_env['UPLOAD_PATH'] = os.path.join(mach_env['UPLOAD_PATH'],
-                                                       'en-US')
-
         # _query_post_upload_cmd returns a list (a cmd list), for env sake here
         # let's make it a string
         if c.get('is_automation'):
             pst_up_cmd = ' '.join([str(i) for i in self._query_post_upload_cmd(multiLocale)])
             mach_env['POST_UPLOAD_CMD'] = pst_up_cmd
 
         return mach_env
 
@@ -1638,44 +1630,27 @@ or run without that action (ie: --no-{ac
         if not self.query_is_nightly():
             self.info("Not a nightly build, skipping multi l10n.")
             return
         self._initialize_taskcluster()
 
         dirs = self.query_abs_dirs()
         base_work_dir = dirs['base_work_dir']
         objdir = dirs['abs_obj_dir']
-        branch = self.branch
-
-        # Building a nightly with the try repository fails because a
-        # config-file does not exist for try. Default to mozilla-central
-        # settings (arbitrarily).
-        if branch == 'try':
-            branch = 'mozilla-central'
+        branch = self.buildbot_config['properties']['branch']
 
         # Some android versions share the same .json config - if
         # multi_locale_config_platform is set, use that the .json name;
         # otherwise, use the buildbot platform.
-        default_platform = self.buildbot_config['properties'].get('platform',
-                                                                  'android')
-
         multi_config_pf = self.config.get('multi_locale_config_platform',
-                                          default_platform)
-
-        # The l10n script location differs on buildbot and taskcluster
-        if self.config.get('taskcluster_nightly'):
-            multil10n_path = \
-                'build/src/testing/mozharness/scripts/multil10n.py'
-            base_work_dir = os.path.join(base_work_dir, 'workspace')
-        else:
-            multil10n_path = '%s/scripts/scripts/multil10n.py' % base_work_dir,
+                                          self.buildbot_config['properties']['platform'])
 
         cmd = [
             self.query_exe('python'),
-            multil10n_path,
+            '%s/scripts/scripts/multil10n.py' % base_work_dir,
             '--config-file',
             'multi_locale/%s_%s.json' % (branch, multi_config_pf),
             '--config-file',
             'multi_locale/android-mozharness-build.json',
             '--merge-locales',
             '--pull-locale-source',
             '--add-locales',
             '--package-multi',
@@ -2035,25 +2010,16 @@ or run without that action (ie: --no-{ac
         """ submit balrog update steps. """
         if not self.query_is_nightly():
             self.info("Not a nightly build, skipping balrog submission.")
             return
 
         # grab any props available from this or previous unclobbered runs
         self.generate_build_props(console_output=False,
                                   halt_on_failure=False)
-
-        # generate balrog props as artifacts
-        if self.config.get('taskcluster_nightly'):
-            env = self.query_mach_build_env(multiLocale=False)
-            props_path = os.path.join(env["UPLOAD_PATH"],
-                    'balrog_props.json')
-            self.generate_balrog_props(props_path)
-            return
-
         if not self.config.get("balrog_servers"):
             self.fatal("balrog_servers not set; skipping balrog submission.")
             return
 
         if self.submit_balrog_updates():
             # set the build to orange so it is at least caught
             self.return_code = self.worst_level(
                 EXIT_STATUS_DICT[TBPL_WARNING], self.return_code,
--- a/testing/mozharness/mozharness/mozilla/updates/balrog.py
+++ b/testing/mozharness/mozharness/mozilla/updates/balrog.py
@@ -9,37 +9,16 @@ class BalrogMixin(object):
     @staticmethod
     def _query_balrog_username(server_config, product=None):
         username = server_config["balrog_usernames"].get(product)
         if username:
             return username
         else:
             raise KeyError("Couldn't find balrog username.")
 
-    def generate_balrog_props(self, props_path):
-        self.set_buildbot_property(
-            "hashType", self.config.get("hash_type", "sha512"), write_to_file=True
-        )
-
-        if self.buildbot_config and "properties" in self.buildbot_config:
-            buildbot_properties = self.buildbot_config["properties"].items()
-        else:
-            buildbot_properties = []
-
-        balrog_props = dict(properties=dict(chain(
-            buildbot_properties,
-            self.buildbot_properties.items(),
-        )))
-        if self.config.get('balrog_platform'):
-            balrog_props["properties"]["platform"] = self.config['balrog_platform']
-        if "branch" not in balrog_props["properties"]:
-            balrog_props["properties"]["branch"] = self.branch
-
-        self.dump_config(props_path, balrog_props)
-
     def submit_balrog_updates(self, release_type="nightly", product=None):
         c = self.config
         dirs = self.query_abs_dirs()
 
         if self.buildbot_config and "properties" in self.buildbot_config:
             product = self.buildbot_config["properties"]["product"]
 
         if product is None:
@@ -47,19 +26,35 @@ class BalrogMixin(object):
 
         props_path = os.path.join(dirs["base_work_dir"], "balrog_props.json")
         credentials_file = os.path.join(
             dirs["base_work_dir"], c["balrog_credentials_file"]
         )
         submitter_script = os.path.join(
             dirs["abs_tools_dir"], "scripts", "updates", "balrog-submitter.py"
         )
+        self.set_buildbot_property(
+            "hashType", c.get("hash_type", "sha512"), write_to_file=True
+        )
 
-        self.generate_balrog_props(props_path)
+        if self.buildbot_config and "properties" in self.buildbot_config:
+            buildbot_properties = self.buildbot_config["properties"].items()
+        else:
+            buildbot_properties = []
 
+        balrog_props = dict(properties=dict(chain(
+            buildbot_properties,
+            self.buildbot_properties.items(),
+        )))
+        if self.config.get('balrog_platform'):
+            balrog_props["properties"]["platform"] = self.config['balrog_platform']
+        if "branch" not in balrog_props["properties"]:
+            balrog_props["properties"]["branch"] = self.query_branch()
+
+        self.dump_config(props_path, balrog_props)
         cmd = [
             self.query_exe("python"),
             submitter_script,
             "--build-properties", props_path,
             "-t", release_type,
             "--credentials-file", credentials_file,
         ]
         if self._log_level_at_least(INFO):