diff --git a/.travis.yml b/.travis.yml
index 027e660059b749b1a90cfd203db390c266c7d179..1561ed344159949574b5ea5fcfafe2b60328df1b 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -18,6 +18,10 @@ branches:
 # The following enables several GHC versions to be tested; often it's enough to
 # test only against the last release in a major GHC version. Feel free to omit
 # lines listings versions you don't need/want testing for.
+#
+# NB: If you test the same GHC version/OS combo multiple times with
+# SCRIPT=script (e.g., see PARSEC=YES below), you MUST supply a
+# TAGSUFFIX to help travis/upload.sh disambiguate the matrix entry.
 matrix:
   include:
    - env: GHCVER=8.0.1 SCRIPT=meta BUILDER=none
@@ -44,10 +48,11 @@ matrix:
    - env: GHCVER=8.0.1 SCRIPT=script DEPLOY_DOCS=YES
      sudo: required
      os: linux
+
    - env: GHCVER=8.0.1 SCRIPT=solver-debug-flags
      sudo: required
      os: linux
-   - env: GHCVER=8.0.1 SCRIPT=script PARSEC=YES
+   - env: GHCVER=8.0.1 SCRIPT=script PARSEC=YES TAGSUFFIX="-parsec"
      os: linux
      sudo: required
    - env: GHCVER=8.0.1 SCRIPT=bootstrap
@@ -59,6 +64,7 @@ matrix:
    # https://ghc.haskell.org/trac/ghc/ticket/8493
    - env: GHCVER=7.8.4 SCRIPT=script
      os: osx
+     # Keep this synced with travis/upload.sh
      osx_image: xcode6.4 # We need 10.10
 
    # TODO: We might want to specify OSX version
@@ -111,6 +117,7 @@ install:
 # ./dist/setup/setup here instead of cabal-install to avoid breakage when the
 # build config format changed.
 script:
+ - rm -rf dist-newstyle
  - ./travis-${SCRIPT}.sh -j1
 
 cache:
@@ -131,6 +138,7 @@ cache:
 before_cache:
  - rm -fv $HOME/.cabal/packages/hackage.haskell.org/build-reports.log
  - rm -fv $HOME/.cabal/packages/hackage.haskell.org/00-index*
+ - rm -fv $HOME/.cabal/packages/hackage.haskell.org/01-index*
  - rm -fv $HOME/.cabal/packages/hackage.haskell.org/*.json
 
 # Deploy Haddocks to the haskell/cabal-website repo.
diff --git a/travis-script.sh b/travis-script.sh
index 9ef59616f4c071773755ec5d64bb0afd14ac465d..ea563409e04eb108bb03d87a1698768e588cbc6d 100755
--- a/travis-script.sh
+++ b/travis-script.sh
@@ -107,21 +107,6 @@ if [ "x$CABAL_INSTALL_ONLY" != "xYES" ] ; then
       timed cabal new-build $jobs Cabal Cabal:unit-tests
     fi
 
-    # NB: the '|| exit $?' workaround is required on old broken versions of bash
-    # that ship with OS X. See https://github.com/haskell/cabal/pull/3624 and
-    # http://stackoverflow.com/questions/14970663/why-doesnt-bash-flag-e-exit-when-a-subshell-fails
-
-    # Run tests
-    (cd Cabal && timed ${CABAL_BDIR}/build/unit-tests/unit-tests       $TEST_OPTIONS) || exit $?
-
-    if [ "x$PARSEC" = "xYES" ]; then
-        # Parser unit tests
-        (cd Cabal && timed ${CABAL_BDIR}/build/parser-tests/parser-tests $TEST_OPTIONS) || exit $?
-
-        # Test we can parse Hackage
-        (cd Cabal && timed ${CABAL_BDIR}/build/parser-tests/parser-hackage-tests $TEST_OPTIONS) | tail || exit $?
-    fi
-
     # Run haddock
     (cd Cabal && timed cabal act-as-setup --build-type=Simple -- haddock --builddir=${CABAL_BDIR}) || exit $?
 
@@ -139,25 +124,11 @@ export CABAL_BUILDDIR="${CABAL_TESTSUITE_BDIR}"
 # both by Cabal and cabal-install
 timed cabal new-build $jobs cabal-testsuite:cabal-tests
 
-if [ "x$CABAL_INSTALL_ONLY" != "xYES" ] ; then
-    # We're doing a full build and test of Cabal
-
-    (cd cabal-testsuite && timed ${CABAL_TESTSUITE_BDIR}/build/cabal-tests/cabal-tests -j3 $TEST_OPTIONS) || exit $?
-
-    # Redo the package tests with different versions of GHC
-    if [ "x$TEST_OTHER_VERSIONS" = "xYES" ]; then
-        (export CABAL_PACKAGETESTS_WITH_GHC="/opt/ghc/7.0.4/bin/ghc"; \
-            cd cabal-testsuite && timed ${CABAL_TESTSUITE_BDIR}/build/cabal-tests/cabal-tests $TEST_OPTIONS)
-        (export CABAL_PACKAGETESTS_WITH_GHC="/opt/ghc/7.2.2/bin/ghc"; \
-            cd cabal-testsuite && timed ${CABAL_TESTSUITE_BDIR}/build/cabal-tests/cabal-tests $TEST_OPTIONS)
-        (export CABAL_PACKAGETESTS_WITH_GHC="/opt/ghc/head/bin/ghc"; \
-            cd cabal-testsuite && timed ${CABAL_TESTSUITE_BDIR}/build/cabal-tests/cabal-tests $TEST_OPTIONS)
-    fi
-fi
-
 unset CABAL_BUILDDIR
 
 if [ "x$CABAL_LIB_ONLY" = "xYES" ]; then
+    # If this fails, we WANT to fail, because the tests will not be running then
+    (timed ./travis/upload.sh) || exit $?
     exit 0;
 fi
 
@@ -175,22 +146,8 @@ timed cabal new-build $jobs cabal-install:cabal \
                       cabal-install:solver-quickcheck \
                       cabal-install:memory-usage-tests
 
-# The integration-tests2 need the hackage index, and need it in the secure
-# format, which is not necessarily the default format of the bootstrap cabal.
-# If the format does match then this will be very quick.
-timed ${CABAL_INSTALL_BDIR}/build/cabal/cabal update
-
-# Run tests
-(cd cabal-install && timed ${CABAL_INSTALL_BDIR}/build/unit-tests/unit-tests         $TEST_OPTIONS) || exit $?
-(cd cabal-install && timed ${CABAL_INSTALL_BDIR}/build/solver-quickcheck/solver-quickcheck  $TEST_OPTIONS --quickcheck-tests=1000) || exit $?
-(cd cabal-install && timed ${CABAL_INSTALL_BDIR}/build/integration-tests/integration-tests  $TEST_OPTIONS) || exit $?
-(cd cabal-install && timed ${CABAL_INSTALL_BDIR}/build/integration-tests2/integration-tests2 $TEST_OPTIONS) || exit $?
-(cd cabal-install && timed ${CABAL_INSTALL_BDIR}/build/memory-usage-tests/memory-usage-tests $TEST_OPTIONS) || exit $?
-
 timed cabal new-build $jobs hackage-repo-tool
 
-(cd cabal-testsuite && timed ${CABAL_TESTSUITE_BDIR}/build/cabal-tests/cabal-tests -j3 --skip-setup-tests --with-cabal ${CABAL_INSTALL_BDIR}/build/cabal/cabal --with-hackage-repo-tool ${HACKAGE_REPO_TOOL_BDIR}/build/hackage-repo-tool/hackage-repo-tool $TEST_OPTIONS) || exit $?
-
 # Haddock
 (cd cabal-install && timed ${CABAL_INSTALL_SETUP} haddock --builddir=${CABAL_INSTALL_BDIR} ) || exit $?
 
@@ -200,3 +157,6 @@ unset CABAL_BUILDDIR
 
 # Check what we got
 ${CABAL_INSTALL_BDIR}/build/cabal/cabal --version
+
+# If this fails, we WANT to fail, because the tests will not be running then
+(timed ./travis/upload.sh) || exit $?
diff --git a/travis/README.md b/travis/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..3f09df3734ba188642b2721d9bf7ab8d6915c41b
--- /dev/null
+++ b/travis/README.md
@@ -0,0 +1,81 @@
+# Continuous integration on Travis
+
+This folder contains scripts for running CI on Travis.
+
+The most unusual thing about our Travis setup is that, after we finish
+building our project, we upload the build products to Git (via the
+haskell-pushbot account) to a separate repository to do testing.
+There are two reasons we do this:
+
+1. On our slowest configuration (GHC 8 on Mac OS X), the time to
+   build and run tests was easily bumping up against the Travis time
+   limit.  By uploading our build products to a separate account
+
+2. Travis parallelism is limited on a per-account basis; if we
+   upload build products to another account, we get more parallelism!
+   (Travis, let us know if you don't like this :)
+
+Here is the general lifecycle of a Travis run:
+
+1. For each build matrix configuration, we run ../travis-script.sh
+   to build Cabal, cabal-install, and all of the test suites.
+
+2. Once the build is successful, we invoke upload.sh to upload
+   the build products to the cabal-binaries repository.  This is done
+   using the private key id_rsa (associated with haskell-pushbot's
+   account).  This upload contains its own .travis.yml (customized
+   for the particular build matrix configuration), and some special
+   JSON metadata in the commit message.
+
+3. Triggered by the push to cabal-binaries, Travis on haskell-pushbot
+   will run the tests.  After this finishes, it will invoke a webhook
+   that invokes sake-bot (https://github.com/ezyang/sake-bot, currently
+   installed at https://sake-bot.herokuapp.com/) which will post
+   back the GitHub status result to the upstream Cabal repository.
+
+## Who maintains this setup
+
+Unfortunately, there are some infrastructural permissions which
+don't coincide with the GitHub permissions for the Cabal project.
+Here are the relevant bits:
+
+* The GitHub account haskell-pushbot is owned by @ezyang (along
+  with the associated Travis account.)
+
+* The Heroku instance https://sake-bot.herokuapp.com/ is maintained by @ezyang.
+  It has a private key for a GitHub integration on the Haskell
+  GitHub organization (which gives it permissions to update
+  statuses on the Cabal project).
+
+Fortunately, if @ezyang ever gets run over a bus, all of these
+infrastructural bits can be reconfigured.  Here is what you
+would need to do:
+
+* Create a new GitHub account to replace haskell-pushbot
+
+* Generate a new private key, associate it with the GH account, and
+  replace id_rsa and id_rsa.pub with the new account
+
+* Create a new binaries repository, modify the invocation of
+  "git remote add" in upload.sh to point to the new location.
+  Enable Travis for this repository.
+
+* Create a new Heroku instance of https://github.com/ezyang/sake-bot
+  (use the "Deploy with Heroku" button.)  Follow the instructions
+  there; you'll need a private key for an integration associated
+  with the Haskell organization; talk to one of the admins there
+  to get the key.
+
+That's it!
+
+## Limitations
+
+If you push to your local account and run Travis, the builds will
+still take place in the shared cabal-binaries Travis instance, and
+you won't get status updates (because sake-bot doesn't have permissions
+to update the status update on any repository besides its own.)
+In principle, it should be possible for upload.sh to autodetect if you
+have a cabal-binaries repository setup on your local account, and use
+that instead, but as the sake-bot integration can only be installed
+on the same account it was created for, getting sake-bot setup would
+be annoyingly fiddly.  Shout if you need this to work.
diff --git a/travis/binaries/.travis.yml b/travis/binaries/.travis.yml
new file mode 100644
index 0000000000000000000000000000000000000000..5dca0a8630d5d638b44bab854049e30bed09060a
--- /dev/null
+++ b/travis/binaries/.travis.yml
@@ -0,0 +1,31 @@
+language: c
+# This doesn't actually help because we always push a single
+# commit to the branch in question
+#git:
+#    # https://github.com/travis-ci/travis-ci/issues/4575
+#    depth: 1
+sudo: required
+before_install:
+ - export PATH=/opt/ghc/$GHCVER/bin:$PATH
+ - export PATH=$HOME/.ghc-install/$GHCVER/bin:$PATH
+ - export PATH=$HOME/bin:$PATH
+ - export PATH=$HOME/.cabal/bin:$PATH
+ - export PATH=$HOME/.local/bin:$PATH
+ - export PATH=/opt/cabal/1.24/bin:$PATH
+ - export PATH=/opt/happy/1.19.5/bin:$PATH
+ - export PATH=/opt/alex/3.1.7/bin:$PATH
+ - ./travis-install.sh
+ - mv .cabal $HOME
+script:
+    - ./travis-test.sh
+notifications:
+  webhooks:
+    urls: https://sake-bot.herokuapp.com/
+    on_start: always
+  irc:
+    channels:
+      - "chat.freenode.net##haskell-cabal"
+  slack: haskell-cabal:sCq6GLfy9N8MJrInosg871n4
+# To append on:
+# env: GHCVER=7.6.3 UPSTREAM_BUILD_DIR=/home/travis/user/repo
+# os: linux
diff --git a/travis/binaries/travis-test.sh b/travis/binaries/travis-test.sh
new file mode 100755
index 0000000000000000000000000000000000000000..738dd27c08c87fea748ff6ae644e35f4536e476a
--- /dev/null
+++ b/travis/binaries/travis-test.sh
@@ -0,0 +1,70 @@
+#!/bin/sh
+
+. ./travis-common.sh
+
+CABAL_STORE_DB="${HOME}/.cabal/store/ghc-${GHCVER}/package.db"
+CABAL_LOCAL_DB="${PWD}/dist-newstyle/packagedb/ghc-${GHCVER}"
+CABAL_BDIR="${PWD}/dist-newstyle/build/Cabal-${CABAL_VERSION}"
+CABAL_TESTSUITE_BDIR="${PWD}/dist-newstyle/build/cabal-testsuite-${CABAL_VERSION}"
+CABAL_INSTALL_BDIR="${PWD}/dist-newstyle/build/cabal-install-${CABAL_VERSION}"
+CABAL_INSTALL_SETUP="${CABAL_INSTALL_BDIR}/setup/setup"
+HACKAGE_REPO_TOOL_BDIR="${PWD}/dist-newstyle/build/hackage-repo-tool-${HACKAGE_REPO_TOOL_VERSION}"
+# --hide-successes uses terminal control characters which mess up
+# Travis's log viewer.  So just print them all!
+TEST_OPTIONS=""
+
+# Setup symlink so that paths look the same
+mkdir -p $(dirname $UPSTREAM_BUILD_DIR)
+ln -s $TRAVIS_BUILD_DIR $UPSTREAM_BUILD_DIR
+
+# Touch package database cache files, so we don't complain they're
+# stale (Git doesn't preserve modification times, so we'll end
+# up with something wrong.)
+touch "$CABAL_STORE_DB/package.cache"
+touch "$CABAL_LOCAL_DB/package.cache"
+
+# Run tests
+(timed ${CABAL_BDIR}/build/unit-tests/unit-tests $TEST_OPTIONS) || exit $?
+
+   if [ "x$PARSEC" = "xYES" ]; then
+       # Parser unit tests
+       (cd Cabal && timed ${CABAL_BDIR}/build/parser-tests/parser-tests $TEST_OPTIONS) || exit $?
+
+       # Test we can parse Hackage
+       (cd Cabal && timed ${CABAL_BDIR}/build/parser-tests/parser-hackage-tests $TEST_OPTIONS) | tail || exit $?
+   fi
+
+(cd cabal-testsuite && timed ${CABAL_TESTSUITE_BDIR}/build/cabal-tests/cabal-tests --builddir=${CABAL_TESTSUITE_BDIR} -j3 $TEST_OPTIONS) || exit $?
+
+# Redo the package tests with different versions of GHC
+if [ "x$TEST_OTHER_VERSIONS" = "xYES" ]; then
+    (export CABAL_PACKAGETESTS_WITH_GHC="/opt/ghc/7.0.4/bin/ghc"; \
+        cd cabal-testsuite && timed ${CABAL_TESTSUITE_BDIR}/build/cabal-tests/cabal-tests --builddir=${CABAL_TESTSUITE_BDIR} $TEST_OPTIONS)
+    (export CABAL_PACKAGETESTS_WITH_GHC="/opt/ghc/7.2.2/bin/ghc"; \
+        cd cabal-testsuite && timed ${CABAL_TESTSUITE_BDIR}/build/cabal-tests/cabal-tests --builddir=${CABAL_TESTSUITE_BDIR} $TEST_OPTIONS)
+    (export CABAL_PACKAGETESTS_WITH_GHC="/opt/ghc/head/bin/ghc"; \
+        cd cabal-testsuite && timed ${CABAL_TESTSUITE_BDIR}/build/cabal-tests/cabal-tests --builddir=${CABAL_TESTSUITE_BDIR} $TEST_OPTIONS)
+fi
+
+if [ "x$CABAL_LIB_ONLY" = "xYES" ]; then
+    exit 0;
+fi
+
+# ---------------------------------------------------------------------
+# cabal-install
+# ---------------------------------------------------------------------
+
+# Update index
+(timed ${CABAL_INSTALL_BDIR}/build/cabal/cabal update) || exit $?
+
+# Run tests
+(timed ${CABAL_INSTALL_BDIR}/build/unit-tests/unit-tests         $TEST_OPTIONS) || exit $?
+(cd cabal-install && timed ${CABAL_INSTALL_BDIR}/build/solver-quickcheck/solver-quickcheck  $TEST_OPTIONS --quickcheck-tests=1000) || exit $?
+(timed ${CABAL_INSTALL_BDIR}/build/memory-usage-tests/memory-usage-tests $TEST_OPTIONS) || exit $?
+
+# These need the cabal-install directory
+(cd cabal-install && timed ${CABAL_INSTALL_BDIR}/build/integration-tests/integration-tests  $TEST_OPTIONS) || exit $?
+(cd cabal-install && timed ${CABAL_INSTALL_BDIR}/build/integration-tests2/integration-tests2 $TEST_OPTIONS) || exit $?
+
+# Big tests
+(cd cabal-testsuite && timed ${CABAL_TESTSUITE_BDIR}/build/cabal-tests/cabal-tests --builddir=${CABAL_TESTSUITE_BDIR} -j3 --skip-setup-tests --with-cabal ${CABAL_INSTALL_BDIR}/build/cabal/cabal --with-hackage-repo-tool ${HACKAGE_REPO_TOOL_BDIR}/build/hackage-repo-tool/hackage-repo-tool $TEST_OPTIONS) || exit $?
diff --git a/travis/id_rsa b/travis/id_rsa
new file mode 100644
index 0000000000000000000000000000000000000000..f625d6369e449df6d0bd6582e935695419ff5a3b
--- /dev/null
+++ b/travis/id_rsa
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEAwyBagHDRv7lqPz0Jus26XmLa9erl29MAT2ns2LURbszqhP6v
+KW5bp0bYeCrBOhUUq14tNpI/5xDnHdt1GJGztiLzTu9FLy7gts4xmkYlkiAJeUkg
+RGUeWDU0oK6Df5jkxu0N+tYcxMFMZLi1Nmm4ISGpYPHvfAPwRDRAojFZBFFI1vYO
+4awyz5X6DaMHu/D+TSTHDBzNDtq2oCWtDT1hh2Bhtxw5ZGeujlEXWLkp9eoA/TU/
+RBWL4s2xAot81iEWNN5xhFijlt2RsBLpqTj+TcEpvU9xMXYkQFpyqPJzxMsjHo4i
+50qnZdKQXeZJd/ZmIiAt4B4/tlSLz6RUmfSQfwIDAQABAoIBAQCXlrD4i61Hx2IV
+UvQWHfGlliMJXb3JM3lQOLh5+uFaNPQU8k9eXo/xuoY9hOmsl+gA4h86ABCJEIac
+mXu05Ky62RgwwI39A+wr2LCMa+aQSTdS9E6PFAeo+1yxYCJkpIFHUa7EqkabTJhu
+v1h4t1UG2EHgQNSOgfjM49M6rh+7y5b8NDH/67y0ygdaXQAlqPOxmllKAKJWKrCd
+zsrhaZXezPljblzGQpaV0+EhGGbrrqaos+kdraZcYXqo++sGEnITg2ElCHtGf0/0
+h1yr1PtNeLvhC0w/3piZnA58ls8OmXy0erVi9Pj1LLGEbeuFSz81+6SpmORgx1Kd
+4jazO1mxAoGBAOM2SXvmqS+8CCI3u52I9bbkE4keIM54tzFLNHWQknVHQn04GGxC
+lXjjcTyLNW2rT04RfGs2tXSse3sgEg1x/4uqo/kJvdZAAG9vUlWNukzqEVawVu84
+AJhhqWQWGSdOhnOS7G2aXjdrTfIvlvwjuUBii4s0fRw6QE0s5vpVyNh9AoGBANvZ
+WtYnuQuzsedhZDB0Chrg/z83DYpxlubDeP3iWnT7eBXes1nTLM0r9AChFCbyX6Ml
+Wd5phCbjvZrtQG04E90xHQNFq77F5q9U8D0gJIDi3fcktRrP9pCQqZhCbuLTKhxa
+eFFS3W8c7pivQLsdwr29wZK+yegN6ksZax7OktmrAoGAewGw1rsRbR5G6P9zOt4i
+6FihmuIMsLr5sl4ckGksYQGrJU9xKWsCsOexLi3PRwgvbvxYd1Ku+fNHBmleXJkS
+1/IRw4lalNshYTLLSDXqXil6KYxeBDQ1XknBAsZT58vDTl6EUPH5f9c/45WQEADn
+EcxH750C/n0qwp1EjtJSYaECgYBTSZi8IPhdkooHWkIWiR9651pLnJOoqze73Lnt
+lN8oCkyIHIJduT7zy3747g0wZAoPSIsvU1IZWZXvJ4qM1f3Qgla3cqGJ+HdYXRlW
+TuMFYO0uP93MdpS2V9eoMyLHE7CUZUHHrVjuS0uo1Fv1h2TLdSPscBMVso/cO5j1
+ZtUDWQKBgQCrIdI4X25eQg7h9noZkOkv0puQQJ/g/+sE7DOL6van74dtVSbgahwu
+/7umITYSfvkEFfbck5m7Yvsaje1Mzj0skXX8tST80WrCYwJ3BCY+BYvHoYOjhPt/
+q3Ycs1SPZ0Ao7/NkTEnkv0+hIGb5K99UvvLNXTk83pYcS09i5TfXDA==
+-----END RSA PRIVATE KEY-----
diff --git a/travis/id_rsa.pub b/travis/id_rsa.pub
new file mode 100644
index 0000000000000000000000000000000000000000..91b0d6ca52e5d2d0a8ba4c984cc82d49056e27db
--- /dev/null
+++ b/travis/id_rsa.pub
@@ -0,0 +1 @@
+ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDDIFqAcNG/uWo/PQm6zbpeYtr16uXb0wBPaezYtRFuzOqE/q8pblunRth4KsE6FRSrXi02kj/nEOcd23UYkbO2IvNO70UvLuC2zjGaRiWSIAl5SSBEZR5YNTSgroN/mOTG7Q361hzEwUxkuLU2abghIalg8e98A/BENECiMVkEUUjW9g7hrDLPlfoNowe78P5NJMcMHM0O2ragJa0NPWGHYGG3HDlkZ66OURdYuSn16gD9NT9EFYvizbECi3zWIRY03nGEWKOW3ZGwEumpOP5NwSm9T3ExdiRAWnKo8nPEyyMejiLnSqdl0pBd5kl39mYiIC3gHj+2VIvPpFSZ9JB/ ezyang@sabre
diff --git a/travis/upload.sh b/travis/upload.sh
new file mode 100755
index 0000000000000000000000000000000000000000..f4c11b159c2e91c58dc59eb29630096ac52a5189
--- /dev/null
+++ b/travis/upload.sh
@@ -0,0 +1,72 @@
+#!/bin/sh
+
+set -x
+
+# Read out ACCOUNT and REPO from the slug
+# Cribbed from http://unix.stackexchange.com/a/53323/118117
+ACCOUNT=${TRAVIS_REPO_SLUG%%"/"*}
+REPO=${TRAVIS_REPO_SLUG#*"/"}
+
+# TAG will be used to uniquely identify a matrix entry; we
+# need to push each matrix entry to a separate branch.
+TAG="$TRAVIS_OS_NAME-$GHCVER$TAGSUFFIX"
+
+# This is the commit for which we want a GitHub status update
+# ping to go to.  Note that it is NOT TRAVIS_COMMIT unconditionally,
+# since if we have a pull request, this commit will be a merge
+# commit which no one from GitHub will be able to see.
+COMMIT=${TRAVIS_PULL_REQUEST_SHA:-$TRAVIS_COMMIT}
+
+# Git will complain if these fields don't work when committing,
+# so set them up.
+git config --global user.name "Pushbot"
+git config --global user.email "pushbot@$(hostname)"
+git config --global push.default simple
+
+cd travis
+
+# Setup SSH key we will use to push to binaries repository
+cp id_rsa $HOME/.ssh/id_rsa
+chmod 0600 $HOME/.ssh/id_rsa
+
+# Setup SSH keys
+ssh-keyscan github.com >> $HOME/.ssh/known_hosts
+
+cd binaries
+
+# Setup binaries repository for pushing
+git init
+# TODO: Update this
+git remote add origin git@github.com:haskell-pushbot/cabal-binaries.git
+
+# Make some final modifications to .travis.yml based so
+# that downstream builds with the correct configuration
+echo "env: GHCVER=$GHCVER UPSTREAM_BUILD_DIR=$TRAVIS_BUILD_DIR CABAL_LIB_ONLY=$CABAL_LIB_ONLY TEST_OTHER_VERSIONS=$TEST_OTHER_VERSIONS PARSEC=$PARSEC" >> .travis.yml
+echo "os: $TRAVIS_OS_NAME" >> .travis.yml
+if [ "x$GHCVER" = "x7.8.4" ] && [ "x$TRAVIS_OS_NAME" = "xosx" ]; then
+    echo "osx_image: xcode6.4" >> .travis.yml
+fi
+
+# Install all of the necessary files for testing
+cp $TRAVIS_BUILD_DIR/travis-install.sh .
+cp $TRAVIS_BUILD_DIR/travis-common.sh .
+cp -R $HOME/.cabal .
+# Index files are too big for Git
+rm -fv .cabal/packages/hackage.haskell.org/00-index*
+rm -fv .cabal/packages/hackage.haskell.org/01-index*
+rm -fv .cabal/packages/hackage.haskell.org/*.json
+cp -R $TRAVIS_BUILD_DIR/dist-newstyle .
+# Test files for test suites that rely on them
+cp -R $TRAVIS_BUILD_DIR/cabal-testsuite .
+mkdir Cabal
+cp -R $TRAVIS_BUILD_DIR/Cabal/tests Cabal
+mkdir cabal-install
+cp -R $TRAVIS_BUILD_DIR/cabal-install/tests cabal-install
+
+# Add, commit, push
+git add .
+# The JSON in the commit message is used by the webhook listening
+# on the downstream repo to figure out who to communicate the
+# status update back to
+git commit -m '{"account":"'$ACCOUNT'", "repo":"'$REPO'", "commit": "'$COMMIT'", "tag":"'$TAG'"}'
+git push -f origin "HEAD:$TAG/$COMMIT"