I was 90% sure about this before I started writing the post, and Andrew Nacin was nice enough to tweet me the exact file I needed to look at, so when I got home to look, I was ready to go!
There are two kinds of automated upgrades for WordPress. The main ‘core’ upgrader and then the ‘child’ upgrades used for themes and plugins. They behave differently.
Most of the time, we all see the plugin and theme installer, where it downloads the plugin to
/wp-content/upgrade/, extracts the plugin, deletes the old one, and copies up the new one. Since this is used more often than the core updater (most of the time), it’s the sort of upgrade we’re all used to and familiar with. And we think ‘WordPress deletes before upgrading, sure.’ This makes sense. After all, you want to make sure to clean out the old files, especially the ones that aren’t used anymore.
This is not how a core update works.
WordPress core updates, the ones to take you from 3.0.3 to 3.0.4, do not run a blanket delete. They don’t even run a variable delete. They don’t even run a wild-card delete on files in
wp-admin (which they could). Instead they have a manually created list of files to delete, files that have been deprecated, and delete only those files. Here’s a snippet of what it deletes:
$_old_files = array( 'wp-admin/bookmarklet.php', 'wp-admin/css/upload.css', [...] // MU 'wp-admin/wpmu-admin.php', 'wp-admin/wpmu-blogs.php', [...] // 3.1 'wp-includes/js/tinymce/blank.htm', 'wp-includes/js/tinymce/plugins/safari', [...] 'wp-admin/images/visit-site-button-grad.gif' );
As you can see, the files and folders are all very carefully specified. They are not ac-hoc, they are all determined based on what WordPress has removed. If you read the whole thing, the part that would impress you the most is, perhaps, the folder
wp-content, where your themes and plugins are installed, is nowhere on that list. Don’t believe me? Go look at
wp-admin/includes/update-core.php and search for it. It’s not not there!
Once the old files are listed, remember that we have not deleted anything, the upgrader runs through 9 steps.
- Download the zip file of the new release, unzip it and delete the zip
- Make sure the file unzipped!
- Make a .maintenance file in WordPress base (this makes your blog ‘down for maintenance’ so no one can do anything and screw you up mid-stream
- Copy over the new files. This is a straight copy/replace. Not delete.
- Upgrade the database. This may or may not happen.
- Delete the unzipped file
- Delete the .maintenance file
- Remove the OLD files. This is where it goes through the list of deprecated and unused files and deletes them.
- Turn off the flag that tells you to upgrade every time you’re in wp-admin
Nowhere in there is wp-content and your themes mentioned.
Well, except in this one weird way.
See, in order for WordPress to work out of the box, a theme must be included, right? WordPress has the default theme of Twenty Ten. Now, I’ve mentioned before that you should never update your themes directly, and instead make child themes. This is why. When the WordPress core files update the copy over everything. Included in everything are two plugins (Akismet, Hello Dolly) and one theme (Twenty Ten).
Normally this isn’t a problem. Sure, someone always edits those files directly and lives to regret it, but they do live. This last cycle, with 3.0.4, Akismet was accidentally rolled back from 2.5.1 to 2.4. Again, normally? Not a problem. We just upgrade our Akismet installs, remark on the silliness and annoyance, and move on. The problem for one user is she had another plugin or theme edit that hooked into the new Akismet. With the way WordPress updates core, it only deletes the files it knows to delete (and Akismet isn’t any of them) and it copies over the ‘new’ files. Or in this case, the old ones. Which broke her site. Her fix? Just re-update Akismet manually. Not a big deal and an easy fix. (Personally I think NOT updating core, even a security upgrade, with the latest Akismet is a poor choice, but the rational is that they want to keep it small and easy to maintain. So okay, I get why, I just don’t like it. I will support that as their choice, and continue to do my manual upgrades, which include deleting Akismet, Hello Dolly and Twenty Ten before I upgrade.)
So then, why doesn’t this work 100% of the time? (Yes, I mentioned this before in the 3.0.1 days, but apparently it bears repeating. Read Why doesn’t the WordPress Auto-Upgrade Work? for more thoughts on the subject.) Well, to start with, that’s impossible. Nothing works 100% of the time. Me submitting this post won’t work 100% of the time. You safely walking up the stairs won’t work 100% of the time. This is just how the world works. There are, simply, far too many variables out there to allow this. Even though I make part of my living ensuring that I have an automated process run in a repeatable fashion, I tell people that I only ask for a 75-80% success ratio on the process before I’ll agree to automate it. Why? Because that’s actually phenomenal.
If you take into consideration all the moving parts, variables, and possibilities that goes into any one individual WordPress install, it’s sort of impressive this stuff works at all. In baseball, if you hit a ball and get on base 33% of the time, you’re considered a fantastic hitter. If you do it 40% of the time, you’re pretty much promised a slot in Cooperstown. Whenever I try and sort out if something is worth the risk, I quote my father “What can go wrong? How likely is it? What are the consequences?” It boils down to an understanding of risk analysis, and what that actually means. The problem is that most of the people using WordPress are users. They’re not generally expected to think about risk. Not that many don’t, but just that Joe Blogger doesn’t tend to look at an upgrade as a ‘risk.’ After all, WordPress tested this, so it should be easy.
Most of the time, it is. And when it’s not, it was an acceptable risk. All those horrible and terrifying outcomes you read about (from a very vocal minority) are gut-wrenching when they happen to you, don’t get me wrong, but at the end of the day, you have to ask ‘If I use the default WordPress theme and no plugins, do they happen?’ If the answer is no, then WordPress has done all the testing that is required. The onus is not on WordPress to test every upgrade with every theme and plugin. That responsibility is firmly on the shoulders of the person using the themes and plugins. A good developer tests their plugins and themes the moment a release candidate comes out for a new version of WordPress, and sorts out how best to support both the current users and the future ones.
It’s what we call ‘acceptable’ risks. You take them all the time. You took an acceptable risk brushing your teeth. You take one every time you walk out your door. You know the risks and you accept them. So when you get to arguing that ‘WordPress upgrades always break’ or ‘I hate upgrading because it means my themes/plugins won’t work’ and using these as reasons to show that WordPress is bad software, then I think you’re missing the point. The more you customize, the more things break. This is something I mentioned in When To Code, and it bears repeating. The more you customize, the more things will break when you upgrade.
But this is an acceptable risk for most of us!
So when the WordPress auto-upgrade breaks, and I promise you, it will for you at least once in your experience, you have to learn to accept this. It’s not going to work on every server, it’s not going to work on every host. Your server is being constantly upgraded and tweaked. Security patches for PHP, FTP and everything else are applied, most of the time automatically so you don’t have to waste time thinking about it. And when you combine all those things, yeah, it’s going to break.
This isn’t meant to scare you off of upgrading, but an attempt to raise your awareness of what’s going on, so when things break (and they will), you have a better understanding of why, and what to do. If the automated upgrade of WordPress breaks, upgrade manually. If every single automated install (upgrades, plugins, themes) always breaks, then start to diagnose your server. But if it’s a one off, just do it manually. It is, literally, copying files up to your server. If that’s too hard for you, you may not want to run your own, self-managed, WordPress install.
As a blanket reminder, in order to prepare yourself for an upgrade, always make backups of your database and your files. A good backup. Never edit core files (even themes) and always remember that the computer is out to get you.