A DrupalSquad WF Favorite: Features-based Drupal development workflow

A pretty well known issue with Drupal-based products development/support is that if there are more than one developer working on the project, you have to keep an extra eye on how new features or bug-fixes are being deployed across environments – be it DEV instances, or DEV to TEST/PROD deployment.

Code-only based solutions are out of scope here – source code control software like SVN, Git, Mercurial (for those of you who are geeks) are available and considered a standard tool to manage changes in your code. However, if you choose a development path that involves stuff being configured through Drupal's admin UI (which is not bad at all – I know people who can build a site of any complexity using Views/Rules/Panels) – managing those changes can easily become a nightmare. That means you have to control code AND db changes (yeah, tons of checkboxes you are used to clicking on while configuring the site go directly to the database in most cases).

Drupal ninjas of level 6 or 7 (based on this classification) would argue that there isn't an issue here at all – but unfortunately, not every Drupal developer is born with Drupal API and variables storage knowledge built-in. Reality is that most of the Drupal projects involve people of different skills and skillsets. In many cases it's efficient just to build the main functionality using configuration options offered by Drupal core and contrib modules – then add custom glue code to the areas not covered by modules (guess where you spend 80% of dev time).

That means that you need to exchange code and configs (yeah, stored in DB) between your developers. For example: one developer (Developer 1) has configured Commerce products. Then, another developer (Developer 2) needs to start working on the Rules that trigger some specific actions for some product types setup by Developer 1. Developer 1 needs to somehow pass configuration of the Products to Developer 2. Code is being transferred through Git repository and Developer 2 is happy having all modules necessary for Commerce to work (they came with code). But hey, where are those Products?

The situation becomes more complicated once you get into a geographically world-wide distributed project team – meaning you can't just go to your colleague's desk and ask where the hell that data subset is coming from to the Views field output.

There are a couple of ways to handle DB changes transfers:

  1. Plain old MySQL dump (don't tell anyone you have PHPMyadmin enabled on PROD).

    Simple solutions usually are the most reliable, but is not the case here. Just imagine: Dev1 finished working on Products, dumped DB and sent the dump to Dev2. While Dev2 imported the dump and is working on Rules, Dev1 needs to start some Views configurations. Dev1 creates beautiful complex-performance-optimized-properly-named Views and realizes that there are VBOs that should trigger Rules components. Rules are created by Dev2, you remember? Dev2 is super-fast with Rules – he dumps his DB and sends it to Dev1. Dev1 imports DB dump that contains new Rules and realizes that now he doesn't have his master-crafted Views. Dev1 is a smart experienced Drupal site-builder, so he did an export of his Views before importing dump from Dev2 – so now he just needs to re-import them. I have already lost track of all those moves while writing this – shouldn't there be easier example? Easier solution, definitely. Stay tuned.

  2. Backup Migrate module. Great tool to backup your Drupal sites – and as (not only) we discovered, to migrate configs. Simple and obvious solution – since configs are mostly stored in DB, why not to try to identify the tables affected by specific functionality and just pull/push backup files created by this module with your favorite SCM tool. Add Drush support on top, and seems you are all covered. One thing that keeps us from declaring it as main deployment tool – it misses diff functionality. Git diff of DB dump is not that readable – remember, we are talking about a mixed-skillset team.

  3. Ctools-based exportables and similar (StrongArm, UUID...). Basically all major contrib modules (and even theme frameworks) support exporting their configs as files that can be imported into other Drupal instance (and our friend Views guru Dev1 just used it in item 1 above). Since exported files are PHP arrays/objects with syntax readable by (almost) humans, and there is a solid Drush support around, why wouldn't I stop adding items to this list and just finally describe how Ctools-based deployment process could look like for those 3 of you still reading this post? Well, there are 2 reasons. Usually, new features (oops, almost a spoiler!) include exportables of more than one type – meaning some additional layer is needed that keeps them organized in the way major pieces of functionality dictate – kind of meta-mega-module. Which is already written for you (yet another spoiler). Other missing piece here is dependencies tracking – you don't want to import config for the module that is relying on another config missing at target instance. Well, I admit, I am too picky here.

  4. So, here comes this post's winner: Features module. As spoiled above, it basically relies on Ctools-like exportable config files. It allows you to select components of your Drupal setup you need to control and save them as single module (yeah, even with .info and .module files) – all through nice UI for those who haven't progress yet far enough to familiarize with Drush command line interface.

  • Since it's a Drupal module, you get all the dependencies tracking in place.
  • Since it's a CUSTOM Drupal module, you can add your code to it.
  • Since Feature module has UI, you can create/update and REVERT your configs from Drupal's admin area.
  • Since resulting Drupal module is just a set of files, you get all the benefits of source code management software.
  • Features module supports everything that is Ctools-based natively – means you can start using it for Views/Contexts/Panels/Rules migrations/deployment right away. Not to mention standard Drupal 7 entities and APIs – fields, content types, taxonomy vocabularies, user roles and permissions, image styles, menus – all supported out of the box.
  • Many contrib modules maintainers did a favor to community and added Features support to their modules – so you will be able to easily move around configs for Field Groups, File (and other) Entities, WYSIWYG profiles and many others. Drupal variables storage is covered by great module called Strongarm – which also has Features support (simple example – control comments settings for the node types). If you need to keep track of changes done to specific CONTENT (nodes, terms, etc) – Features integrates with UUID perfectly (well, there are some kinks around file fields – but manageable). If your themer is big fan of Omega and Delta – just show her how great site layouts can be controlled by Feature through Delta/Context configs.
  • Did I mention Features can be created/updated/reverted through Drush?


So, let's pretend I've convinced you that Features is a great tool to manage Drupal configs. But what's the price?

Well, nothing is cheap nowadays (besides hosting plans at $4.99/month).

  1. First of all, the dev team will have to learn – both example devs used to Drupal's admin UI and code junkies. Using Features might also affect the way you handle page layouts – front end team will have to get familiar with all kinds of Deltas, Contexts, Panels (I assume they are already, but who knows, who knows) and Drush.

  2. Someone will have to take responsibility and split the site's functionality into logical chunks (hey, are you that lucky team lead who has an experienced BA on board?) that translate into Drupal's entities and logic of their interactions (yeah, Rules). Based on those chunks (or in progress of their development) main Features will need to be created.

  3. Sometimes it might be confusing to properly identify dependencies between project-specific features/configs (you won't need to think about core/contrib modules dependencies – Features will identify them automatically).

  4. Features will impact your site's performance – you MUST have opcode caching solutions installed on all instances (that's why you will have to forget about hosting at $4.99/month).

  5. There is a Features Tools module that was partially leveraging (at least for production sites) performance hit by making Features work in one direction – once imported, configs were stored to DB and read by Drupal from there as it normally happens – however, it doesn't work with latest 2.x branch of Features. Hope this functionality will be added to Features some day.

  6. Features do not cover everything out of the box – there might be some time needed to identify additional Features plugins for specific contrib modules and Drupal configurations or even write them.

So, to summarize: Features is a great configurations management tool for multi-skilled Drupal project teams and might be worth checking if you are looking into optimize and unify your deployment processes as your (or your clients) projects grow. It works great (and actually, is only useful) with tools like Git and Drush, and can be integrated into more sophisticated Jenkins/Capistrano/etc deployment workflows.

Still interested? Stay tuned for the next chapter - we will uncover some real-life examples of Features-based configurations deployment in next tech blog post.

Have questions? If you can't find answers at Features project page (https://drupal.org/project/features) – find us on Twitter @DrupalSquad – our dev team will be glad to help.