WordPress and Bamboo – Continuous Integration, automatic testing, one click deploy (and roll back)

If this topic is interesting to you, you may also like the text of my WordCamp Raleigh 2015 talk, Continuous Deployment: WordPress Code, Configuration, and Content.


Atlassian’s Bamboo seems to rarely be discussed in WordPress World ™, but it is entirely possible to marry the two. Most of the problems I had – and I feel pretty confident in using past tense at this point – were due to my own inexperience with WordPress. Our Bamboo server also did not have any PHP code installed or running, so our server admin had to take care of a few installs and related tasks to get everything running.

What’s the point of Bamboo?

Bamboo makes it very, very easy to do several important things:

  • continuously integrate code changes from multiple developers – e.g. Continuous Integration
  • automate unit and other kinds of testing, taking that burden off of developers and testers
  • automate deployment of code changes (if desired) – e.g. Continuous Deployment
  • give developers one-click deployment of code changes (in other cases)
  • quick deployment of previous code releases – effectively, a one-click roll back

So in other words, it makes build, test (the parts that can be automated), and deploy incredibly painless. Gone are the days of “we can’t deploy because only Dev X can deploy, and she’s out today!”  All of the tasks that Dev X would have done in her playpen are scripted, automated, and enforced in the Bamboo setup for your project.

Build and Test

Builds start with a trigger – in our case, and this is very common, with a commit and push to a central Git repo.  So whenever a dev commits and pushes, a build starts in Bamboo.

Here are the steps in our build process…

  1. Update code on our autotest WordPress instance
    • source code download from central git repo (this gets the code that we develop),
    • run Composer install (code that we did not develop, including WordPress core), getting everything in require-dev – because that includes our automated testing dependencies such as Selenium and its ecosystem – we will need these in the next stage, and,
    • copy files out to our autotest instance.
  2. Run PHPUnit tests
    • Send Selenium tests (running within PHPUnit) to our Selenium grid for browser 1,
    • ditto, for browser 2,
    • ditto for all browsers we care about right now – and these grid tests run in parallel
  3. Create deployment artifact
    • clean the working directory,
    • source code download (again),
    • composer install –no-dev – no need to deploy Selenium, etc to the instances that humans use!
    • bash script to remove unwanted items from the working directory – .git, composer.json and the like
    • create deployment artifact with just those files that are left.


Deploy is incredibly simple. I’ve set up deployment environments for each of our human-usable test installs – alpha and beta.  Deploying involves selecting a build artifact to tag as a release, and then clicky-clicky. Bamboo copies the files out to alpha or beta.

Once our live/stage multi-network is ready, I’ll create a deployment environment for it as well.

Beta and live/stage will always be manual deploy.  Alpha may become auto-deploy if the dev team decides we want it that way.

The Database

Oh right, that thing. The above really only deals with code changes.

This seems to be the hard question for everyone to answer when they talk about better deployment practices for WordPress. I don’t know that I have answers, but here’s what I have decided so far:

  • I don’t have a database ‘seed’ that I can deploy with test content, or settings. Cross that bridge when I come to it, but I can run mySQL commands from a LINUX command line within Bamboo, so if I need to automate seeding of the autotest database, that should be feasible.
  • When possible, make database changes – like enabling plugins, or setting settings – through the WordPress admin UI. This means either a human or Selenium.

Moving content from staging to live is a different problem to solve. It has been very useful to separate concerns properly during this exercise (adventure!) in infrastructure design.