Keeping your Drupal Features in sync
This covers some best practice tips for automating your development processes using Features, updatedb and cloud hooks.
We use Features for putting db components into code in Drupal 7. Best practice will see any of your Features get updated as soon as the relevant component is modified on a development site. This ensures the codebase always has the latest version of the Feature within it so that it can be committed to the version control system (VCS) and tracked.
Sometimes you'll have a number of Features with modifications queued up ready for release to live. If some time has elapsed since they were modified or if several developers have made changes, then you'll need some way of recording what Features have changed via release notes to TODO tasks so you know what to revert after the code has been pushed to live. Also, you'll need to share modifications between other developers so that when they get the latest codebase they need to know to revert a Feature which has changed. Ideally, this would just happen without the need to remember to do it.
One solution is to record that Feature reversions are required using update hooks. So, for example, you make a modification to the Feature mysite_news, you'll add an update hook to one of your custom modules install files. Many sites run a master or system module for this purpose to keep these hooks neatly together in one place (although they could easily sit in mysite_news.install)
/** * Revert all features in mysite_news. */ function mysite_system_update_7001() { features_revert_module('mysite_news'); }
Now when the update process is run (e.g. via drush updatedb), mysite_news will be reverted.
And because you added it when you made the change, you don't have to remember that it needs doing when you release because you always run updatedb after updating your code base (don't you? You should, it's liberating).
Automating updatedb with cloud hooks
In an ideal world, updatedb will just happen on code deployment. Acquia hosting (and others) provide cloud hooks for this purpose.
On Acquia hosting, add the following code to a file called hooks/common/post-code-update/update-db.sh to the hooks directory. The hooks directory should be on the same level as docroot and may need to be created.
#!/bin/sh # Cloud Hook: update-db echo "Running cloud hooks from hooks/common/post-code-update/update-db.sh" site="$1" target_env="$2" source_branch="$3" deployed_tag="$4" repo_url="$5" repo_type="$6" uri="" case $target_env in "prod" ) echo "Prod deploy script" uri="www.mysite.com" ;; "test" ) echo "Test deploy script" uri="mysitetest.devcloud.acquia-sites.com" ;; "dev" ) echo "Dev deploy script" uri="mysitetestdev.devcloud.acquia-sites.com" ;; esac drush7 @$site.$target_env cc drush echo "$site.$target_env: About to master ensure modules..." drush7 @$site.$target_env master-execute -y --uri=$uri drush7 @$site.$target_env cc drush echo "$site.$target_env: About to updatedb..." drush7 @$site.$target_env updb -y --uri=$uri
After saving the file, you will need to make it executable with chmod +x update.sh then check the whole hooks directory into Acquia's git and push up.
Now when code is released to any Acquia environment, drush updatedb is executed after deployment and Features that need an update are updated.
You can add the same script to hooks/common/post-code-deploy/update-db.sh to run this when code is dragged and dropped to an environment.
You can also add the same script to hooks/common/post-db-deploy/update-db.sh to run the code when database is dragged and dropped onto an environment.
For more information on cloud hooks, check out these links: