Bug 1154796 - update gecko based mozharness to sync with 4d855a6835ed, DONTBUILD r=mshal, a=testing
authorJordan Lund <jlund@mozilla.com>
Wed, 08 Jul 2015 12:15:00 -0700
changeset 201243 e6a1ef7a16fa9595d6b0b3195d6b27b08cde21b6
parent 201242 7105dab57de828c29a8f8df97487f4ff79430306
child 201246 34c57f26109477bccb93469d207907ffaf13631a
push id296
push userjlund@mozilla.com
push dateWed, 08 Jul 2015 19:15:26 +0000
treeherdermozilla-esr31@e6a1ef7a16fa [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmshal, testing
bugs1154796
milestone31.8.0esrpre
Bug 1154796 - update gecko based mozharness to sync with 4d855a6835ed, DONTBUILD r=mshal, a=testing
testing/mozharness/README.txt
testing/mozharness/configs/android/android_panda_releng.py
testing/mozharness/configs/b2g/taskcluster-phone-blobfree.py
testing/mozharness/configs/b2g/taskcluster-spark-blobfree.py
testing/mozharness/configs/builds/build_pool_specifics.py
testing/mozharness/configs/merge_day/aurora_to_beta.py
testing/mozharness/configs/merge_day/beta_to_release.py
testing/mozharness/configs/merge_day/central_to_aurora.py
testing/mozharness/configs/merge_day/release_to_esr.py
testing/mozharness/configs/update_tests/mozilla-beta.py
testing/mozharness/configs/update_tests/mozilla-release.py
testing/mozharness/configs/vcs_sync/beagle.py
testing/mozharness/configs/vcs_sync/build-repos.py
testing/mozharness/configs/vcs_sync/gecko-git.py
testing/mozharness/configs/vcs_sync/l10n.py
testing/mozharness/configs/vcs_sync/project-branches.py
testing/mozharness/configs/vcs_sync/staging_build-repos.py
testing/mozharness/configs/vcs_sync/staging_l10n.py
testing/mozharness/mozharness/mozilla/building/buildbase.py
testing/mozharness/mozharness/mozilla/tooltool.py
testing/mozharness/mozharness/mozilla/vcstools.py
testing/mozharness/scripts/android_emulator_unittest.py
testing/mozharness/scripts/android_panda.py
testing/mozharness/scripts/b2g_build.py
testing/mozharness/scripts/desktop_l10n.py
testing/mozharness/scripts/firefox_ui_updates.py
testing/mozharness/scripts/merge_day/gecko_migration.py
--- a/testing/mozharness/README.txt
+++ b/testing/mozharness/README.txt
@@ -1,11 +1,11 @@
 the contents of this dir (testing/mozharness) represent two parts
 
 1) the old way: mozharness.json is a manifest file that locks or "pins" mozharness to a repository and a revision.
 
 2) the new way: an in-gecko-tree copy of mozharness.
     * hgmo/build/mozharness is still live and the defacto read/write repository
     * continuous integration jobs are based on this copy
     * As we transition to dropping support for hg.m.o/build/mozharness, this copy will continue to be synced
-    * this copy is currently based on: http://hg.mozilla.org/build/mozharness/rev/4d855a6835ed
+    * this copy is currently based on: http://hg.mozilla.org/build/mozharness/rev/43f7600b8c80
 
 
--- a/testing/mozharness/configs/android/android_panda_releng.py
+++ b/testing/mozharness/configs/android/android_panda_releng.py
@@ -5,27 +5,16 @@ import os
 MINIDUMP_STACKWALK_PATH = "/builds/minidump_stackwalk"
 
 config = {
     # Values for the foopies
     "exes": {
         'python': '/tools/buildbot/bin/python',
         'virtualenv': ['/tools/buildbot/bin/python', '/tools/misc-python/virtualenv.py'],
     },
-    "run_file_names": {
-        "mochitest": "runtestsremote.py",
-        "reftest": "remotereftest.py",
-        "crashtest": "remotereftest.py",
-        "jsreftest": "remotereftest.py",
-        "robocop": "runtestsremote.py",
-        "instrumentation": "runinstrumentation.py",
-        "xpcshell": "remotexpcshelltests.py",
-        "jittest": "jit_test.py",
-        "cppunittest": "remotecppunittests.py"
-    },
     "hostutils_url":  "http://talos-remote.pvt.build.mozilla.org/tegra/tegra-host-utils.Linux.1109310.2.zip",
     "verify_path":  "/builds/sut_tools/verify.py",
     "install_app_path":  "/builds/sut_tools/installApp.py",
     "logcat_path":  "/builds/sut_tools/logcat.py",
     # test harness options are located in the gecko tree
     "in_tree_config": "config/mozharness/android_panda_config.py",
     "all_mochitest_suites": {
         "mochitest-1": ["--total-chunks=8", "--this-chunk=1"],
new file mode 100644
--- /dev/null
+++ b/testing/mozharness/configs/b2g/taskcluster-phone-blobfree.py
@@ -0,0 +1,31 @@
+#!/usr/bin/env python
+config = {
+    "default_vcs": "tc-vcs",
+    "default_actions": [
+        'checkout-sources',
+        'build',
+        'build-symbols',
+        'prep-upload'
+    ],
+    "upload": {
+        "default": {
+            "upload_dep_target_exclusions": []
+        }
+    },
+    "env": {
+        "GAIA_OPTIMIZE": "1",
+        "WGET_OPTS": "-c -q"
+    },
+    "build_targets": ["blobfree"],
+    "is_automation": True,
+    "repo_remote_mappings": {
+        'https://android.googlesource.com/': 'https://git.mozilla.org/external/aosp',
+        'git://codeaurora.org/': 'https://git.mozilla.org/external/caf',
+        'https://git.mozilla.org/b2g': 'https://git.mozilla.org/b2g',
+        'git://github.com/mozilla-b2g/': 'https://git.mozilla.org/b2g',
+        'git://github.com/mozilla/': 'https://git.mozilla.org/b2g',
+        'https://git.mozilla.org/releases': 'https://git.mozilla.org/releases',
+        'http://android.git.linaro.org/git-ro/': 'https://git.mozilla.org/external/linaro',
+        'git://github.com/apitrace/': 'https://git.mozilla.org/external/apitrace',
+    },
+}
new file mode 100644
--- /dev/null
+++ b/testing/mozharness/configs/b2g/taskcluster-spark-blobfree.py
@@ -0,0 +1,36 @@
+#!/usr/bin/env python
+config = {
+    "default_vcs": "tc-vcs",
+    "default_actions": [
+        'checkout-sources',
+        'build',
+        'build-symbols',
+        'prep-upload'
+    ],
+    "upload": {
+        "default": {
+            "upload_dep_target_exclusions": []
+        }
+    },
+    "env": {
+        "GAIA_OPTIMIZE": "1",
+        "WGET_OPTS": "-c -q",
+        "LIGHTSABER": "1",
+        "B2G_PATH": "%(work_dir)s",
+        "BOWER_FLAGS": "--allow-root",
+        "GAIA_DISTRIBUTION_DIR": "%(work_dir)s/gaia/distros/spark",
+        "WGET_OPTS": "-c -q",
+    },
+    "is_automation": True,
+    "build_targets": ["blobfree"],
+    "repo_remote_mappings": {
+        'https://android.googlesource.com/': 'https://git.mozilla.org/external/aosp',
+        'git://codeaurora.org/': 'https://git.mozilla.org/external/caf',
+        'https://git.mozilla.org/b2g': 'https://git.mozilla.org/b2g',
+        'git://github.com/mozilla-b2g/': 'https://git.mozilla.org/b2g',
+        'git://github.com/mozilla/': 'https://git.mozilla.org/b2g',
+        'https://git.mozilla.org/releases': 'https://git.mozilla.org/releases',
+        'http://android.git.linaro.org/git-ro/': 'https://git.mozilla.org/external/linaro',
+        'git://github.com/apitrace/': 'https://git.mozilla.org/external/apitrace',
+    },
+}
--- a/testing/mozharness/configs/builds/build_pool_specifics.py
+++ b/testing/mozharness/configs/builds/build_pool_specifics.py
@@ -34,10 +34,13 @@ config = {
         'stage_server': 'stage.mozilla.org',
         "sendchange_masters": ["buildbot-master81.build.mozilla.org:9301"],
         'taskcluster_index': 'index',
     },
     "taskcluster": {
         'graph_server': 'graphs.mozilla.org',
         'symbol_server_host': "symbolpush.mozilla.org",
         'stage_server': 'stage.mozilla.org',
+        # use the relengapi proxy to talk to tooltool
+        "tooltool_servers": ['http://relengapi/tooltool/'],
+        "tooltool_url": 'http://relengapi/tooltool/',
     },
 }
--- a/testing/mozharness/configs/merge_day/aurora_to_beta.py
+++ b/testing/mozharness/configs/merge_day/aurora_to_beta.py
@@ -1,17 +1,45 @@
 config = {
     "log_name": "aurora_to_beta",
 
-    "branding_dirs": [
-        "mobile/android/config/mozconfigs/android-api-11/",
-        "mobile/android/config/mozconfigs/android-api-9-10-constrained/",
-        "mobile/android/config/mozconfigs/android-x86/",
+    "replacements": [
+        # File, from, to
+        ("{}/{}".format(d, f),
+        "ac_add_options --with-branding=mobile/android/branding/aurora",
+        "ac_add_options --with-branding=mobile/android/branding/beta")
+        for d in ["mobile/android/config/mozconfigs/android-api-11/",
+                  "mobile/android/config/mozconfigs/android-api-9-10-constrained/",
+                  "mobile/android/config/mozconfigs/android-x86/"]
+        for f in ["debug", "nightly", "l10n-nightly"]
+    ] + [
+        # File, from, to
+        ("{}/{}".format(d, f),
+        "ac_add_options --with-branding=browser/branding/aurora",
+        "ac_add_options --with-branding=browser/branding/nightly")
+        for d in ["browser/config/mozconfigs/linux32",
+                  "browser/config/mozconfigs/linux64",
+                  "browser/config/mozconfigs/win32",
+                  "browser/config/mozconfigs/win64",
+                  "browser/config/mozconfigs/macosx64"]
+        for f in ["debug", "nightly", "l10n-mozconfig"]
+    ] + [
+        ("browser/config/mozconfigs/macosx-universal/nightly",
+         "ac_add_options --with-branding=browser/branding/aurora",
+         "ac_add_options --with-branding=browser/branding/nightly"),
+        ("browser/confvars.sh",
+         "ACCEPTED_MAR_CHANNEL_IDS=firefox-mozilla-aurora",
+         "ACCEPTED_MAR_CHANNEL_IDS=firefox-mozilla-beta,firefox-mozilla-release"),
+        ("browser/confvars.sh",
+         "MAR_CHANNEL_ID=firefox-mozilla-aurora",
+         "MAR_CHANNEL_ID=firefox-mozilla-beta"),
+        ("browser/config/mozconfigs/whitelist",
+         "ac_add_options --with-branding=browser/branding/aurora",
+         "ac_add_options --with-branding=browser/branding/nightly"),
     ],
-    "branding_files": ["debug", "l10n-nightly", "nightly"],
 
     # Disallow sharing, since we want pristine .hg directories.
     # "vcs_share_base": None,
     # "hg_share_base": None,
     "tools_repo_url": "https://hg.mozilla.org/build/tools",
     "tools_repo_revision": "default",
     "from_repo_url": "ssh://hg.mozilla.org/releases/mozilla-aurora",
     "to_repo_url": "ssh://hg.mozilla.org/releases/mozilla-beta",
--- a/testing/mozharness/configs/merge_day/beta_to_release.py
+++ b/testing/mozharness/configs/merge_day/beta_to_release.py
@@ -1,17 +1,28 @@
 config = {
     "log_name": "beta_to_release",
-
-    "branding_dirs": [
-        "mobile/android/config/mozconfigs/android-api-11/",
-        "mobile/android/config/mozconfigs/android-api-9-10-constrained/",
-        "mobile/android/config/mozconfigs/android-x86/",
+    "replacements": [
+        # File, from, to
+        ("{}/{}".format(d, f),
+        "ac_add_options --with-branding=mobile/android/branding/beta",
+        "ac_add_options --with-branding=mobile/android/branding/official")
+        for d in ["mobile/android/config/mozconfigs/android-api-11/",
+                  "mobile/android/config/mozconfigs/android-api-9-10-constrained/",
+                  "mobile/android/config/mozconfigs/android-x86/"]
+        for f in ["debug", "nightly", "l10n-nightly", "l10n-release", "release"]
+    ] + [
+        # File, from, to
+        ("browser/confvars.sh",
+         "ACCEPTED_MAR_CHANNEL_IDS=firefox-mozilla-beta,firefox-mozilla-release",
+         "ACCEPTED_MAR_CHANNEL_IDS=firefox-mozilla-release"),
+        ("browser/confvars.sh",
+         "MAR_CHANNEL_ID=firefox-mozilla-beta",
+         "MAR_CHANNEL_ID=firefox-mozilla-release"),
     ],
-    "branding_files": ["release", "l10n-release", "l10n-nightly", "nightly"],
 
     # Disallow sharing, since we want pristine .hg directories.
     # "vcs_share_base": None,
     # "hg_share_base": None,
     "tools_repo_url": "https://hg.mozilla.org/build/tools",
     "tools_repo_revision": "default",
     "from_repo_url": "ssh://hg.mozilla.org/releases/mozilla-beta",
     "to_repo_url": "ssh://hg.mozilla.org/releases/mozilla-release",
--- a/testing/mozharness/configs/merge_day/central_to_aurora.py
+++ b/testing/mozharness/configs/merge_day/central_to_aurora.py
@@ -15,22 +15,17 @@ config = {
         ("{}/{}".format(d, f),
         "ac_add_options --with-branding=browser/branding/nightly",
         "ac_add_options --with-branding=browser/branding/aurora")
         for d in ["browser/config/mozconfigs/linux32",
                   "browser/config/mozconfigs/linux64",
                   "browser/config/mozconfigs/win32",
                   "browser/config/mozconfigs/win64",
                   "browser/config/mozconfigs/macosx64"]
-        for f in ["debug", "nightly"]
-    ] + [
-        ("browser/config/mozconfigs/macosx-universal/nightly",
-        "ac_add_options --with-branding=browser/branding/nightly",
-        "ac_add_options --with-branding=browser/branding/aurora")
-
+        for f in ["debug", "nightly", "l10n-mozconfig"]
     ] + [
         # File, from, to
         ("{}/l10n-nightly".format(d),
         "ac_add_options --with-l10n-base=../../l10n-central",
         "ac_add_options --with-l10n-base=..")
         for d in ["mobile/android/config/mozconfigs/android-api-11/",
                   "mobile/android/config/mozconfigs/android-api-9-10-constrained/",
                   "mobile/android/config/mozconfigs/android-x86/"]
@@ -48,16 +43,22 @@ config = {
     ] + [
         # File, from, to
         ("browser/confvars.sh",
          "ACCEPTED_MAR_CHANNEL_IDS=firefox-mozilla-central",
          "ACCEPTED_MAR_CHANNEL_IDS=firefox-mozilla-aurora"),
         ("browser/confvars.sh",
          "MAR_CHANNEL_ID=firefox-mozilla-central",
          "MAR_CHANNEL_ID=firefox-mozilla-aurora"),
+        ("browser/config/mozconfigs/macosx-universal/nightly",
+         "ac_add_options --with-branding=browser/branding/nightly",
+         "ac_add_options --with-branding=browser/branding/aurora"),
+        ("browser/config/mozconfigs/whitelist",
+         "ac_add_options --with-branding=browser/branding/nightly",
+         "ac_add_options --with-branding=browser/branding/aurora"),
     ],
     "locale_files": [
         "browser/locales/shipped-locales",
         "browser/locales/all-locales",
         "mobile/android/locales/maemo-locales",
         "mobile/android/locales/all-locales"
     ],
 
--- a/testing/mozharness/configs/merge_day/release_to_esr.py
+++ b/testing/mozharness/configs/merge_day/release_to_esr.py
@@ -1,14 +1,23 @@
 NEW_ESR_REPO = "ssh://hg.mozilla.org/releases/mozilla-esr45"
 OLD_ESR_REPO = "https://hg.mozilla.org/releases/mozilla-esr38"
 OLD_ESR_CHANGESET = "16351963d75c"
 
 config = {
     "log_name": "relese_to_esr",
+    "replacements": [
+        # File, from, to
+        ("browser/confvars.sh",
+         "ACCEPTED_MAR_CHANNEL_IDS=firefox-mozilla-release",
+         "ACCEPTED_MAR_CHANNEL_IDS=firefox-mozilla-esr"),
+        ("browser/confvars.sh",
+         "MAR_CHANNEL_ID=firefox-mozilla-release",
+         "MAR_CHANNEL_ID=firefox-mozilla-esr"),
+    ],
     # Disallow sharing, since we want pristine .hg directories.
     # "vcs_share_base": None,
     # "hg_share_base": None,
     "tools_repo_url": "https://hg.mozilla.org/build/tools",
     "tools_repo_revision": "default",
     "from_repo_url": "ssh://hg.mozilla.org/releases/mozilla-release",
     "to_repo_url": NEW_ESR_REPO,
 
deleted file mode 100644
--- a/testing/mozharness/configs/update_tests/mozilla-beta.py
+++ /dev/null
@@ -1,18 +0,0 @@
-from mozharness.base.script import platform_name
-
-PLATFORM_CONFIG = {
-    'linux64': {
-        'update_verify_config': 'mozBeta-firefox-linux64.cfg'
-    },
-    'macosx': {
-        'update_verify_config': 'mozBeta-firefox-mac64.cfg'
-    },
-    'win32': {
-        'update_verify_config': 'mozBeta-firefox-win32.cfg'
-    },
-}
-
-config = PLATFORM_CONFIG[platform_name()]
-config.update({
-    'firefox_ui_branch': 'mozilla-beta'
-})
deleted file mode 100644
--- a/testing/mozharness/configs/update_tests/mozilla-release.py
+++ /dev/null
@@ -1,18 +0,0 @@
-from mozharness.base.script import platform_name
-
-PLATFORM_CONFIG = {
-    'linux64': {
-        'update_verify_config': 'mozRelease-firefox-linux64.cfg'
-    },
-    'macosx': {
-        'update_verify_config': 'mozRelease-firefox-mac64.cfg'
-    },
-    'win32': {
-        'update_verify_config': 'mozRelease-firefox-win32.cfg'
-    },
-}
-
-config = PLATFORM_CONFIG[platform_name()]
-config.update({
-    'firefox_ui_branch': 'mozilla-beta'
-})
--- a/testing/mozharness/configs/vcs_sync/beagle.py
+++ b/testing/mozharness/configs/vcs_sync/beagle.py
@@ -733,17 +733,17 @@ config = {
         "requests==2.2.1",
     ],
     "find_links": [
         "http://pypi.pvt.build.mozilla.org/pub",
         "http://pypi.pub.build.mozilla.org/pub",
     ],
     "pip_index": False,
 
-    "default_notify_from": "developer-services@mozilla.org",
+    "default_notify_from": "developer-services+%s@mozilla.org" % hostname,
     "notify_config": [{
         "to": "releng-ops-trial@mozilla.com",
         "failure_only": False,
         "skip_empty_messages": True,
     }],
 
     # Disallow sharing, since we want pristine .hg and .git directories.
     "vcs_share_base": None,
--- a/testing/mozharness/configs/vcs_sync/build-repos.py
+++ b/testing/mozharness/configs/vcs_sync/build-repos.py
@@ -78,17 +78,17 @@ config = {
         "mozprocess==0.11",
         "requests==2.2.1",
     ],
     "find_links": [
         "http://pypi.pub.build.mozilla.org/pub"
     ],
     "pip_index": False,
 
-    "default_notify_from": "developer-services@mozilla.org",
+    "default_notify_from": "developer-services+%s@mozilla.org" % hostname,
     "notify_config": [{
         "to": "releng-ops-trial@mozilla.com",
         "failure_only": False,
         "skip_empty_messages": True,
     }],
 
     # Disallow sharing, since we want pristine .hg and .git directories.
     "vcs_share_base": None,
--- a/testing/mozharness/configs/vcs_sync/gecko-git.py
+++ b/testing/mozharness/configs/vcs_sync/gecko-git.py
@@ -375,19 +375,19 @@ config = {
 
     "upload_config": [{
         "ssh_key": "~/.ssh/id_rsa",
         "ssh_user": "pmoore",
         "remote_host": "github-sync2",
         "remote_path": "/home/pmoore/upload/gecko-git-upload",
     }],
 
-    "default_notify_from": "developer-services@mozilla.org",
+    "default_notify_from": "developer-services+%s@mozilla.org" % hostname,
     "notify_config": [{
-        "to": "pmoore@mozilla.com",
+        "to": "releng-ops-trial@mozilla.com",
         "failure_only": False,
-        "skip_empty_messages": False,
+        "skip_empty_messages": True,
     }],
 
     # Disallow sharing, since we want pristine .hg and .git directories.
     "vcs_share_base": None,
     "hg_share_base": None,
 }
--- a/testing/mozharness/configs/vcs_sync/l10n.py
+++ b/testing/mozharness/configs/vcs_sync/l10n.py
@@ -276,17 +276,17 @@ config = {
         "mozprocess==0.11",
         "requests==2.2.1",
     ],
     "find_links": [
         "http://pypi.pub.build.mozilla.org/pub",
     ],
     "pip_index": False,
 
-    "default_notify_from": "developer-services@mozilla.org",
+    "default_notify_from": "developer-services+%s@mozilla.org" % hostname,
     "notify_config": [{
         "to": "releng-ops-trial@mozilla.com",
         "failure_only": False,
         "skip_empty_messages": True,
     }],
 
     # Disallow sharing, since we want pristine .hg and .git directories.
     "vcs_share_base": None,
--- a/testing/mozharness/configs/vcs_sync/project-branches.py
+++ b/testing/mozharness/configs/vcs_sync/project-branches.py
@@ -97,17 +97,17 @@ config = {
     "find_links": [
         "http://pypi.pvt.build.mozilla.org/pub",
         "http://pypi.pub.build.mozilla.org/pub",
     ],
     "pip_index": False,
 
     "combined_mapfile": "combined_gecko_mapfile",
 
-    "default_notify_from": "developer-services@mozilla.org",
+    "default_notify_from": "developer-services+%s@mozilla.org" % hostname,
     "notify_config": [{
         "to": "releng-ops-trial@mozilla.com",
         "failure_only": False,
         "skip_empty_messages": True,
     }],
 
     # Disallow sharing, since we want pristine .hg and .git directories.
     "vcs_share_base": None,
deleted file mode 100644
--- a/testing/mozharness/configs/vcs_sync/staging_build-repos.py
+++ /dev/null
@@ -1,113 +0,0 @@
-import os
-import socket
-hostname = socket.gethostname()
-
-build_repos = (
-    'autoland',
-    'buildapi',
-    'buildbot-configs',
-    'buildbotcustom',
-    'cloud-tools',
-    'mozharness',
-    'opsi-package-sources',
-    'partner-repacks',
-    'preproduction',
-    'puppet',
-    'puppet-manifests',
-    'rpm-sources',
-    'talos',
-    'tools',
-)
-
-conversion_repos = []
-remote_targets = {}
-
-for repo in build_repos:
-    conversion_repos.append({
-        "repo": "https://hg.mozilla.org/build/%s" % repo,
-        "repo_name": "build-%s" % repo,
-        "conversion_dir": "build-%s" % repo,
-        "targets": [{
-            "target_dest": "build-%s-github" % repo,
-            "force_push": True
-        }],
-        "vcs": "hg",
-        "mapper": {
-            "url": "https://api-pub-build.allizom.org/mapper",
-            "project": "build-%s" % repo,
-        },
-        "branch_config": {
-            "branches": {
-                "default": "master",
-            },
-            "branch_regexes": [
-                "^.*$"
-            ]
-        },
-        "tag_config": {
-            "tag_regexes": [
-                "^.*$"
-            ]
-        },
-        "generate_git_notes": True, # False by default
-    })
-    remote_targets["build-%s-github" % repo] = {
-        "repo": "git@github.com:petermoore/build-%s.git" % repo,
-        "ssh_key": "~/.ssh/github_mozilla_rsa",
-        "vcs": "git",
-    }
-
-config = {
-    "log_name": "build-repos",
-    "log_max_rotate": 99,
-    "job_name": "build-repos",
-    "env": {
-        "PATH": "%(PATH)s:/usr/libexec/git-core",
-    },
-    "conversion_repos": conversion_repos,
-    "remote_targets": remote_targets,
-    "virtualenv_modules": [
-        "dulwich==0.9.0",
-        "ordereddict==1.1",
-        "hg-git==0.4.0-moz2",
-        "mapper==0.1",
-        "mercurial==2.6.3",
-        "mozfile==0.9",
-        "mozinfo==0.5",
-        "mozprocess==0.11",
-        "requests==2.2.1",
-    ],
-    "find_links": [
-        "http://pypi.pub.build.mozilla.org/pub"
-    ],
-    "pip_index": False,
-
-    "default_notify_from": "developer-services@mozilla.org",
-    "notify_config": [{
-        "to": "releng-ops-trial@mozilla.com",
-        "failure_only": False,
-        "skip_empty_messages": True,
-    }],
-
-    # Disallow sharing, since we want pristine .hg and .git directories.
-    "vcs_share_base": None,
-    "hg_share_base": None,
-
-    # any hg command line options
-    "hg_options": (
-        "--config",
-        "web.cacerts=/etc/pki/tls/certs/ca-bundle.crt"
-    ),
-
-    "default_actions": [
-        'list-repos',
-        'create-virtualenv',
-        'update-stage-mirror',
-        'update-work-mirror',
-        'create-git-notes',
-        'publish-to-mapper',
-        'push',
-        'combine-mapfiles',
-        'notify',
-    ],
-}
deleted file mode 100644
--- a/testing/mozharness/configs/vcs_sync/staging_l10n.py
+++ /dev/null
@@ -1,290 +0,0 @@
-from copy import deepcopy
-import socket
-hostname = socket.gethostname()
-
-GECKO_BRANCHES = {
-    'v2.0': 'mozilla-beta',
-    'v2.1': 'mozilla-aurora',
-    'v2.2': 'mozilla-central',
-}
-
-GECKO_CONFIG_TEMPLATE = {
-
-    'mozilla-release': {
-        'generate_git_notes': False, # we can change this when bug 1034725 is resolved
-        'mapper': {
-            'project': 'gitmo-gecko-l10n',
-            'url': 'https://api-pub-build.allizom.org/mapper'
-        },
-        'locales_file_url': 'https://hg.mozilla.org/releases/mozilla-release/raw-file/default/b2g/locales/all-locales',
-        'hg_url': 'https://hg.mozilla.org/releases/l10n/mozilla-release/%(locale)s',
-        'targets': [{
-            'target_dest': 'releases-l10n-%(locale)s-gecko/.git',
-            'test_push': True,
-            'vcs': 'git'
-        }, {
-            'target_dest': 'gitmo-gecko-l10n-%(locale)s',
-        }],
-        'tag_config': {
-            'tag_regexes': [
-                '^B2G_',
-            ],
-        },
-    },
-
-    'mozilla-beta': {
-        'generate_git_notes': False, # we can change this when bug 1034725 is resolved
-        'mapper': {
-            'project': 'gitmo-gecko-l10n',
-            'url': 'https://api-pub-build.allizom.org/mapper'
-        },
-        'locales_file_url': 'https://hg.mozilla.org/releases/mozilla-beta/raw-file/default/b2g/locales/all-locales',
-        'hg_url': 'https://hg.mozilla.org/releases/l10n/mozilla-beta/%(locale)s',
-        'targets': [{
-            'target_dest': 'releases-l10n-%(locale)s-gecko/.git',
-            'test_push': True,
-            'vcs': 'git'
-        }, {
-            'target_dest': 'gitmo-gecko-l10n-%(locale)s',
-        }],
-        'tag_config': {
-            'tag_regexes': [
-                '^B2G_',
-            ],
-        },
-    },
-
-    'mozilla-aurora': {
-        'generate_git_notes': False, # we can change this when bug 1034725 is resolved
-        'mapper': {
-            'project': 'gitmo-gecko-l10n',
-            'url': 'https://api-pub-build.allizom.org/mapper'
-        },
-        'locales_file_url': 'https://hg.mozilla.org/releases/mozilla-aurora/raw-file/default/b2g/locales/all-locales',
-        'hg_url': 'https://hg.mozilla.org/releases/l10n/mozilla-aurora/%(locale)s',
-        'targets': [{
-            'target_dest': 'releases-l10n-%(locale)s-gecko/.git',
-            'test_push': True,
-            'vcs': 'git'
-        }, {
-            'target_dest': 'gitmo-gecko-l10n-%(locale)s',
-        }],
-        'tag_config': {
-            'tag_regexes': [
-                '^B2G_',
-            ],
-        },
-    },
-
-    'mozilla-central': {
-        'generate_git_notes': False, # we can change this when bug 1034725 is resolved
-        'mapper': {
-            'project': 'gitmo-gecko-l10n',
-            'url': 'https://api-pub-build.allizom.org/mapper'
-        },
-        'locales_file_url': 'https://hg.mozilla.org/mozilla-central/raw-file/default/b2g/locales/all-locales',
-        'hg_url': 'https://hg.mozilla.org/l10n-central/%(locale)s',
-        'targets': [{
-            'target_dest': 'releases-l10n-%(locale)s-gecko/.git',
-            'test_push': True,
-            'vcs': 'git'
-        }, {
-            'target_dest': 'gitmo-gecko-l10n-%(locale)s',
-        }],
-        'tag_config': {
-            'tag_regexes': [
-                '^B2G_',
-            ],
-        },
-    },
-}
-
-# Build gecko_config
-GECKO_CONFIG = {}
-for version, branch in GECKO_BRANCHES.items():
-    GECKO_CONFIG[branch] = deepcopy(GECKO_CONFIG_TEMPLATE[branch])
-    GECKO_CONFIG[branch]['git_branch_name'] = version
-
-config = {
-    "log_name": "l10n",
-    "log_max_rotate": 99,
-    "job_name": "l10n",
-    "env": {
-        "PATH": "%(PATH)s:/usr/libexec/git-core",
-    },
-    "conversion_type": "b2g-l10n",
-    "combined_mapfile": "l10n-mapfile",
-    "l10n_config": {
-        "gecko_config": GECKO_CONFIG,
-        "gaia_config": {
-            'v2_0': {
-                'generate_git_notes': False, # we can change this when bug 1034725 is resolved
-                'mapper': {
-                    'project': 'gitmo-gaia-l10n',
-                    'url': 'https://api-pub-build.allizom.org/mapper'
-                },
-                'locales_file_url': 'https://raw.github.com/mozilla-b2g/gaia/v2.0/locales/languages_all.json',
-                'hg_url': 'https://hg.mozilla.org/releases/gaia-l10n/v2_0/%(locale)s',
-                'git_branch_name': 'v2.0',
-                'targets': [{
-                    'target_dest': 'releases-l10n-%(locale)s-gaia/.git',
-                    'test_push': True,
-                    'vcs': 'git'
-                }, {
-                    'target_dest': 'gitmo-gaia-l10n-%(locale)s',
-                }],
-                'tag_config': {
-                    'tag_regexes': [
-                        '^B2G_',
-                    ],
-                },
-            },
-            'v1_4': {
-                'generate_git_notes': False, # we can change this when bug 1034725 is resolved
-                'mapper': {
-                    'project': 'gitmo-gaia-l10n',
-                    'url': 'https://api-pub-build.allizom.org/mapper'
-                },
-                'locales_file_url': 'https://raw.github.com/mozilla-b2g/gaia/v1.4/locales/languages_all.json',
-                'hg_url': 'https://hg.mozilla.org/releases/gaia-l10n/v1_4/%(locale)s',
-                'git_branch_name': 'v1.4',
-                'targets': [{
-                    'target_dest': 'releases-l10n-%(locale)s-gaia/.git',
-                    'test_push': True,
-                    'vcs': 'git'
-                }, {
-                    'target_dest': 'gitmo-gaia-l10n-%(locale)s',
-                }],
-                'tag_config': {
-                    'tag_regexes': [
-                        '^B2G_',
-                    ],
-                },
-            },
-            'v1_3': {
-                'generate_git_notes': False, # we can change this when bug 1034725 is resolved
-                'mapper': {
-                    'project': 'gitmo-gaia-l10n',
-                    'url': 'https://api-pub-build.allizom.org/mapper'
-                },
-                'locales_file_url': 'https://raw.github.com/mozilla-b2g/gaia/v1.3/locales/languages_dev.json',
-                'hg_url': 'https://hg.mozilla.org/releases/gaia-l10n/v1_3/%(locale)s',
-                'git_branch_name': 'v1.3',
-                'targets': [{
-                    'target_dest': 'releases-l10n-%(locale)s-gaia/.git',
-                    'test_push': True,
-                    'vcs': 'git'
-                }, {
-                    'target_dest': 'gitmo-gaia-l10n-%(locale)s',
-                }],
-                'tag_config': {
-                    'tag_regexes': [
-                        '^B2G_',
-                    ],
-                },
-            },
-            'v1_2': {
-                'generate_git_notes': False, # we can change this when bug 1034725 is resolved
-                'mapper': {
-                    'project': 'gitmo-gaia-l10n',
-                    'url': 'https://api-pub-build.allizom.org/mapper'
-                },
-                'locales_file_url': 'https://raw.github.com/mozilla-b2g/gaia/v1.2/locales/languages_all.json',
-                'hg_url': 'https://hg.mozilla.org/releases/gaia-l10n/v1_2/%(locale)s',
-                'git_branch_name': 'v1.2',
-                'targets': [{
-                    'target_dest': 'releases-l10n-%(locale)s-gaia/.git',
-                    'test_push': True,
-                    'vcs': 'git'
-                }, {
-                    'target_dest': 'gitmo-gaia-l10n-%(locale)s',
-                }],
-                'tag_config': {
-                    'tag_regexes': [
-                        '^B2G_',
-                    ],
-                },
-            },
-            'master': {
-                'generate_git_notes': False, # we can change this when bug 1034725 is resolved
-                'mapper': {
-                    'project': 'gitmo-gaia-l10n',
-                    'url': 'https://api-pub-build.allizom.org/mapper'
-                },
-                'locales_file_url': 'https://raw.github.com/mozilla-b2g/gaia/master/locales/languages_all.json',
-                'hg_url': 'https://hg.mozilla.org/gaia-l10n/%(locale)s',
-                'git_branch_name': 'master',
-                'targets': [{
-                    'target_dest': 'releases-l10n-%(locale)s-gaia/.git',
-                    'test_push': True,
-                    'vcs': 'git'
-                }, {
-                    'target_dest': 'gitmo-gaia-l10n-%(locale)s',
-                }],
-                'tag_config': {
-                    'tag_regexes': [
-                        '^B2G_',
-                    ],
-                },
-            },
-        },
-    },
-
-    "remote_targets": {
-        "gitmo-gecko-l10n-%(locale)s": {
-            "repo": 'git@github.com:petermoore/l10n-%(locale)s-gecko.git',
-            "ssh_key": "~/.ssh/github_mozilla_rsa",
-            "vcs": "git",
-        },
-        "gitmo-gaia-l10n-%(locale)s": {
-            "repo": 'git@github.com:petermoore/l10n-%(locale)s-gaia.git',
-            "ssh_key": "~/.ssh/github_mozilla_rsa",
-            "vcs": "git",
-        },
-    },
-
-    "virtualenv_modules": [
-        "bottle==0.11.6",
-        "dulwich==0.9.0",
-        "ordereddict==1.1",
-        "hg-git==0.4.0-moz2",
-        "mapper==0.1",
-        "mercurial==2.6.3",
-        "mozfile==0.9",
-        "mozinfo==0.5",
-        "mozprocess==0.11",
-        "requests==2.2.1",
-    ],
-    "find_links": [
-        "http://pypi.pub.build.mozilla.org/pub",
-    ],
-    "pip_index": False,
-
-    "default_notify_from": "developer-services@mozilla.org",
-    "notify_config": [{
-        "to": "pmoore@mozilla.com",
-        "failure_only": False,
-        "skip_empty_messages": True,
-    }],
-
-    # Disallow sharing, since we want pristine .hg and .git directories.
-    "vcs_share_base": None,
-    "hg_share_base": None,
-
-    # any hg command line options
-    "hg_options": (
-        "--config",
-        "web.cacerts=/etc/pki/tls/certs/ca-bundle.crt"
-    ),
-
-    "default_actions": [
-        'list-repos',
-        'create-virtualenv',
-        'update-stage-mirror',
-        'update-work-mirror',
-        'publish-to-mapper',
-        'push',
-        'combine-mapfiles',
-        'notify',
-    ],
-}
--- a/testing/mozharness/mozharness/mozilla/building/buildbase.py
+++ b/testing/mozharness/mozharness/mozilla/building/buildbase.py
@@ -1062,22 +1062,28 @@ or run without that action (ie: --no-{ac
                        "tree to use use. Please provide the path in your "
                        "config via 'src_mozconfig'")
 
     # TODO: replace with ToolToolMixin
     def _get_tooltool_auth_file(self):
         # set the default authentication file based on platform; this
         # corresponds to where puppet puts the token
         if 'tooltool_authentication_file' in self.config:
-            return self.config['tooltool_authentication_file']
+            fn = self.config['tooltool_authentication_file']
+        elif self._is_windows():
+            fn = r'c:\builds\relengapi.tok'
+        else:
+            fn = '/builds/relengapi.tok'
 
-        if self._is_windows():
-            return r'c:\builds\relengapi.tok'
-        else:
-            return '/builds/relengapi.tok'
+        # if the file doesn't exist, don't pass it to tooltool (it will just
+        # fail).  In taskcluster, this will work OK as the relengapi-proxy will
+        # take care of auth.  Everywhere else, we'll get auth failures if
+        # necessary.
+        if os.path.exists(fn):
+            return fn
 
     def _run_tooltool(self):
         self._assert_cfg_valid_for_action(
             ['tooltool_script', 'tooltool_bootstrap', 'tooltool_url'],
             'build'
         )
         c = self.config
         dirs = self.query_abs_dirs()
@@ -1090,17 +1096,19 @@ or run without that action (ie: --no-{ac
         cmd = [
             'sh',
             fetch_script_path,
             tooltool_manifest_path,
             c['tooltool_url'],
             c['tooltool_bootstrap'],
         ]
         cmd.extend(c['tooltool_script'])
-        cmd.extend(['--authentication-file', self._get_tooltool_auth_file()])
+        auth_file = self._get_tooltool_auth_file()
+        if auth_file:
+            cmd.extend(['--authentication-file', auth_file])
         self.info(str(cmd))
         self.run_command(cmd, cwd=dirs['abs_src_dir'], halt_on_failure=True)
 
     def query_revision(self, source_path=None):
         """ returns the revision of the build
 
          first will look for it in buildbot_properties and then in
          buildbot_config. Failing that, it will actually poll the source of
--- a/testing/mozharness/mozharness/mozilla/tooltool.py
+++ b/testing/mozharness/mozharness/mozilla/tooltool.py
@@ -28,22 +28,28 @@ class TooltoolMixin(object):
     file than that used in releng automation,override
     config['tooltool_authentication_file']; set it to None to not pass
     any authentication information (OK for public files)
     """
     def _get_auth_file(self):
         # set the default authentication file based on platform; this
         # corresponds to where puppet puts the token
         if 'tooltool_authentication_file' in self.config:
-            return self.config['tooltool_authentication_file']
+            fn = self.config['tooltool_authentication_file']
+        elif self._is_windows():
+            fn = r'c:\builds\relengapi.tok'
+        else:
+            fn = '/builds/relengapi.tok'
 
-        if self._is_windows():
-            return r'c:\builds\relengapi.tok'
-        else:
-            return '/builds/relengapi.tok'
+        # if the file doesn't exist, don't pass it to tooltool (it will just
+        # fail).  In taskcluster, this will work OK as the relengapi-proxy will
+        # take care of auth.  Everywhere else, we'll get auth failures if
+        # necessary.
+        if os.path.exists(fn):
+            return fn
 
     def tooltool_fetch(self, manifest, bootstrap_cmd=None,
                        output_dir=None, privileged=False, cache=None):
         """docstring for tooltool_fetch"""
         tooltool = self.query_exe('tooltool.py', return_type='list')
 
         if self.config.get("developer_mode"):
             tooltool = [bin for bin in tooltool if os.path.exists(bin)]
--- a/testing/mozharness/mozharness/mozilla/vcstools.py
+++ b/testing/mozharness/mozharness/mozilla/vcstools.py
@@ -34,19 +34,25 @@ class VCSToolsScript(VCSScript):
                     self.download_file(
                         url=self.config[vcs_tool],
                         file_name=file_path,
                         parent_dir=os.path.dirname(file_path),
                         create_parent_dir=True,
                     )
                     self.chmod(file_path, 0755)
         else:
+            # We simply verify that everything is in order
+            # or if the user forgot to specify developer mode
             for vcs_tool in VCS_TOOLS:
                 file_path = self.which(vcs_tool)
-                if file_path is None:
-                    file_path = self.query_exe(vcs_tool)
 
-                    if not self.is_exe(file_path):
-                        self.critical("%s is not executable." % file_path)
+                # If the tool is specified and it is a list is
+                # because we're running on Windows and we won't check
+                if type(self.query_exe(vcs_tool)) is list:
+                    continue
 
+                if not self.is_exe(file_path):
+                    self.critical("%s is not executable." % file_path)
+
+                if file_path is None:
                     self.fatal("This machine is missing %s, if this is your "
                                "local machine you can use --cfg "
                                "developer_config.py" % vcs_tool)
--- a/testing/mozharness/scripts/android_emulator_unittest.py
+++ b/testing/mozharness/scripts/android_emulator_unittest.py
@@ -590,17 +590,17 @@ class AndroidEmulatorTest(BlobUploadMixi
         '''
         Check to see if the emulator can be contacted via adb, telnet, and sut, if configured. 
         If any communication attempt fails, kill the emulator, re-launch, and re-check.
         '''
         self.mkdir_p(self.query_abs_dirs()['abs_blob_upload_dir'])
         max_restarts = 3
         emulator_ok = self._retry(max_restarts, 30, self._verify_emulator_and_restart_on_fail, "Check emulator")
         if not emulator_ok:
-            self.fatal('Unable to start emulator after %d attempts' % max_restarts)
+            self.fatal('INFRA-ERROR: Unable to start emulator after %d attempts' % max_restarts)
         # Start logcat for the emulator. The adb process runs until the
         # corresponding emulator is killed. Output is written directly to
         # the blobber upload directory so that it is uploaded automatically
         # at the end of the job.
         logcat_filename = 'logcat-%s.log' % self.emulator["device_id"]
         logcat_path = os.path.join(self.abs_dirs['abs_blob_upload_dir'], logcat_filename)
         logcat_cmd = '%s -s %s logcat -v threadtime Trace:S StrictMode:S ExchangeService:S > %s &' % \
             (self.adb_path, self.emulator["device_id"], logcat_path)
--- a/testing/mozharness/scripts/android_panda.py
+++ b/testing/mozharness/scripts/android_panda.py
@@ -427,17 +427,17 @@ class PandaTest(TestingMixin, MercurialS
         if self.symbols_url:
             return self.symbols_url
 
     def _query_abs_base_cmd(self, suite_category, suite):
         #check for apk first with if ?
         c = self.config
         dirs = self.query_abs_dirs()
         options = []
-        run_file = c['run_file_names'][suite_category]
+        run_file = self.tree_config["suite_definitions"][suite_category]["run_filename"]
         base_cmd = ['python', '-u']
         base_cmd.append(os.path.join((dirs["abs_%s_dir" % suite_category]), run_file))
         self.device_ip = socket.gethostbyname(self.mozpool_device)
         #applies to mochitest, reftest, jsreftest
         # TestingMixin._download_and_extract_symbols() will set
         # self.symbols_path when downloading/extracting.
         hostnumber = 0
         mozpool_device_list = self.mozpool_device.split('-')
--- a/testing/mozharness/scripts/b2g_build.py
+++ b/testing/mozharness/scripts/b2g_build.py
@@ -535,16 +535,17 @@ class B2GBuild(LocalesMixin, PurgeMixin,
                 cmd.append('-j{0}'.format(multiprocessing.cpu_count()))
             cmd.append(target)
         return cmd
 
     def build(self):
         dirs = self.query_abs_dirs()
         gecko_config = self.load_gecko_config()
         build_targets = gecko_config.get('build_targets', [])
+        build_targets.extend(self.config.get("build_targets", []))
         if not build_targets:
             cmds = [self.generate_build_command()]
         else:
             cmds = [self.generate_build_command(t) for t in build_targets]
         env = self.query_build_env()
         if self.config.get('gaia_languages_file'):
             env['LOCALE_BASEDIR'] = dirs['gaia_l10n_base_dir']
             env['LOCALES_FILE'] = os.path.join(dirs['abs_work_dir'], 'gaia', self.config['gaia_languages_file'])
--- a/testing/mozharness/scripts/desktop_l10n.py
+++ b/testing/mozharness/scripts/desktop_l10n.py
@@ -1295,22 +1295,28 @@ class DesktopSingleLocale(LocalesMixin, 
                     pgc_files.append(os.path.join(dirpath, pgc))
         return pgc_files
 
     # TODO: replace with ToolToolMixin
     def _get_tooltool_auth_file(self):
         # set the default authentication file based on platform; this
         # corresponds to where puppet puts the token
         if 'tooltool_authentication_file' in self.config:
-            return self.config['tooltool_authentication_file']
+            fn = self.config['tooltool_authentication_file']
+        elif self._is_windows():
+            fn = r'c:\builds\relengapi.tok'
+        else:
+            fn = '/builds/relengapi.tok'
 
-        if self._is_windows():
-            return r'c:\builds\relengapi.tok'
-        else:
-            return '/builds/relengapi.tok'
+        # if the file doesn't exist, don't pass it to tooltool (it will just
+        # fail).  In taskcluster, this will work OK as the relengapi-proxy will
+        # take care of auth.  Everywhere else, we'll get auth failures if
+        # necessary.
+        if os.path.exists(fn):
+            return fn
 
     def _run_tooltool(self):
         config = self.config
         dirs = self.query_abs_dirs()
         if not config.get('tooltool_manifest_src'):
             return self.warning(ERROR_MSGS['tooltool_manifest_undetermined'])
         fetch_script_path = os.path.join(dirs['abs_tools_dir'],
                                          'scripts/tooltool/tooltool_wrapper.sh')
@@ -1319,17 +1325,19 @@ class DesktopSingleLocale(LocalesMixin, 
         cmd = [
             'sh',
             fetch_script_path,
             tooltool_manifest_path,
             config['tooltool_url'],
             config['tooltool_bootstrap'],
         ]
         cmd.extend(config['tooltool_script'])
-        cmd.extend(['--authentication-file', self._get_tooltool_auth_file()])
+        auth_file = self._get_tooltool_auth_file()
+        if auth_file and os.path.exists(auth_file):
+            cmd.extend(['--authentication-file', auth_file])
         self.info(str(cmd))
         self.run_command(cmd, cwd=dirs['abs_mozilla_dir'], halt_on_failure=True)
 
     def _create_base_dirs(self):
         config = self.config
         dirs = self.query_abs_dirs()
         for make_dir in config.get('make_dirs', []):
             dirname = os.path.join(dirs['abs_objdir'], make_dir)
--- a/testing/mozharness/scripts/firefox_ui_updates.py
+++ b/testing/mozharness/scripts/firefox_ui_updates.py
@@ -335,16 +335,13 @@ class FirefoxUIUpdates(FirefoxUITests):
                                   '--determine-testing-configuration --run-tests '
                                   % (self.firefox_ui_branch, self.updates_config_file, self.tools_tag, url))
                         self.info('If you want to run this on your development machine:')
                         self.info('python scripts/firefox_ui_updates.py '
                                   '--firefox-ui-branch %s --update-verify-config %s '
                                   '--tools-tag %s --installer-url %s '
                                   '--cfg developer_config.py '
                                   % (self.firefox_ui_branch, self.updates_config_file, self.tools_tag, url))
-                        self.info('python scripts/firefox_ui_updates.py --cfg developer_config.py '
-                                  '--installer-url %s --update-channel %s --firefox-ui-branch %s'
-                                  % (url, self.channel, self.firefox_ui_branch))
 
 
 if __name__ == '__main__':
     myScript = FirefoxUIUpdates()
     myScript.run_and_exit()
--- a/testing/mozharness/scripts/merge_day/gecko_migration.py
+++ b/testing/mozharness/scripts/merge_day/gecko_migration.py
@@ -362,18 +362,17 @@ class GeckoMigration(MercurialScript, Ba
             self.run_command(
                 hg + ["revert", "-r", end_tag, f],
                 cwd=dirs['abs_to_dir'],
                 error_list=HgErrorList,
                 halt_on_failure=True,
             )
         next_ma_version = self.get_fx_major_version(dirs['abs_to_dir'])
         self.bump_version(dirs['abs_to_dir'], next_ma_version, next_ma_version, "a1", "a2")
-        for f, from_, to in self.config["replacements"]:
-            self.replace(os.path.join(dirs['abs_to_dir'], f), from_, to)
+        self.apply_replacements()
         # bump m-c version
         curr_mc_version = self.get_fx_major_version(dirs['abs_from_dir'])
         next_mc_version = str(int(curr_mc_version) + 1)
         self.bump_version(
             dirs['abs_from_dir'], curr_mc_version, next_mc_version, "a1", "a1",
             bump_major=True
         )
         # touch clobber files
@@ -386,34 +385,17 @@ class GeckoMigration(MercurialScript, Ba
             We could have all of these individually toggled by flags, but
             by separating into workflow methods we can be more precise about
             what happens in each workflow, while allowing for things like
             staging beta user repo migrations.
             """
         dirs = self.query_abs_dirs()
         mb_version = self.get_fx_major_version(dirs['abs_to_dir'])
         self.bump_version(dirs['abs_to_dir'], mb_version, mb_version, "a2", "")
-        self.replace(
-            os.path.join(dirs['abs_to_dir'], "browser/confvars.sh"),
-            "MOZ_BRANDING_DIRECTORY=browser/branding/aurora",
-            "MOZ_BRANDING_DIRECTORY=browser/branding/nightly")
-        self.replace(
-            os.path.join(dirs['abs_to_dir'], "browser/confvars.sh"),
-            "ACCEPTED_MAR_CHANNEL_IDS=firefox-mozilla-aurora",
-            "ACCEPTED_MAR_CHANNEL_IDS=firefox-mozilla-beta,firefox-mozilla-release")
-        self.replace(
-            os.path.join(dirs['abs_to_dir'], "browser/confvars.sh"),
-            "MAR_CHANNEL_ID=firefox-mozilla-aurora",
-            "MAR_CHANNEL_ID=firefox-mozilla-beta")
-        for d in self.config['branding_dirs']:
-            for f in self.config['branding_files']:
-                self.replace(
-                    os.path.join(dirs['abs_to_dir'], d, f),
-                    "ac_add_options --with-branding=mobile/android/branding/aurora",
-                    "ac_add_options --with-branding=mobile/android/branding/beta")
+        self.apply_replacements()
         self.touch_clobber_file(dirs['abs_to_dir'])
         # TODO mozconfig diffing
         # The build/tools version only checks the mozconfigs from hgweb, so
         # can't help pre-push.  The in-tree mozconfig diffing requires a mach
         # virtualenv to be installed.  If we want this sooner we can put this
         # in the push action; otherwise we may just wait until we have in-tree
         # mozconfig checking.
 
@@ -421,60 +403,39 @@ class GeckoMigration(MercurialScript, Ba
         """ mozilla-beta -> mozilla-release behavior.
 
             We could have all of these individually toggled by flags, but
             by separating into workflow methods we can be more precise about
             what happens in each workflow, while allowing for things like
             staging beta user repo migrations.
             """
         dirs = self.query_abs_dirs()
-        self.replace(
-            os.path.join(dirs['abs_to_dir'], "browser/confvars.sh"),
-            "ACCEPTED_MAR_CHANNEL_IDS=firefox-mozilla-beta,firefox-mozilla-release",
-            "ACCEPTED_MAR_CHANNEL_IDS=firefox-mozilla-release"
-        )
-        self.replace(
-            os.path.join(
-                dirs['abs_to_dir'], "browser/confvars.sh"),
-            "MAR_CHANNEL_ID=firefox-mozilla-beta",
-            "MAR_CHANNEL_ID=firefox-mozilla-release"
-        )
-        for d in self.config['branding_dirs']:
-            for f in self.config['branding_files']:
-                self.replace(
-                    os.path.join(dirs['abs_to_dir'], d, f),
-                    "ac_add_options --with-branding=mobile/android/branding/beta",
-                    "ac_add_options --with-branding=mobile/android/branding/official")
+        self.apply_replacements()
         if self.config.get("remove_locales"):
             self.remove_locales(
                 os.path.join(dirs['abs_to_dir'], "browser/locales/shipped-locales"),
                 self.config['remove_locales']
             )
         self.touch_clobber_file(dirs['abs_to_dir'])
 
     def release_to_esr(self, *args, **kwargs):
         """ mozilla-release -> mozilla-esrNN behavior. """
         dirs = self.query_abs_dirs()
         for to_transplant in self.config.get("transplant_patches", []):
             self.transplant(repo=to_transplant["repo"],
                             changeset=to_transplant["changeset"],
                             cwd=dirs['abs_to_dir'])
-        self.replace(
-            os.path.join(dirs['abs_to_dir'], "browser/confvars.sh"),
-            "ACCEPTED_MAR_CHANNEL_IDS=firefox-mozilla-release",
-            "ACCEPTED_MAR_CHANNEL_IDS=firefox-mozilla-esr"
-        )
-        self.replace(
-            os.path.join(
-                dirs['abs_to_dir'], "browser/confvars.sh"),
-            "MAR_CHANNEL_ID=firefox-mozilla-release",
-            "MAR_CHANNEL_ID=firefox-mozilla-esr"
-        )
+        self.apply_replacements()
         self.touch_clobber_file(dirs['abs_to_dir'])
 
+    def apply_replacements(self):
+        dirs = self.query_abs_dirs()
+        for f, from_, to in self.config["replacements"]:
+            self.replace(os.path.join(dirs['abs_to_dir'], f), from_, to)
+
     def transplant(self, repo, changeset, cwd):
         """Transplant a Mercurial changeset from a remote repository."""
         hg = self.query_exe("hg", return_type="list")
         cmd = hg + ["--config", "extensions.transplant=", "transplant",
                     "--source", repo, changeset]
         self.info("Transplanting %s from %s" % (changeset, repo))
         status = self.run_command(
             cmd,