This is the story about how I wasted 3 days, but also, which is more important, how I set up continuous integration for WP Pusher with CircleCi. With a continuous integration service, you can have your tests run on every commit and ensure that nothing is broken. That is, if you have some tests to run of course.
Last week I spent most of my awake hours playing around with CircleCi. What should have taken me an hour or two ended up being a weekend project and ultimately resulted in this article. Let me start out by saying that this was my own fault. I overcomplicated the process instead of just using the awesome tools that were already available to me in the CircleCi eco-system. Allow me to explain:
A few weeks ago, I discovered a really cool project called Wocker – which is basically WordPress in a Docker container. Wocker is super awesome and makes setting up a WordPress environment extremely fast and simple. When I saw Wocker the first time my immediate thought was “Hey! This could really simplify setting up CI for WordPress“. I did a bit of Googling and after finding out that CircleCi supported Docker containers, I decided to give it a go… Quickly, I realised that Wocker was not the best fit to run in a CI container, so I decided to roll my own Docker image based on some of the existing Apache, MySQL and WordPress images I could find. Basically, I wanted to run apache in the Docker container so I had a simple environment where I could install WordPress and WP Pusher. This is where I should have taken a step back and looked at what is already included in the CircleCi container (which I guess is much like a Docker container), but I didn’t. Instead I spent my weekend hitting the wall again and again. Eventually I got it all working but then I found out: My CircleCi container already had Apache and MySQL running, which was basically all I needed to run WordPress. I went out the get some fresh air and when I came back, I reconfigured everything to not use Docker and made it all work in something like 2 hours. Now that I learned it the hard way, there is no need for you to do the same – hence this article.
What Is Continuous Integration?
Continuous integration (CI) is the practice of performing certain routines, such as running a test suite, every time something is committed to version control. Let’s say you are using GitHub and have opened a pull request for a new feature. With a continuous integration service, you can be notified if the new feature breaks any tests before you merge it. As an example, here is a small pull request I made for the Laravel PHP framework. This pull request was run through 2 different CI services before it was merged – Travis CI and Scrutinizer. Actually, as you can see here, the build failed with Travis for PHP 5.4. However, it was merged anyways, since the failed test was not related to my code. But you can probably see why a CI service is a handy tool for someone like Taylor Otwell, the creator of Laravel, when you see that the project have about 4000 closed pull requests. That is a lot of code to review and test manually.
Travis CI is great for open source projects, but in this tutorial, we will use a service called CircleCi, which I am very excited about these days. It is free for one build container, which covers my needs for WP Pusher so far.
So let’s get started.
The WordPress Environment
Now is the time to start preparing our environment. These are the steps we will go through:
- Set up our machine and PHP environment
- Set up a database for WordPress
- Download, configure and install WordPress (hint: we will use WP CLI for this)
- Install and activate our plugin or theme – WP Pusher in this case (we will do this in the next section)
- Setup an Apache configuration for our WordPress installation
When these steps are completed, we will have WordPress running in our CI container, so we can run some tests for our code to make sure it is working properly.
In order to configure CircleCi, you can include a
circle.yml file in your project. This file is a YAML file that contains instructions for CircleCi to use when it sets up your CI environment. This is also where you define how your tests are run. Here is an example
circle.yml file for WP Pusher:
The first part of the file,
machine, should be pretty self-explaining. We define a timezone, a PHP version and make a hostfile entry for our WordPress site. The next part of the file is more interesting. This is where we instruct CircleCi on how to set up and configure WordPress. For this purpose WP-CLI is pretty handy. Let’s walk through each of the steps in the
dependencies section of the file:
- We start by creating a WordPress MySQL database. This is easy because MySQL is already available to us in our container. The database will have a user named
ubuntuwith no password.
- We then use cURL to fetch the WP-CLI binary and in the following step we make sure it is executable.
- Now, we can use WP-CLI to download WordPress. Notice we set the
pathparameter to a directory called
wordpress. We will make sure to add this parameter every time we call WP-CLI.
- We can now have WP-CLI generate a
wp-config.phpfile for us, by providing our database credentials.
- With WordPress configured, it is time to install it. We set the
urlparameter to the URL we added to the hostfile.
- Next step is to install our plugin or theme, but we will talk about this in the next section.
Finally, the last step is to configure Apache. This is done in the
post section of the
dependencies section. The easiest way is to include a sample Apache configuration file in your project.
Here is the one for WP Pusher:
As you can see from the CircleCi configuration files, the steps for configuring Apache are similar to what you would do in a production environment. Copy the Apache configuration file, run
a2ensite and restart the server.
Installing A Plugin (Or Theme)
With our WordPress environment running, it is time fetch our code (the WP Pusher plugin in this case) and install it. Actually, the code will already be available to us, since CircleCi will pull your code from GitHub and into the home folder of the
ubuntu user. This means that if you have some unit tests for you plugin that does not require a webserver, you can just run them there. Actually, as you will see in the next section, this is also where we will run the Behat features for WP Pusher. However, if you have acceptance tests that requires a webserver to interact with WordPress, you need to have your plugin or theme installed in the
plugins folder. Once again, WP-CLI can help us out with this. As you can see in the Circle Ci configuration file, two steps are required to achieve this:
- Cloning the Git repository
- Using WP-CLI to activate the plugin
In the first step of the
test section, we run
./wp-cli.phar plugin list --path=wordpress to verify that WP Pusher is actually installed and is activated.
The output of this step looks like this in CircleCi:
Running Some Tests
As I mentioned, CircleCi clones our code to the home folder by default, so running unit tests there is pretty trivial. Now that we have a server running with WordPress and WP Pusher, we can fire off some acceptance tests that interacts with our code via HTTP. For this example, I have set up a simple Behat feature, using the Mink context with the Goutte driver to go through HTTP. As the last entry in the
circle.yml file, we run the Behat suite.
This is the output we get in our Circle Ci container:
This feature is just an example. It does not test WP Pusher, it just verifies that the Apache server is running and is serving WordPress correctly. Also, you do not have to use Behat. This is just the tool I prefer to use. You can use Mink together with PHPUnit – or something else like Codeception.
Our continuous integration server on CircleCi is all set up and our tests are running green. It might seem like a bit of work to get this up and running, but now that it is all configured, it is really easy to use. Most of it you will never have to touch again. You just have to write some tests (I will have an article about this in not too long) and let CircleCi verify them after each commit. You do not have to be 100% test-driven or anything in order to benefit from a CI service, even if you have just a few tests, it is still valuable to see if your code breaks when you try to install it in the build container.
You should set up a CI container for your WordPress project. And why not start a new habit while you are at it? How about if you wrote a test every time someone reported a bug in your WordPress product?
I haven’t included instructions for how to connect Circle Ci to your Git repository. This process is so easy and smooth and only requires a few clicks. Go to their website and check it out yourself.
Thanks for reading along. If you have any comments, please ping me on Twitter.