Bug 1154796 - update gecko tree copy of Mozharness to 43f7600b8c80, CLOSED TREE r=mshal
authorJordan Lund <jlund@mozilla.com>
Wed, 08 Jul 2015 10:44:58 -0700
changeset 276342 e25de9972a7779490fcab6a522a6a808211f1c3d
parent 276288 9b902b7669aec048987e332161215b42514a0dfb
child 276343 9b10bbcb2307fb69e8c72acebba8e0d5a8b03a0e
child 276349 2469f45c4770ee66a5c0a3e7c6e27fb73c6e6ee6
push id3308
push userj.parkouss@gmail.com
push dateWed, 08 Jul 2015 18:18:20 +0000
reviewersmshal
bugs1154796
milestone42.0a1
Bug 1154796 - update gecko tree copy of Mozharness to 43f7600b8c80, CLOSED TREE r=mshal
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,