Drush broke the build! But that's a good thing...

At work, we have a Jenkins server. I love the butler. One thing we use it for is making nightly snapshots of our distribution, Demo Framework. One cool feature of Jenkins is that I can tell it to email me when the build fails. (Of course, this always seems to happen on a Friday night!) Sometimes the build fails due to network errors, so when I received an email on Friday that the build broke, I didn't worry.

"If it breaks again tomorrow, I'll check on it," I said to myself. Well, it broke again tonight and this time it wasn't because of code that I had committed or network problems. Now my curiosity was peaked - I had to login to Jenkins and see why the build was failing. I quickly saw an error was being thrown before the build could even get rolling.

PHP Warning: require(/home/jenkins/jobs/workspace/demoframework-tarball/drush/vendor/autoload.php): failed to open stream: No such file or directory in /home/jenkins/jobs/workspace/demoframework-tarball/drush/includes/bootstrap.inc on line 1007

One unique feature of this particular build is that we pull down the latest HEAD of Drush to run drush make for packaging the distro. Now, yes, this is kind of crazy. The maintainers of Drush might cringe at this, but I don't mind being a guinea pig. This particular job has been running for the better part of a year and Friday was the first time it failed because of Drush. So I trust drush-ops won't commit bad code - but it doesn't mean they won't commit new "features" that break the build.

In order to debug why drush was no longer working, it was fairly easy to visit the drush commit log on github and look for commits from the day that the build broke. There were only 10 commits on this day, and I noticed that one commit had the message, "Fix #127. Fetch external libs with composer, and use Composer autoloader..."

This explained everything I needed to know. Composer is great and the fact that Drush is now using code from other PHP projects is double great. This is a pattern for Drupal starting in D8, so it only makes sense that Drush would do this.

It was a quick fix to add downloading and configuring Composer as a part of the build. (Ok, so it took a few test runs, but I got things working...) Here's what our current build looks like:

#!/bin/bash
 
echo "Building Demo Framework Nightly Snapshot"
rm -rf df_checkout
git clone --branch 7.x-1.x <a href="http://git.drupal.org/project/df.git">http://git.drupal.org/project/df.git</a> df_checkout
 
echo "Checkout Composer"
rm -rf composer
git clone <a href="mailto:git@github.com">git@github.com</a>:composer/composer composer
 
echo "Install Composer"
rm -rf composer.phar
wget <a href="http://getcomposer.org/composer.phar
cd">http://getcomposer.org/composer.phar
cd</a> composer && php ../composer.phar install
cd ..
 
echo "Checkout Drush"
rm -rf drush
git clone <a href="mailto:git@github.com">git@github.com</a>:drush-ops/drush.git drush
 
echo "Install Drush dependencies"
cd drush
php ../composer/bin/composer install
cd ..
chmod +x drush/drush
 
echo "Prepare output directory"
rm -rf build_df
mkdir build_df
 
echo "Run the build"
drush/drush make  --no-cache df_checkout/build-df.make --tar build_df/df_nightly_dev_snapshot_`date +%s` -d --concurrency=1

Originally, we were just checking out Drush and using it straight away. The new build requires downloading and installing Composer first. We then have to move into the checked out drush directory and run composer install to get the required autoloader. Then voilà - the build is upright once again.

Until next time, that is.

Submitted by brant on Sat, 02/08/2014 - 23:45