RFC #17: Experiments and the Economics of Open Source

RFC #17: Experiments and the Economics of Open Source. I joined Nadia and Mikeal to discuss my work on WP-CLI, the economics, origins, staying productive as a maintainer, fund raising, and the state of WP-CLI "today" (aka last May when this was recorded).

Update: I forgot I said this: "[The GPL] is used often as a blunt instrument for enforcing certain economic dynamics around everyone's businesses." Pretty good!

WordPress needs automated browser/integration/end-to-end testing

One thing I love most about WP-CLI is its Behat-based test suite. In fact, if you consider WP-CLI successful at all, I'd attribute said success to the test suite.

Having a great test suite ensures exceptional build quality because:

  • It’s easy to write new tests, which means they actually get written.
  • The tests interface with a command in the same manner as users interface with a command, and they describe how the command is expected to work in human-readable terms.

WordPress should have amazing integration tests too.

Historically, PhantomJS has been the de-facto standard for headless browser testing. PhantomJS is also Yet Another Abandoned Open Source project, and generally a pain to deal with. But we're in luck! Headless Chrome shipped in Chrome 59. It's pretty amazing. For your next side project, try out the Puppeteer library.

Now that we're over the headless browser hurdle, implementing automated browser testing is simply a matter of:

  1. Picking a framework. Behat is one option (see WordHat for an example), and Codeception is another. I like Behat, but Codeception is based on PHPUnit which might be a perk.
  2. Setting up a Docker container to provide a WordPress install in an isolated environment. For ease of use, Chrome headless could be provided in another container.
  3. Writing some tests. Prior to writing tests though, it would be helpful to plan out all major UX flows we want to cover with tests.

In fact, I'd argue that integration tests will be key for managing breakage when Gutenberg lands in WordPress core.

What would be really neat is if the test suite supported importing some base "state", such that it'd be possible to easily run the same test against dozens of scenarios. This would let us perform an experiment where run the test suite against every plugin in the WordPress.org plugin directory.

So good

A limited set (199 in total) will be headed to WordCamp Europe next week for WP-CLI’s biggest fans.

10 advanced WP-CLI tricks

These examples are adapted from my “WP-CLI: Advanced Usage” VIP Workshop presentation last week. I will now only ever use GIFs in slides.

wp-cli update --nightly

Live life on the bleeding edge by running latest and greatest version of WP-CLI.

The master branch is typically stable enough to use in local and staging environments. Or production too, yolo.

wp scaffold theme-tests

You probably knew you could scaffold plugin tests, but you probably didn’t know that you could also scaffold theme tests.

wp scaffold theme-tests gives you everything you need to write PHPUnit tests that leverage the WordPress test suite. Specifically:

  • bin/install-wp-tests.sh is a setup script to download the WordPress test suite and create the test database.
  • .travis.yml is a configuration file to automatically run your tests every time you push to GitHub (Travis account required).
  • tests/ contains the PHPUnit-specific files. You can modify test-sample.php to your liking.

Functionally, theme tests are pretty much the same as plugin tests. Check out the generated tests/bootstrap.php file for the secret of how your theme gets loaded into the test suite.

wp role reset

If you’ve been monkeying about with core’s default roles, wp role reset will set them back to the basics.

Reset a single role, or reset them all with --all.

wp rewrite list --match=<uri>

Rewrite rules are WordPress’ API for routing URI patterns to WP_Query instances.

For historical reasons, rewrite rules are stored in an option, which means you need to “flush” (regenerate) rewrite rules any time you register a new one.

The --match=<uri> argument makes it possible to see which rewrite rules match the URI you’ve provided, making it simple to debug why your rewrite rule doesn’t seem to be working. Because rewrite rules never work the first time.

wp shell

Ever wish you could literally write and run PHP code against WordPress?

Well, now you can. Actually, you’ve been able to for years.

wp site empty

If you want to delete all content in your WordPress install, but keep users, options, etc., wp site empty is your new best friend.

wp cron event run

After the Rewrite API, WP Cron is the WordPress developer’s second most bane of their existence. It’s opaque, buggy, and unreliable.

But, we have to use it, so we may as well make it easier to work with.


There are some commands I still can never remember the arguments for.

--prompt works with any WP-CLI command, even those you write yourself, and interactively walks you through all of the arguments you need to complete.


WP-CLI supports global- and project-based configuration files to accelerate your workflow.

For instance, if you use the same command with the same arguments over and over again, you can define those arguments as the default arguments for the command.

“Ugh, I always have to enter the same username and password when installing WordPress”… no you don’t!


You must be a WP-CLI master.

Here are four challenges for you to complete (with WP-CLI) in two minutes or less. For the solution, click on the link to see the GIF:

Managing an open source project

Xavier Borderie sent me a series of questions via email about managing an open source project. My responses are primarily from the perspective of managing WP-CLI.

How do you organize daily/weekly schedules so that community PRs are not forgotten? 

Call me a glutton for punishment, but I receive email notifications for all the GitHub activity of projects I manage. I use email because:

  • Email is easy to quickly process with keyboard shortcuts.
  • Email keeps track of read/unread state for me.
  • As needed, I can create filters to help manage my information flow.

Ultimately, this means I see a pull request as soon as it comes in (or, at least, when I check my email).

When I see the pull request come in, I take some form of action on it. This action is either:

  • Make a judgement as to whether the pull request will be able to land — yes without additional changes, yes with additional changes, or no.
  • Determine I’ll need to set aside dedicated time to review (and make a judgement).

In both cases, I respond to the contributor accordingly. In the latter case, I add the code review to my task management tool, and come back to it when I have the bandwidth.

All of this hopefully underscores I think it’s important to communicate well, and handle contributions in a timely, effective manner.

How do you manage with contributions which need rebasing, amending and/or tweaking — and the contributor is silent for months?

WP-CLI has a two-week abandonment policy. If we don’t hear from you in two weeks, then we consider the pull request is abandoned.

Usually around day 10, I’ll reach out on the thread and as the contributor if they’ll be coming back to finish up. They respond most of the time, with either “yes, just need another day or two” or “no, I’m too busy now.”

When a pull request is abandoned and I want to land the code anyway, I’ll fork their branch so they still get credit for the work they’ve done and finish it up.

Does every team member manages her/his own time, or do you clock community-related work?

My dba, Hand Built, actually just a business of me, myself, and I. In 2015 (the last year I calculated it), I spent 12.26% of my time contributing to open source.

This year, things are bit different. Not only do I get paid (on a part-time basis) to maintain WP-CLI, but I have the budget to eventually hire a couple more part-time maintainers. The first is ramping up right now.

The expectation is that each of us commits an average of five to ten hours per week towards project. The theory is this is enough time to make regular, substantial contributions to the project, while also having enough of a foot in the real world to focus our effort on what’s most important. Each person is expected to manage her/his own time, balancing WP-CLI with the rest of their life as they see fit.

What was the impact of 5 For the Future for you when it was launched, and do you feel the 5FF campaign is still relevant/followed today?

For those who aren’t in the loop, “5 For The Future” was/is a call by Matt Mullenweg for companies to dedicate 5% of their people towards the WordPress project:

I think a good rule of thumb that will scale with the community as it continues to grow is that organizations that want to grow the WordPress pie (and not just their piece of it) should dedicate 5% of their people to working on something to do with core — be it development, documentation, security, support forums, theme reviews, training, testing, translation or whatever it might be that helps move WordPress mission forward.

Personally, I’m not sure how much of an impact 5FF specifically had on increasing the labor pool for the WordPress project. It seemed to be more of a one-time rallying cry than anything else.

I don’t mean to discount the intent, though. While the WordPress project could certainly benefit from more labor capacity, it certainly has a lot already from a healthy variety of companies. Furthermore, introducing more labor to the project also requires scaling up capacity to direct the labor.

On the other side, five percent of people seems to be a very challenging goal for many companies. If I were to put a number to it, it seems like most companies engaged with open source would be in the one to two percent range.

Which isn’t to say it’s not important for companies to more effectively support the open source projects they depend on. Contributing to open source is still hard: it’s a lot of overhead to stay regularly engaged with a project, and difficult to account for the benefit of the contributions.