Categories
How It Works

Mailbag: How do plugins update?

How plugins (and themes) upgrade and (possibly) why we sometimes break WordFence.

From Ken the Web Mechanic comes this:

Hi! I wonder if you’d have any insight on this… I’ll mention Wordfence, though I imagine that it applies to any security plugin that compares plugin files with those in the WordPress repository… One of the most common things that Wordfence reports as a file “inconsistency” is the readme.txt of many plugins. Frequently, when using Wordfence’s compare feature, the readme of an installed and up-to-date plugin is shown as not the most current version and the repository shows the latest version – which is for the version that is installed!! If you delete the plugin and then download and install it anew from the repository, the readme is for the current, Wordfence has no complaint and all is right with the world… So I guess my question is… When a plugin is updated through WordPress, does the readme.txt file always get updated? It’s always been my understanding that during an update all of the old filed are deleted and then the new version is installed from the repository… It’s seeming like this may not be 100% of the case. It’s certainly only a minor irritation to me… but it makes me curious… Inquiring minds and all of that! 😉 Thanks!

I put the whole question in because while the crux is “How are these buggers updating?” the whole picture is interesting. I’ve talked about this once before, but it was a very long time ago. How the WordPress Upgrade Works was posted in 2011, and Why does the WordPress background auto-upgrade work? was back in 2013. So it’s about time for a revisit.

The short answer is “Actually, the readme.txt is deleted on plugin (and theme) upgrades.”

The longer answer means first we should understand what’s going on with upgrades! How plugins (and themes) update is pretty basic and you can check out /wp-admin/includes/class-wp-upgrader.php to see all this code:

  1. Connect to the filesystem.
  2. Download a package.
  3. Unpack a compressed package file.
  4. Clears the directory where this item is going to be installed into.
  5. Install a package.

These are all great failsafes, making sure multiple times that we’re not about to leave a user in a bad state. We check to make sure we can download and use the file before deleting and replacing. We check to make sure WordPress can find all the folders it needs, like plugins and wp-content and so on. If it can’t connect to any of the ones it needs, it will fail. We make sure we can download and unzip the file. Even when we look at the complex fourth step, we’re all checking over and over to make sure that when we really do delete these files, we have something to replace them with.

The goal is that WordPress should never be able to leave you with a plugin deleted and not installed again, nor should it leave you with a half-deleted plugin. Obviously critical failures, like a server reboot mid-stream, will have some catastrophic effects. This is why WordPress tosses a .maintenance file down, mind you. Stops your site from looking like total poop while all this is going on.

When we look at the class Plugin_Upgrader itself (line 766 or so), we get into some nitty gritty things. The public function upgrade does some interesting things:

		add_filter('upgrader_pre_install', array($this, 'deactivate_plugin_before_upgrade'), 10, 2);
		add_filter('upgrader_clear_destination', array($this, 'delete_old_plugin'), 10, 4);

Here we are clearly deactivating and deleting safely before we upgrade. And at this point, I’m very confident that we’re deleting that readme.txt before we upgrade.

Okay! So why is WordFence being a dillweed?

I have a theory it’s related to the updates we do when WordPress core has a new version. You see, instead of updating the whole plugin, we update the readmes only to edit the “tested up to…” value. If there’s no code change, after all, why would we bother? No need to push an update! This means you no longer have a plugin that 100% matches what’s on Wordpress.org, you have a plugin where the code files match, but not the readme.txt files.

And then poor WordFence notices that the readme you have and the readme on .org’s servers is out of whack, and tosses an error.

I don’t know how WordFence would fix that, but I’m pretty sure this would hang ’em up.

WordFence folks, got any ideas?

9 replies on “Mailbag: How do plugins update?”

WordFence is basically checking for consistency between the two sets of data, but the problem is that plugin authors are rarely consistent.

Essentially, WordFence needs to adjust their code to recognize degrees of difference. If the difference is just a few lines of text in the readme.txt, which is a file not actually used on the websites themselves, then meh, maybe not bother to warn the user about that? Differences in an unused text file don’t seem like a real security threat, and that would be a relatively commonplace occurrence, generally speaking.

Fault-tolerance is tricky. 🙂

Thanks for sharing this. I also use Wordfence, and this happens to me, too. I’m a little confused about something you said:

I have a theory it’s related to the updates we do when WordPress core has a new version. You see, instead of updating the whole plugin, we update the readmes only to edit the “tested up to…” value.

I’ve disabled all automatic updates, so I assume you’re not talking about that?

Something I do know happens (from asking in the forums exactly because of this issue) is that plugin authors sometimes forget to update something in the readme file before pushing an update, and go back to add it later without pushing another update, since as you said, the code hasn’t changed. But new downloads have the correct version, and if it’s something useful on the repository, like new tags, then it’s up to date there too.

I like seeing the changes, because sometimes they lead to interesting questions or helpful information, so I wouldn’t want how it works to change…

Regardless, your client doesn’t have to delete and reinstall the plugin to get the correct readme. Wordfence provides a button within the change notification: “Restore the original version of this file.”

Nope, not automatic update related. We developers manually update the readmes when there is a new version of WordPress.

But you don’t want to ‘restore’ — you want WordFence to ignore the readme being out of sync, or know to just update that.

But you don’t want to ‘restore’ — you want WordFence to ignore the readme being out of sync, or know to just update that.

Restoring the file only replaces the version on your system with the version from the repository. It doesn’t touch any other files, so I’m not sure why it wouldn’t be alright… Especially since Wordfence provides a comparison between the two files so you can see exactly what changed. If you’re not sure of what you’re seeing (or if you made the changes yourself, for instance), Wordfence provides an option to ignore the file (either permanently or until the next time it changes).

But let me get this straight. You manually go through all the plugin readmes in the repository 3 times per year? OMG. You gays are warriors! I always thought authors updated the compatibility tag themselves…

Then ‘restore’ is the wrong term. ‘Update readme’ is what you’re looking to do, and ‘restore’ implies restoring from backup. Bad terminology…

I do not manually go through the readmes on the whole repo 🙂 Each developer updates the readme in trunk and the one in their stable release of the plugin for every new version of WP. It takes me and my dozen plugins about an hour, only because I check for typos while I’m at it, and review the readme as a whole.

Interesting discussion. As a plugin developer, I didn’t realize that changing the readme file without updating the whole plugin would cause an issue. I believe that I have been guilty of just that, as sometimes I will spot something wrong in the readme and fix it and not want to annoy everyone with an update.

There are a lot of things to remember before updating a plugin and the first few times I did this I would forget about one of the changes. Now I have a list: update the version in the plugin file header, plus the version number that’s saved in a variable, and then the readme file needs the stable tag updated, plus the changelog and the upgrade notice.

Comments are closed.