A Better Way to Build a WordPress Plugin

Photo by Joan Gamell on Unsplash

A Better Way to Build a WordPress Plugin

Scaffolding a WordPress plugin using WP CLI, WP ENV, PHPUnit and adding CI/CD with GitHub Actions

ยท

3 min read

There's a lot of cool new WordPress projects around, but sometimes it's difficult to get them all working together. A while ago, I found the WP CLI, and then I found the WP Scaffold Plugin command. It's a great way to setup a new plugin, however you need to have a WordPress environment set up already, and you need to install a bunch of things like composer and svn in order to run the Unit Tests that come with the plugin.

Then I came across wp-env, which is a really great way of booting up a virtual WordPress environment without having to install anything. So how do we make these two things work together?

How its Done

First off, you create a new folder and set up wp-env

npm init && npm install --save-dev @wordpress/env

Next you add "wp-env": "wp-env", to your package.json

{
  ...
  "scripts": {
    "wp-env": "wp-env"
  },
 ...
}

Then, you create a .wp-env file

{
  "plugins": [
    "."
  ],
  "config": {
    "WP_DEBUG": true,
    "SCRIPT_DEBUG": true
  }
}

Ok, so running npm run wp-env start will boot up your WordPress environment now, and you should be able to access it at localhost:8888. Next up, we create our new plugin

npm run wp scaffold plugin 'my-plugin-name' --dir=.

And that's it. You should have a shiny new plugin, and a clean WordPress install to build and test it. But what about the unit tests I hear you say? Well the default unit tests that come with WordPress won't run without some additional setup, so lets do that now.

Create a composer.json file in the root directory and add the following

{
  "require-dev": {
    "yoast/phpunit-polyfills": "^1.0"
  }
}

Then you need to include the library at the top of the /tests/bootstrap.php file

<?php 

require dirname(dirname(__FILE__)) . '/vendor/yoast/phpunit-polyfills/phpunitpolyfills-autoload.php';

Our unit tests should work now, but there's no tests to run yet. So we copy /tests/test-sample.php to /tests/test-my-plugin.php. Just make sure the filename starts with test, otherwise it wont work.

Ok, we're ready to go now. Run the tests via

wp-env run phpunit 'phpunit -c /var/www/html/wp-content/plugins/my-plugin/phpunit.xml.dist --verbose'

Yes that's a long command to remember, so you can add it to your package-json file and free up some space in your brain ๐Ÿ˜. Now just run npm run unit:php and thats it.

{
  ...
  "scripts": {
    "wp-env": "wp-env",
    "unit:php": "wp-env run phpunit 'phpunit -c /var/www/html/wp-content/plugins/my-plugin/phpunit.xml.dist --verbose'"
  },
 ...
}

If only we could make all this easier!

Ok, so thats actually a lot of work. So that's what this script does. It automatically configures and sets up the environment, the new plugin and sets up the unit tests as well.

If you want to try it out, download and run the script, enter the name of your plugin and make yourself a cup of coffee โ˜•

But Wait, there's more... GitHub Actions

Now that we have our plugin set up, we can configure this to work with GitHub Actions too. At the root of the plugin, add a folder called .github/workflows/ and in that folder, create a file called 'unittest.yml' (the unittest file name can be anything).

Now, every time you push your code to the main, your unit tests will also run (Just remember to change the 'my-plugin' line in the code below.

name: CI

on:
  push:
    branches:
      - main

jobs:
  unit-php:
    name: Integration Tests
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Use Node.js
        uses: actions/setup-node@v3
        with:
          node-version: "16.x"

      - name: NPM Install
        run: npm ci

      - name: Run Unit Tests
        run: |
          npm run wp-env start
          npm run wp-env run composer 'install --no-interaction'
          npm run wp-env run phpunit 'phpunit -c /var/www/html/wp-content/plugins/my-plugin/phpunit.xml.dist --verbose'
ย