CAll Us: +1 888-999-8231 Submit Ticket

Use WordPress Testing Tools to Build Your Plugin & Run Unit Tests in Github Actions

We’ve been talking a bunch about unit tests lately, starting with the basics, and then moving up to adding tests to a plugin, so you could see it in practice. We’ve also covered how to use Github Actions to deploy your site automatically to your host. Today, we’re going to take pieces from both of these concepts and combine them, so that we’re running our tests automatically with Github actions when we push new code to the repository.

The easiest way I’ve found to get started is with WP Testing Tools from Valu Digital. The team at Valu Digital has provided a fairly easy way to get your tests up and running on Github Actions. We’re only going to cover how to use their base template to start from scratch with your plugin development so that you can run tests. Adding their test setup to an existing plugin takes a bit more work.

Add WP Testing Tools Setup to an Existing Plugin

To start, clone the repository onto your local computer.

git@github.com:valu-digital/wp-testing-tools.git your-plugin-name

Next, we need to grab the plugins folder from inside the repository as that will be the base for our plugin. Migrate that folder to where you want your new plugin and rename it to match the plugin name you want to use. 

Dealing with Composer

This testing setup requires Composer, which you don’t need to be intimately familiar with today. I’ll cover Composer in detail in a future post. For now, you’ll need to run composer install to install the required dependencies for WP Testing Tools.

Unfortunately, I’ve found that the repository is missing some required Composer packages so we’ll need to make sure these are also installed with the following commands.

composer require codeception/module-rest --dev 

composer require codeception/module-phpbrowser --dev

composer require codeception/module-db --dev

composer require codeception/module-asserts --dev

composer install

Wait, I got memory errors with Composer. Help! It probably doesn’t matter and you shouldn’t get them in Github Actions so you can ignore it for now.

Now we have the proper tools installed, you can push to Github and you’ll see that the unit tests run without issue. This plugin still isn’t ready for us to build on though so let’s get to renaming the other strings in it and make it our own.

Setting Up Plugin Files

We can start by renaming the plugin header information found in plugin.php. Name it whatever suits your plugin and make the author yourself. We’ll also need to change the namespace and class entries so that we’ve named them properly for our project. I’m changing the namespace to my company name and using PluginBase as my class name for this tutorial. You can see my working renamed file below. I’ve also cleaned up the comments to make it easier to read.

<?php

/**

 * Plugin Name: Hostdedi - Github Actions Unit Tests

 * Plugin URI: https://nexcess.net

 * Description: Plugin base that runs unit tests with Github Actions

 * Author: Curtis McHale

 * Version: 0.1.0

 *

 * @package example

 */

 if (!class_exists('SfndesignPluginBase')) {

    require_once __DIR__ . '/vendor/autoload.php';

 }

SfndesignPluginBase::init();

Now in composer.json, we have a few things to change around as well. Make sure that you’re listed as the author of the plugin and change the links to Github Issues and Source to match your repository. You’ll also need to change the namespace of your plugin under the autoload entry. I’m using my company name so mine says Sfndesign. You can see my changed composer.json file below.

{

  "name": "sfndesign/pluginbase",

  "description": "Actions Plugin",

  "type": "wordpress-plugin",

  "license": "GPL-2.0-or-later",

  "authors": [

    {

      "name": "Curtis McHale",

      "email": "curtis@curtismchale.ca",

      "role": "developer"

    }

  ],

  "require-dev": {

    "valu/wp-testing-tools": "^0.4.0",

    "lucatume/wp-browser": "~2.2",

    "codeception/module-rest": "^1.2",

    "codeception/module-phpbrowser": "^1.0",

    "codeception/module-db": "^1.0",

    "codeception/module-asserts": "^1.3"

  },

  "autoload": {

    "psr-4": {

      "Sfndesign\": "src/"

    }

  },

  "scripts": {

    "wp-install": "wp-install --full --env-file .env --wp-composer-file composer.wp-install.json",

    "wpunit": "codecept run wpunit",

    "functional": "codecept run functional",

    "test": [

      "@wpunit",

      "@functional"

    ]

  },

  "config": {

    "optimize-autoloader": true

  },

  "support": {

    "issues": "https://github.com/example/example/issues",

    "source": "https://github.com/example/example"

  }

}

Now we need to change the name of the Example.php file found in the src directory. I’m going to call it PluginBase.php to stick with the format we’ve been using. Next, open that file and change the namespace to Sfndesign and the class name to PluginBase. You can see the adjusted file below.

<?php

namespace Sfndesign;

class PluginBase {

    public static function init() {

        define( 'EXAMPLE', 'initialized' );

        add_action('the_title', function () {

            return 'EXAMPLE TITLE MOD';

        });

    }

}

Now that we’ve made these adjustments we need to run composer update again so that Composer registers the new autoload paths that are needed with our renamed files.

Finally, to make sure the whole thing is working well, I find it easier to change their initial test found in tests/ExampleTest.php to something that will return true no matter what. You can see this code below.

 public function testInit()

    {

        $this->assertTrue(true);

    }

Now that we’re set up, you can initialize your plugin as a git repository and then push it to Github. Once you’ve done this you should see an action running under the Actions tab for your repository and everything will come back green because your unit test has been run.

Throughout the last few posts, we’ve written tests and used Github Actions to automate parts of our process. Now, it’s up to you to use these tools in your client projects. You won’t write tests later, so make sure you start your projects with tests from the beginning. If you want to go even deeper with testing there is an excellent course by Fränk Klein that explains Unit Testing in WordPress. It’s already on my list to go over so that I can get better at my testing practices.

Source link

Deploy WordPress with Github Actions

A while back I showed you how to deploy your WordPress site with Deploybot. I’ve used this service for years now, but when I started, it was out of my price range, so I used nothing and made many mistakes deploying my sites which cost me many lost hours and some tears.

Today, I’m going to walk you through how to use Github Actions to deploy your site automatically for no cost. The set up is more complex than Deploybot, but it’s going to be free for most projects.

This post has a bunch of working parts so set aside some time, especially if you haven’t worked with Git or SSH keys before. We’re going to cover:

  • Creating a Hosting Account
  • Getting your code into Git
  • Creating special deploy SSH keys for Github to use
  • Configuring the Github Actions YAML file
  • Using Github repository secrets to keep private information safe
  • rsync via ssh

What Are Github Actions?

Github Actions is a feature of Github that allows you to automatically perform tasks based on the state of your code. Today, we’ll look at deployment, but you could also have an action to run your unit tests or notify a Slack chat when someone makes a new PR on your project.

While they may take a bit of time and effort to set up your first time, they return the investment by letting you get back to code instead of worrying about repeating the same work over and over. 

Getting Your Site Set up

The first thing you’ll need is to create a hosting account on Hostdedi, so head over and check out the plans available. The Maker WordPress plan is a good plan if you’re hosting a few sites.

With your site set up, go to the backups and create a backup of the site before you do anything else. Make sure you download this backup as well so you have a copy on your computer…just in case.

Unzip the backup and then copy out the public_html folder to use as our git repository. You can remove the wp-config.php file because we won’t need it today.

Now that we have our copy of the repository downloaded, let’s add it to Github. To start we’ll need to create a new repository in Github. Add your title and whatever description you want, I usually don’t initialize the repository with a README because I’ll provide my own with any project-specific notes and documentation for a client project.

Next, open up Terminal and cd into the downloaded copy of WordPress so you can initialize the repository with git init. The first thing we want to do is add our .gitignore file so that we don’t add any files that may overwrite what Hostdedi needs to run your site. You can use the .gitignore file provided below.

The top eight lines are specific to Hostdedi, so make sure you copy those lines if you have your own preferred ignore configuration.

If you’re not familiar with Git, check out my post on Introduction to Git.

.htaccess

wp-config.php

wp-content/uploads/*

wp-content/cache/*

wp-content/upgrade/*

wp-content/advanced-cache.php

wp-content/object-cache.php

wp-content/mu-plugins/*

config/app_config.yml

config/database.yml

config/*.sphinx.conf

config/s3_credentials.yml

*~

*.cache

*.log

*.pid

tmp/**/*

.DS_Store

db/cstore/**

db/sphinx/**

doc/api

doc/app

doc/plugins

doc/*.dot

coverage/*

db/*.sqlite3

*.tmproj

*.sw?

*.esproj

_notes*

dwsync.xml

podcast.xml

*.kpf

*uploads/*

*.swp

*.idea

*.sublime-project

*.sublime-workspace

*/node_modules/*

tags

*.bak

cache/*

managewp/*

Now that you have the ignore file ready, use git add and git commit to add the WordPress files to your repository. Then push those files to your Github repository.

Creating a Deploy SSH Key for Github

To deploy our site via Github Actions, we’ll need an SSH key for the action to use. Do not use your regular SSH key.

To generate the SSH keys needed use the command below using your email. When prompted for a passphrase, press enter and leave it blank. When you’re asked for a location, choose a location to store them temporarily. You can find Github’s documentation on SSH keys with extra details here.

ssh-keygen -t rsa -b 4096 -C "your_email@example.com"

Before we take the next step, make sure your new SSH keys are stored safely. I store them in my 1Password vault alongside the other server credentials. Don’t leave them sitting in some folder on your computer because if someone gets your keys they get access to any server those keys are used on.

Now, open the public key (the one that ends in .pub) and open it in the text editor of your choice. In your Hostdedi account, click on your account name in the top right corner and select SSH Keys.

Next, select Add Key and copy/paste the whole key out into the main text field. Make sure to label your key properly so you can tell what the key is being used for.

Finally, click Add to save the key to your account.

Adding and Configuring Your Github Action

Before we start to build our action, we’ll need some secret information stored in our account. Stuff like our private key for the key pair we just created, the location of our server, and the entry for the known_hosts file.

Start this by choosing Settings from the top right of your repository. Then choose Secrets from the left column. We’re going to add 3 different values.

  1. DEPLOY_SSH_KEY: This is the private key we generated (doesn’t have .pub at the end)
  2. NEXCESS_LOCATION: The location SSH will access on our server plus the file path to your html directory. Making a mistake here could delete your site, but this is why we took a backup.
  3. NEXCESS_HOST: The allowed host file we need from our server

You already have 1 so open your key file and copy it’s entire contents into a secret called DEPLOY_SSH_KEY.

Next, you can get the location of your server from your Hostdedi control panel for your site under the Access menu.

Finally, the easiest way to get the content for NEXCESS_HOST is to ssh into your server from your computer. This should prompt you to accept a new known server. Accept the new server and then you can head to ~/.ssh/known_hosts and get the last line in the file for the secret you need to add to your repository.

Why are we keeping this stuff secret? Each of these pieces of information has some security risk so you don’t want them in your repository. Putting them in a secret variable in Github makes sure you don’t expose information by accident.

We’re ready to head back over to our repository on Github and get our action going. Start by going to the Actions menu at the top of your repository and click on it. While there are lots of prebuilt actions, we’re going to start by creating our own action so select that from the Actions screen.

Doing this will give you a basic workflow file written in YAML. By default, it works only on your master branch, but by changing which branch is in the arguments on lines 9 & 11 you can make it work for a different branch. You may do this if you wanted to deploy from a staging branch to a staging site and from master to the live site.

Starting with the line below, delete the rest of your default workflow file.

# Runs a single command using the runners shell

    - name: Run a one-line script

      run: echo Hello, world

Now we need to get our SSH agent. On the right hand side of the workflow screen search for webfactory/ssh-agent.

Click on this and it will provide you with some commands to copy and paste into the bottom of your file, but we’re going to use our own custom script. Copy the code below and paste it into your workflow file below the actions/checkout@v2line.

   # Setting up SSH

    - name: Setup SSH agent

      uses: webfactory/ssh-agent@v0.4.0

      with:

        ssh-private-key: ${{ secrets.DEPLOY_SSH_KEY }}

    - name: Setup known_hosts

      run: echo '${{ secrets.NEXCESS_HOST }}' >> ~/.ssh/known_hosts

    - name: Sync project files

      run: rsync -uvzr --backup --backup-dir='~/deploy-backup/' --exclude 'wp-config.php' --exclude '.gitignore' --exclude '.git/*' --exclude 'wp-content/uploads/*' --exclude '.htaccess' --exclude 'wp-content/cache/*' --exclude 'wp-content/advanced-cache.php' --exclude 'wp-content/object-cache.php' --exclude 'wp-content/mu-plugins/*' ${GITHUB_WORKSPACE}/ ${{ secrets.NEXCESS_LOCATION }}

You can see the secrets we set up earlier in this file. It starts by pulling in the ssh-agent and adds our private DEPLOY_SSH_KEY to the server it’s getting ready in the background. Next, it adds our server as a known host.

It finishes by syncing the project files over to the live server in a long rsync command. In short, it backs up the remote server into a directory called deploy-backup and then moves any new files in the Github project over to the live server. We excluded all the same location we ignored in our original .gitignore file so that rsync doesn’t touch them by accident.

If you want to read up on each rsync command there, I usually refer to this Ubuntu documentation on rsync

Now all you need to do is make some changes in your repository and then use git to add and commit them to your repository. Push those changes to Github, and the action will automatically backup your files and then push your changes over to your site.

If you’re new to automatic deployments, this does seem like a lot of work. Even my first time using Github Actions to deploy my site I spent a few days working on the script. This doesn’t feel like it saves time until I’m using the same script for weeks with a project deploying regularly.

Automating your deployment, and taking the time to get it right, means you never accidentally overwrite the wrong files, put the wrong files in the wrong directory, or make any other of the many mistakes I’ve made moving files around in the 12 years I’ve been building sites.

A day or two of time spent configuring deployment for your first time is worth saving that pain.

Source link