cute robot

TimNash.co.uk

Dev/Sec/Ops with a splattering of humour

10 tips for getting started with WordPress in version control

Really old post – This post is from 4 years, 9 months and has not been updated, some if not all of the information maybe out of date. Proceed with caution.

If you are new to using Version Control and WordPress be it with SVN, GIT, or another system then some of the things you used to do are going to have to change. However, the benefits do outweigh any initial inconvenience. So here are my 10 many tips for people who might be in the process of switching to using version control.

1. Disable automatic updates

One of the most important things is that the site in version control is the same as the one deployed, or at least a branch of it is. While you do want to do timely updates to WordPress core, you want to do that from a local copy, which is then managed via version control and deployed.
WordPress Core is pretty smart, and if it spots you are are using a version control system because you have a folder (.svn, .git, .hg, .bz) in either your root path (for core updates), plugins folder (For plugins) or one level up from these then it will disable automatic updates and instead email the admin user. This is fine on local and maybe staging environments but on production servers you may have deployed and these folders haven’t been carried over. To stop automatic updates all together (including the email firing) you can use the following in your wp-config.php


define( 'AUTOMATIC_UPDATER_DISABLED', true );

This has disabled all the WordPress automatic updates. Bear in mind you should only do this if you updating via version control and if for some reason you stop using version control (maybe you’re parting ways with a client) that you remove this define.

2. No File Editor please, we are British

You might not be (British that is) but the file editor is evil and with version control you have absolutely no excuse to be using the file editor to modify plugins or your themes. Hopefully this wouldn’t have been an issue as you would have not made such files writable by WordPress in the first place. Regardless as we don’t need this functionality it’s best to disable it.


define( 'DISALLOW_FILE_EDIT', true );

3. Stop users from uploading plugins/themes directly

I suspect you can see a trend, but the ability to install plugins directly from WordPress goes against using version control. Again we want to disable it, and the simplest way is to use:


define( 'DISALLOW_FILE_MODS', true );

Which also disables the File Editor and Automatic updates, so basically you can skip the last two steps and jump straight to this one. Again it’s important to emphasise that if you don’t use version control this can leave a site vulnerable and using version control only works if you do actually update WordPress!

4. Separate WordPress core from plugins and themes into different repos

example.com/
|->local-config.php
|->public_html
|-->index.php
|-->wp-config.php
|--> core
|-->custom
|--->plugins
|--->themes

This will make updates much simpler, and WordPress feel much more logical. I have written an article on how I structure WordPress projects, and one of the big advantages of doing this is that you can load in the WordPress core as sub module (or equivalent in your version control of choice). This means you hold a separate repository for WordPress core and your sites. You then only need to have WordPress core repo once and update it once for it to be updated across all your sites. Just remember whatever deployment system you use it has to cope with sub modules and deploy the latest version on the branch specified of them too.

You can expand this to include other items in sub modules, for example if you have a default parent theme you use across multiple sites, you might want to have it’s own repo and include it as a sub module. Likewise plugins used on multiple sites are another perfect candidate to working with sub modules. Be careful, while deployment systems should be able to cope with sub modules, some might not be able to cope with sub module in sub module and things can get complex quickly sometimes it’s easier to have repetition between codebases to keep things simple.

5. Separate out a local config version

I guess this tip isn’t specifically a version control tip, but if you are deploying to multiple sites then you will probably be interacting with different databases, using different keys and generally have different config options along the way. One option is to ignore the wp-config file and simply allow each site to have its own wp-config.php, but I prefer to put the shared information (all the bits in the wp-config that will be the same) into wp-config.php then create a local-config.php an idea originally found in Mark Jaquith’s skeleton structure. I can then ignore (or put it outside of version control entirely) this local-config that includes server specific content.

6. Automate your build processes

So when people think of version control, they tend to think of it for teams. Most of my projects these days are solo affairs yet I still use version control, still branch when developing a new feature and still regularly commit. One of the reasons for this is habit, and it’s also a good backup policy, but also because of the next step after I push my changes, automated builds both on staging and production. Automated Builds (Deployments) allow you to deploy changes made in a version control branch to a specific server (staging, production) and run any associated tasks, for example compiling sass files, or tests along the way. There are dozens of tools and services out there such as Jenkins, Travis, PHPCI and services like DeployHQ, and these allow you to deploy code and run additional tasks on the server post deployment.

Deployment systems will normally allow you to run additional tasks, such as working with WP-CLI to auto-activate plugins or update WordPress database when needed, a good deployment setup is one where no one has to get involved and you have the confidence that everything will update without any interference or even need to manually check (but take a peek and check anyway). However it should also be simple enough that any member of staff can use it.

7. Run your tests before you build (aka write some tests)

Speaking of running tests, why not run them before they get on to the server? Version control systems like Git have hooks that can be used to run other tasks. For example a commonly used Git hook is pre-commit-hook which allows you to run a task prior to the commit being stored. If you have critical features you may wish to run tests of this hook to make sure your commit is not going to break anything. An alternate test suite hook location might be pre push (Only available in Git 1.8.2+), and this fires before you push your changes to others. Depending how you are using Git this might be a more appropriate time to test.

8. Never Let broken code through

Even if you are not using pre-commit-hook or its equivalent for running tests (shame on you) what you can do is make sure you don’t commit bad code. Most languages have what’s called a linter and in PHP you call it via the CLI version of PHP using:


php -l myfile.php

What it does is run through the file and spot any fatal errors, warnings etc. being picked up and displays them to the screen. It doesn’t however execute the file, just reads it and checks for errors. Most languages have a linter or one has been developed for them, so you can build a script to go through your common languages, check the files for issues and notify you when you try to commit. For PHP you can start with this simple gist or for multiple languages take a look at One commit hook to rule them all. Bear in mind that linters normally use local version of the language. If you develop using Vagrant or similar but commit on your local machine, then the pre-commit-hook will run using the local machine not the Vagrant version of the language.

9. Enforce Standards

WordPress has a coding style and standards and while sadly they have chosen to not adopt what the rest of the PHP world is doing at least it’s consistent. However, unless you work in WordPress 100% chances are you are going to have habits and style that are different. It’s up to you how much this might bother you, but if you are working on a public WordPress project you may wish to enforce the WordPress coding standards on commits. This is easy enough to do using PHP Codesniffer, a Pear/Composer package that like the linter tools reads files but instead of looking for errors looks for incorrect placing of curly brackets. You can specify what particularly to look for and how your code should be styled. You can grab a ruleset for WordPress from Github. For a generic PHP project Zumba have a good step by step guide to setting Codesniffer with Git.

10. Pick a branching strategy

simplebranch
This will probably be unique to your organisation but there are lots of tutorials on good branching strategies. Most involve having 1 or 2 main trunks (for dev and production) and then individual developers work on a specific feature. I use a variant on Vincent Driessen’s Branching Model.

11. (because these list never have just 10) Still backup uploads

This might seem like a bit of a weird one. If you have been used to doing “full site” backups of all your files then the good news with version control is that you don’t need to backup the files in version control as well – it’s in version control (unless you are insanely paranoid, in which case do the backup through git rather than your site). You do however still need to backup the database and your uploads folder (which won’t be in version control). When setting up a backup regime it’s easy to forget that user uploads are not in your version control repository, and if you stop doing file based backups can easily be forgotten entirely.

Finally a couple of non WordPress specific bonus tips

You don’t need to use VI

At least on a Mac, when you merge changes the wonderful vi/vim opens up and for many users the nightmare begins. But you can change the editor simply by doing:


git config --global core.editor "nano"

In that case it globally changes the core editor to the much more user friendly nano, of course you could always learn the dark art’s of working with VIM.

Searching your commit messages

Assuming you write intelligent commit messages, this command is really useful


git log --grep="message in commit"

Never let the boss have sftp access

If you are automating deployments, then no one barring system administrators should have direct access to servers. In larger organisations this means you should be revoking credentials for almost everyone in the company who perhaps in the past had ssh or worse FTP credentials, even the boss. If you don’t then the temptation to go around the build process will be high and the moment someone makes a “hot fix” the whole system is broken.

Put it all together

Version control systems only work if they are at the heart of your workflow not simply somewhere to store code, but once you start to build a workflow around them they become an incredibly powerful tool that can be tailored to almost any development environment. I would love to hear your tips and how you are using version control systems in your workflow, especially if it’s something you are just getting started with, what issues are you facing?


Have your say?

  • Max says:

    Very nice post
    Thank you ! A lot of people should learn benefit of version control theirs WordPress instances

    • Tim Nash says:

      thanks, I find it amazing how many people continue to not use version control and automated deployments and claim it’s “easier” once setup version control and automated deployments is a no brainer.

      Thanks for stopping by!

  • Chris says:

    I’m still undecided as to including WP as a sub module. It strikes me that once it is in my project, I don’t really care about what WP is doing in it’s own sub module. It’s more useful to see when WP was updated / what changed at what commit (in my project) in relation to how my code changed so as to make it easier to resolve any issues that arise?

    Having said this, maybe I am just showing my lack of knowledge of Git sub modules and the best way to use them?

    • Tim Nash says:

      The advantage of sub module comes really if you are supporting multiple projects, and that first time you update a dozen sites with one commit. You can script this to do similar without sub modules, but separating out common code to their own sub module tends to make organisational sense. The downside is that you are effectively isolating your sub modules and while you can see when you updated the sub module, not necessarily what commit in the sub module broke your code. In this scenario this is minimised by the fact that WordPress sub module should really be stable builds, rather then bleeding edge nightlies.

  • Jonathan Perlman says:

    Hi Tim,

    I’m doing most of what you’re suggesting. I’ve just gotten into wp-cli and I have my wordpress core in a folder named “wordpress” at the same level as wp-content.

    For my test site, I can’t seem to get wp-cli to respond correctly in comparison to my normal un-submoduled sites. I tried “wp plugin list” and all I get is hello dolly. I can tell you it’s not even installed.

    Any suggestions? Thanks.

    • Tim Nash says:

      That sounds more like you are looking at the WordPress sub module rather then your actual site, though weirdly I would have thought that should just return a lack of database error. Do you have a wp-cli.yml in your root pointing to the WordPress path? Are the plugins active, and as daft as it sounds are you looking at the right site?

  • Jack Lenox says:

    Hey Tim, do you have any recommendations for keeping on top of which plugins need updating once you’ve disallowed file mods? :)

    • Tim Nash says:

      I tend to run:
      wp plugin list --format=json --update=available --field=name
      through WP-CLI this can be completely automated if you are brave enough and update each one though if you are going to do that you might as well just update all at once and be damned.

  • I’ve been keeping WP out of Git (and in its own folder). Then, what happened was – I had to upgrade all staging machines separately. Hassle. May forget. Etc,etc.
    Besides, if I do a temporary patch in the WP core, if it’s under version control, PhpStorm shows what’s changed. I can always rollback. I can make a patch and submit to WP trac. Etc, etc.

    Great article. Confirmed all I learned “hard way”. Thank you!

  • rubén says:

    Hi Tim

    very interesting topic. One thing I miss was some tips about database versioning (plugins will modify database as well the files). As you know is the most critical and less documented topic. Do you have any best practice for this?

    Thanks!

Sorry Comments are now closed, feel free to tweet me!