Skip to content

Instantly share code, notes, and snippets.

@patcon
Created June 15, 2012 21:56
Show Gist options
  • Save patcon/2938898 to your computer and use it in GitHub Desktop.
Save patcon/2938898 to your computer and use it in GitHub Desktop.
How to alter a drush make file on-the-fly for CI

Been thinking lately on continuous integration/delivery, and how we can have a project where everything required to build the site is in version control, but absolutely no more than necessary. In drupal-land, this is an install profile (with some extraneous data like snippets that will be appended to settings.php, but that's out of scope here).

So to really do continuous delivery right, we need to be able to rebuild a the site in 3 weeks exactly as we built it tonight. But this is tough while using a workflow like described for Drupal.org packaging, which is a great way to operate otherwise. Why is this tough? Because the build-[distro].make file, when written for an install profile that is a git repo, will only ever build the HEAD of a branch.

For example, something like this would normally be used to build the site:

core = 7.x
api = 2

projects[drupal][version] = 7.14

projects[projectname][type] = profile
projects[projectname][download][type] = git
projects[projectname][download][url] = [email protected]:myplanetdigital/projectname.git
projects[projectname][download][reference] = develop

See the problem here? The only way to have your CI system be able to re-deploy the site at any point is to manually include the commit hash of the current commit in that commit itself. Which is impossible. You can't know the current commit until after you've committed it... But we do want this file in version control so that everything we need to build the site is in the repo.

So here's the trick: You can script it so that your CI system rewrites the build-projectname.make file on the fly, substituting in the commit hash in question after cloning the repo to get the proper build-projectname.make that you want to run (potentially to build a site that's 2 weeks old.

Here's the example of the approach, although it does the substitute on core, so that you can test it on your local system:

$ mkdir /tmp/drush-make-test
$ cd drush-make-test
$ # Write simple makefile to disk
$ cat << EOH >> test.make
core = 7.x
api = 2

projects[drupal][version] = 7.14
EOH
$ cat test.make | sed 's/7\.14/7.13/g' | drush make php://stdin .
>>> Project information for drupal retrieved.
>>> drupal downloaded from http://ftp.drupal.org/files/projects/drupal-7.13.tar.gz.
$ head -2 CHANGELOG.txt
>>>
>>> Drupal 7.13 2012-05-02
>>> ======================
$

So as you can see, since jenkins knows the hash of the commit you just cloned, you can keep a build script in that install profile with something like this:

#!/bin/sh
set -e

cat ${WORKSPACE}/profile/build-projectname.make | sed 's/develop/${GIT_COMMIT}/g' | drush make php://stdin ${WORKSPACE}/build

And now, regardless of which git reference you use for your job to start, you'll be building that site. So someone can click a button to build a given past version of the site for your QA environment, and it will build that site and deploy it with a separate deploy script (also version-controlled, by the way).

@patcon
Copy link
Author

patcon commented Jun 15, 2012

Can also use sed to substitute out a TOKEN (like for a commit hash or branch name on git repos :) )

EDIT: expanded to demostrate this

@patcon
Copy link
Author

patcon commented Jun 29, 2012

Updated to accomodate a later problem that was resolved regarding running drush on /dev/stdin:
https://gist.github.com/3014293

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment