Better WordPress Plugin Updates: A GitHub-Powered Approach

At PIE, managing an array of small plugins across multiple clients and offering them publicly brings its own set of challenges. A paramount concern is keeping these plugins consistently up-to-date. The impracticality of manually uploading ZIP directories to a growing list of sites led us to explore a more efficient way, seamlessly integrating with WordPress’ native plugin update mechanism.

Enter YahnisElsts/plugin-update-checker 

Yahnis Elsts’ Plugin Update Checker library, a stalwart for over a decade, has been our go-to solution for many years. It provides a robust framework for developers looking for direct integration with WordPress’ native plugin updates. The process involves three main steps:

  1. Include the library in your plugin.
  2. Maintain a JSON file containing the latest version information.
  3. Host a ZIP directory of your plugin for users to download.

While effective, this manual process begs the question – why handle ZIP creation and JSON updates manually?

GitHub Pages: Hosting the JSON File

The second requirement of YahnisElsts/plugin-update-checker is that we host a JSON file somewhere so that the plugin update checker can refer to it and find out information about the latest version of our plugin to recognise when an update is required.

Instead of manual upkeep, GitHub Pages offers an automated solution. By maintaining an “update.json” file in the repository’s root and enabling Github Pages, the file becomes publicly accessible at https://<your username><your repo slug>/update.json. A simple commit to this file triggers the update checker to recognize a new version.

Using Github Workflows to build an artifact

GitHub Workflows are essentially docker-based task runners and provide an ideal solution for creating a distribution-ready ZIP artifact of our plugin. Leveraging these workflows streamlines the entire update process. The workflow, triggered on a new release, automates several key tasks.

We already use Github workflows to deploy many of our projects into development, staging, and production environments at PIE (our library of workflows is publicly available at, and our original flow was to use a Github workflow to build our zip and then transfer it via SSH to a linode we use, manually updating our JSON file to point to the new zip folder. That said, a little Google-fu revealed that if we created a named release of our plugin within Github itself, we could also upload a publicly available ‘artifact’ to that release. With this in mind, what is stopping us from using this to host the zip of our release for the Update Checker to download?

Triggering the Workflow on a New Release: Employing a GitHub Action (tag-release-on-push-action), the workflow runs only when a new release is ready. The subsequent steps utilize the version number for further operations.

This allows us to create a pull request against the main branch, and then this workflow will run only if it is labeled as release:major, release:minor, or release:patch. What is also really useful is that the step makes the next version number (be it major, minor, or patch) available to subsequent steps as an output.

The next step of our workflow only runs if check_for_release finds that it has a release label, and both builds our zip artifact and creates the release. The first few lines of this step are below, and perform some simple stuff like checking out the repo and installing our composer dependencies. If you needed to compile SASS or JS, you could also do that here.

Updating Version Numbers and Editing JSON: Before creating the ZIP, the workflow ensures version consistency across files. It dynamically adjusts version numbers in files like package.json, update.json, and others.

Build an installable ZIP

In the next step, we go about creating our zip artifact. Within our repo we choose to maintain a ‘.zipignore’ file, much like a ‘.gitignore’ this file lists everything in the repo that we do not want added to our distribution artifact – JSON files, .git related files, SASS, and so on. For convention, we name the zip folder with the same slug as the repository itself.

Finally, we create our release, adding the zip directory as an artifact

The end result is a new release added to the repo, with a correct version number, and a built artifact ready for downloading by a user, or to be pointed to by the Plugin Updater

This workflow has helped us with distributing plugins tremendously, and not having to host JSON and ZIP files elsewhere, being able to run everything out of a Github repository has saved us unimaginable time and effort.

You can find this workflow, along with other starter functionality in our WordPress Plugin Template over on Github: and you can see an example of it in use in many of our publicly available plugins at

Leave a Reply

Your email address will not be published. Required fields are marked *