My Simple, but Nerve-Calming, drush Update Workflow

Just posted for my own reference - here's my workflow for updating a D6 (probably also D7) website using drush. Comprehensive information about all drush commands can be found on the http://drush.ws/ website. If you're not yet drinking the drush kool-aid, you need to—if you use a Linux server, of course.

  1. Visit admin/reports/updates page on your site, read through any relevant release notes for required updates (to check if there are special requirements for said update).
  2. $ drush @site pm-updatecode <module1_shortname> <module2_shortname> (add all modules to be updated)
  3. $ drush @site updatedb (updates the site database - update.php)
  4. $ drush @site cc all (clears all caches on the site)

The reason I do this manually, instead of running something like pm-update or pm-updatecode is that I like the granularity and security of doing all the updates discretely—especially when I'm updating a larger site, where I like to know exactly what's happening when I update.

For Drupal core updates, at least in D6, I always copy the files in by hand (even though drush can handle this), because I just don't trust Drush with that operation—especially if I have other files included in my root directory for other purposes. (Plus, using git, this is a breeze. When I used SVN or CVS, it was a major pain, due to all the 'CVS' or '.svn' directories that had to be maintained).

After finishing the drush process, I do a $ git add ., $ git add -u, then $ git commit -am "Updated <modulename1>, <modulename2>, etc." (after testing the site thoroughly, of course). Then I push the changes to production, do an updatedb on that server, and breathe a sigh of relief when everything's working perfectly.

Anyone have a better idea for leveraging drush for updates? One thing I wish I could do is maintain patches when doing drush updates on a module, instead of having to re-download and apply the patch.

Comments

I would like to also hear about your use a git to push your changes to your production server. What is your workflow for this process. I have never found a clear tutorial on using git in dev-live environment. I think this is because everyone has there own method.

I'm doing something same to you. Do you patched? I'm pretty sure "drush cc 1" is not work, instead "drush cc all".

I meant $ drush cc all - sorry about that! (If you just enter $ drush cc without an argument, you'll get a numeric selection option, in which 1 = 'all.' And half the time, I forget to add 'all', and I see that menu :-/

I'm no expert at drush, but if you run drush dl module over the old module, don't you risk getting orphaned files mixed with new files in your module folder? (If files and/or folders have been removed or file/folder names have been change in the module.)

On the other hand, afaik, if you run drush upc module you get a complete backup of the old module folder, and a clean install of the updated module folder.

If committing all the code at once anyway, i'd definitely recommend running drush upc for all modules, testing the site, and if anything isn't working then rolling back to a one-at-a-time commit and update.php after each module updated.

In drush-4, you can read release notes from drush. Regarding patching after an update, see http://drupal.org/node/392762. This was more of an experiment in using drush hooks than anything else; I don't use it in practice, and I expect you would often run into conflicts that needed to be resolved if you did.

While I too advocate a calm and careful approach to upgrades, I would not recommend this approach. Using drush dl will not clean up deleted/moved files, which can cause significant problems (many modules scan directories and load all .inc files, for example).

Using pm-update or pm-updatecode you can replicate your exact workflow - you can specify each module you want updated - you can update them one at a time, and even specify specific versions (other than the recommended one) if you like!.

It will also clean up deleted files (using the cvs or git_drupalorg package handlers is recommended for this purpose, but we make an attempt to clean up deletions with wget also).

It will also make sure updated modules go to the correct location (handy if you have modules in sites/all and sites/whatever, or organized by stable/dev), and will perform sanity checks using your version control system (e.g. that you haven't got uncommitted changes in that directory).

Thanks for the comment - looks like I will need to refine my drush workflow a little... can I do -dev releases using pm-updatecode?

Yes you can - for example, this works as expected:
drush dl pathauto-1.4 token
drush en pathauto
drush upc pathauto-1.x-dev
cd all/pathauto
cvs stat pathauto.module | grep Tag
Sticky Tag: DRUPAL-6--1 (branch: 1.118.2)
(it would work with wget also)

If you have a stable release of a project installed, then you must use pm-download --dev to go to the dev release; pm-updatecode will never go from stable to dev. If you alread have a dev release installed, then pm-updatecode will update it to the latest dev release, when available.

If you're not sure which version of a module to download, try pm-download --select (or pm-download --select --all if you don't see what you were looking for the first time).

Regarding patches, most people who manage patches check them in to svn or git. For my part, I keep my dev machine checked in to svn, but I push with drush rsync + sql-sync. Some people push code by doing a checkin on the dev machine, and check out on the live machine. I don't like to do this myself, because Drupal gets very unhappy if your SQL database and your files get "out of sync", so I always test on the dev or staging server, then push code + sql together.

For more drush info, see http://definitivedrupal.org/drush

Perfect! Thanks for this comment - it is very helpful for me, and I think I'll be continuing my attempt at memorizing these drush commands and shortcuts, instead of my rather barebones list of dl, cc, etc.

Going back to this, to help me upgrade my site to 6.20, then to 7.0. Before long, you will be able to use git submodules.

Thanks for posting htis Jeff. This is very similar to my own workflow. Although I tend to do one module at a time, so I can have a separate commit in git for each module.

Regarding maintaining patches, if you have applied the patch then committed with Git, then you can use git cherry-pick to re-apply the patch after an update. You just need the patch's commit hash from your git repo.

I also use Drush to backup my production database and store this in git before pushing updates live. I have a custom script to do this which you can read about over at http://www.opc.com.au/web-development/drupal-release-management-drush-and-git. I find this process adds even more nerve-calming goodness :-)