Plugin update backup and restore
Updating plugins on a live site is scary. Yes, we should test updates on a staging site first, and we do, but problems can still occur. Wp-cli is great for updating plugins but it would be even better if there were a built-in backup and restore for plugin updates. The currently available options I'm aware of for backup & restore are:
wp plugin update --version=<version>(doesn't work for all plugins)- The WP Rollback plugin (doesn't work for all plugins)
I would like:
- for
wp plugin updateto locally back up the plugin version being replaced before doing the update - a
wp plugin restorecommand that rolls back to a backed up plugin version - both of these commands to log what happens in case I need to investigate something later
The advantages of this would be:
- It works for all plugins, even paid/proprietary ones
- Restoring is immediate and reliable because the backup is local
I've written a couple short bash scripts to do this after a recent situation where a plugin update appeared to work fine in staging but created a huge problem in production that wasn't visible until later. I can use scripts like this but it would be great if it were built into wp-cli. I can attempt to do it PHP and contribute the code if you think it's a good idea.
wp plugin update (bash example)
if [ $# -eq 0 ] ; then
echo "Usage <plugin>" && exit 1
fi
backups=~/.wp-backups/plugins
logfile=$backups/plugin-changes.log
plugin="$1"
version=$(wp plugin status "$plugin" | grep -i Version | sed 's/[^0-9.]*//g')
pluginversion="${plugin}-${version}"
read -p "Update ${pluginversion}? " -n 1 -r
echo ""
if [[ ! $REPLY =~ ^[Yy]$ ]] ; then
echo "Aborting..." && exit 1
fi
mkdir -p $backups
timestamp=$(TZ='America/New_York' date)
rm -Rf $backups/$pluginversion
cp -Rp wp-content/plugins/$plugin $backups/$pluginversion
echo "--- ${timestamp}: Backed up ${pluginversion}" 2>&1 | tee -a $logfile
wp plugin update --format=summary $plugin 2>&1 | tee -a $logfile
wp plugin restore (bash example)
if [ $# -ne 2 ] ; then
echo "Usage <plugin> <version>" && exit 1
fi
backups=~/.wp-backups/plugins
logfile=$backups/plugin-changes.log
plugin="$1"
version="$2"
pluginversion="${plugin}-${version}"
if [ -z "${plugin}" ] ; then
echo "${plugin} name is empty, aborting..." && exit 1
fi
if [ ! -d "${backups}/${pluginversion}" ] ; then
echo "${backups}/${pluginversion} does not exist, aborting..." && exit 1
fi
read -p "Restore ${pluginversion}? " -n 1 -r
echo ""
if [[ ! $REPLY =~ ^[Yy]$ ]] ; then
echo "Aborting..." && exit 1
fi
timestamp=$(TZ='America/New_York' date)
cd wp-content/plugins
rm -Rf $plugin
cp -Rp $backups/$pluginversion $plugin
echo "--- ${timestamp}: Restored ${pluginversion}" 2>&1 | tee -a $logfile
Thanks for the suggestion, @37Rb !
I think it's unlikely that we'll add something like this to WP-CLI itself in the near future. Some complexities that come to mind:
- The plugin may modify the database during the update process, which is difficult to revert back.
- The plugin may write to the database after it's been updated, and those writes might not be readable by the earlier version of the plugin.
You're welcome to create your own WP-CLI package around this, though. If you find a robust solution for this, we could consider adopting it as a community package.
You're right that just copying files wouldn't always work when a plugin update makes database changes. I've found most plugin updates don't make database changes. The ones that do usually add something to the database so rolling back just means the old version ignores what was added. But there would definitely be cases where it would cause a problem.
I think the popular WP Rollback plugin has this same issue and people use it. Doing wp plugin update --version=<version> to an older version would also have this issue but wp-cli allows it.
I'm happy to continue using the bash scripts I already have if it's unlikely to be added to wp-cli. I just thought others might want a plugin restore like I did.