I’m not sure how widely this might be applicable but I’ve found it an interesting problem to think about and it’s going to help iron out some wrinkles in our workflow.
We have a standard platform that does a great deal of the scutwork required of a generic CMS based on Drupal. What’s included in it doesn’t really matter (it’s an install profile that does a bunch of stuff), just that it’s the base of many of our projects and it is maintained as a unit and upgraded as a whole on individual sites.
I currently maintain this using a bunch of git repos, a custom feature server (which uses
ssh tunnels to access the git repos),
drush make and about a dozen other moving parts which produce a new build of the platform in a tarball. Needless to say this is tedious, error prone, and means new releases are slower than they should be. Git to the rescue!
Rather than building tarballs of platform releases manually I’ll be maintaining canonical versions in repositories and using git to manage applying upgrades to individual projects.
Creating a platform
This first step is creating my “blessed” platform repository. To keep things simple I’ll describe managing two platforms:
6.xis the current release of Drupal 6; and
7.xis the current release of Drupal 7.
As this repo is somewhat special I’m going to take some pains to make sure it’s structured exactly as I want it. In particular, I want every branch to be correspond to one of my platforms. This is a little tricky but it only happens once so don’t worry too much if you find it confusing.
# Initialise a new empty repo and add the origin I'll push the result to mkdir platform cd platform git init git remote add origin git@gorilla:/platforms/drupal.git # First, let's create the Drupal 6 branch. git symbolic-ref HEAD refs/heads/6.x rm .git/index git clean -fdx drush dl --yes --drupal-project-rename=htdocs drupal-6 git add htdocs git commit -m 'drupal-6' git push origin 6.x # Now, let's take care of the Drupal 7 branch. git symbolic-ref HEAD refs/heads/7.x rm .git/index git clean -fdx drush dl --yes --drupal-project-rename=htdocs drupal-7 git add htdocs git commit -m 'drupal-7' git push origin 7.x
This sequence is a little verbose (the
git clean for Drupal 6 aren’t strictly necessary) but it should be obvious how I can add additional platforms.
Assuming that the repo at
git@gorilla:/platforms/drupal.git was newly
inited, it should now contain a
6.x branch containing Drupal 6 and a
7.x branch containing Drupal 7.
For safety’s sake, it’d probably be a good idea to have push restrictions on the platform repository to prevent accidental and illicit modifications flowing back from projects into platforms. It’s outside the scope of this document to describe how to do this but you probably want to use
gitolite or something else with fine-grained access control (i.e. not gitosis).
Starting a project
Now that my platforms are available in git I can use them as the starting point for a new project. I just clone the right branch from the platform repo and I’m off!
git clone --origin platform --branch 6.x git@gorilla:/platforms/drupal example.com cd example.com git checkout -b master
It’s a bit confusing at first glance, so I’ll break that down a bit. First I clone the platform repository with the
git clone command. Instead of letting it use default values I’m telling it what to call the origin remote in the new repository (
platform instead of
origin) and which branch to clone (
6.x instead of the default
HEAD in the remote). Running this command will create a new repository in
example.com/ with a remote called
platform and a single branch called
6.x (based on the
I recommend using the
6.x branch exclusively for pulling in new releases of the platform so I also create a
master branch to work on with the next git command does.
example.com has two branches:
6.x where I can pull in new releases of the platform, and
master where I’ll be working on the example.com site.
Upgrading a project
Upgrading a project to run on the latest version of it’s platform should be a simple matter of pulling the appropriate branch and merging the changes into
cd example.com git checkout 6.x git pull git checkout master git merge 6.x
Here I checkout the “platform” branch (
6.x as in the example above) and pull in any remote changes. Then I checkout the
master branch and merge the changes in the updated
Unless I’ve been a naughty boy and modified files that are “owned” by the platform this shouldn’t result in so much as a merge conflict.
I haven’t rolled this new method out at work yet but it’s in the pipeline. I’m quite excited by it and I think it’ll help make what’s currently tedious and error prone into something of a NOOP. Hopefully the rest of the team agrees!
Have you done something similar? Have I missed some serious consideration? Is this all old hat and I should get with the programme? I’d love to hear any comments or feedback on the approach I’ve described.