Using GitHub for WordPress Plugin Development

Over the years I have developed several different plug-ins for WordPress, and contributed them to the plugin directory. In that time, many things have changed about source code management, while WordPress has not moved on.

For those that don’t know, the WordPress plug-in directory is still using SVN (Subversion) for submitting plug-ins. Back 2012 when I first submitted a plugin, this was perfectly fine. SVN will still very popular, SourceForge was the king of open source software version control repositories, and life was good.

Fast forward to 2023, and well, that’s not so much the case anymore.

GitHub has become a huge repository of open source source code and has featured that SourceForge could never dream of.

While there has been some consternation around Microsoft’s purchase of GitHub, that doesn’t seem to have had a major impact so far.

So what’s the best way to use GitHub if you’re doing plugin development?

Well, GitHub Actions are going to be your best friend.

I won’t cover the basics of using Git here, you’re probably well familiar with it if you’re reading this post. But there are two issues that GitHub Actions can help you solve when hosting your plug-in on GitHub:

  • Generate a
  • Deploy a release to

Auto Generate a from readme.txt and GitHub use two different standards for their readme files, and while GitHub will display a readme.txt file, it will look very ugly. To fix this, you need to create and maintain a version of your readme.txt file, but that’s a manual task, unless you use GitHub Actions and a bit of grunt magic.

The first thing you’re going to want to do is make sure npm is installed, your distro should have it in the default software repositories:

npm --version

If you get an error, go figure out how to fix it.

Now you want to create a file called “package.json” in the root of your plugin git repo, add the following content to it:

  "devDependencies": {
    "grunt": "~1.5.3",
    "grunt-contrib-jshint": "~3.2.0",
    "grunt-contrib-nodeunit": "~4.0.0",
    "grunt-contrib-uglify": "~5.2.2",
    "grunt-wp-readme-to-markdown": "^2.1.0"

This tells npm that you want to install some packages here, the important one is grunt-wp-readme-to-markdown which will create a markdown version of your readme.txt file.

Now create a “Gruntfile.js” in the same directory:

module.exports = function(grunt) {

  pkg: grunt.file.readJSON('package.json'),
  wp_readme_to_markdown: {
	convert: {
	    files: {
	      '': 'readme.txt'
	    options: {
			screenshot_url: 'assets/{screenshot}.png'


grunt.registerTask('default', ['wp_readme_to_markdown']);


This file tells grunt what to do, in this case, run the readme converter. Note the options line, if your screenshots are somewhere other in an “assets” folder in the root of your git repo, you can change this line to point to the right location. See the grunt-wp-readme-to-markdown for details.

One last file to create here, if you don’t already have one, is “.gitignore”, add the following lines to it:


Ok, now it’s time to try converting your readme.txt to

npm i

The first line tells npm to install the modules you included in package.json, this might take a few minutes depending upon your connection. The second tells grunt to run the default action.

You should see output something like this:

added 245 packages, and audited 430 packages in 24s

npm -i
3 packages are looking for funding
  run `npm fund` for details

51 vulnerabilities (5 low, 15 moderate, 20 high, 11 critical)

To address issues that do not require attention, run:
  npm audit fix

To address all issues (including breaking changes), run:
  npm audit fix --force

Run `npm audit` for details.

Running "wp_readme_to_markdown:convert" (wp_readme_to_markdown) task
File "" created.

Done, without errors.

You may see additional warnings based upon your distro, but as long as it doesn’t generate an error you should be fine.

You should now have a nicely formated MarkDown version of your readme.txt.

This is good, but it kinda sucks having to generate and commit it each time you update your readme… so this is where GitHub Actions come in to play.

Now create a directory called “.github/workflows” in the root of your repository. Then create a new file there called “readme-md-generator.yml” with the following content:

name: Generate from readme.txt

    branches: [ "main", "master" ]
    paths: [ "readme.txt" ]

    runs-on: ubuntu-latest

        node-version: [18.x]

    - uses: actions/checkout@v3

    - name: Use Node.js ${{ matrix.node-version }}
      uses: actions/setup-node@v3
        node-version: ${{ matrix.node-version }}

    - name: Build
      run: |
        npm install
        git config --global '${{secrets.GIT_USERNAME}}'
        git config --global '${{secrets.GIT_EMAIL}}'
        git commit -am "Regenerate"
        git push

This action will regenerate your file every time readme.txt is committed to the main/master branch of your plugin, and then commit it back to your repo.

Before you can run this action though, you need to create two secrets in your repository:

  • GIT_USERNAME: Your GIT username (usually something like “First Last”)
  • GIT_EMAIL: Your GIT e-mail address

Go over to your GitHub repo settings and find Secrets->Actions to set these two values up. Make sure to do this before committing the rest of the changes to your repo, otherwise the GitHub Action will fail the first time it is run.

Now you can commit all of the above changes to your repo. If you want to recover some local space, you can remove the “package-lock.json” file as well as the “node_modules” if you don’t want to manually generate the file in the future.

Once commited, the file should be generated every time you make a change to the readme.txt file on GitHub.

Note: if you do not commit a file (with or without content) the Action will not work as it expects a file to already exist in the repo. Simply create an empty one and commit it to the repo.

Deploy a release to

Once you have readme file auto generating, the next big issue is deploying to Fortunately 10up has created a GitHub Action to do this for you.

Your first step is to create two additional secrets for your repo:

  • SVN_USERNAME: Your SVN username on
  • SVN_PASSWORD: your SVN password on

Now you can create another Action in your repo under “.github/workflows” called “wordpress-plugin-deploy.yml”:

name: Deploy to
    types: [published]
    name: New release
    runs-on: ubuntu-latest
    - name: Checkout code
      uses: actions/checkout@v2
    - name: WordPress Plugin Deploy
      id: deploy
      uses: 10up/action-wordpress-plugin-deploy@stable
        generate-zip: true
        SVN_USERNAME: ${{ secrets.SVN_USERNAME }}
        SVN_PASSWORD: ${{ secrets.SVN_PASSWORD }}
    - name: Upload release asset
      uses: actions/upload-release-asset@v1
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        ASSETS_DIR: assets
        upload_url: ${{ github.event.release.upload_url }}
        asset_path: ${{ }}
        asset_name: ${{ }}.zip
        asset_content_type: application/zip

This action will deploy a new version of your plugin to every time you create a release on GitHub. It will also generate a zip file an attach it to the GitHub release for you.

Of note here is the “ASSETS_DIR” variable, just like with the screenshots on the generator, this is the location of your assets. If they are somehwere else, set this variable to that directory.

You can also setup this Action to fire when you tag your code instead of release it, you can see more details over on the WordPress Plugin Deploy page.


And that’s it!

You now have an automated way to generate for GitHub and automated deployment to for your plugins.

There are a few other things that could be automated with GitHub Actions:

  • 10up has the “ Plugin Readme/Assets Update” Action, however I have a php script to do this separately.
  • Readme and plugin version updates on release. At the moment you have to manually update your plugin version, both in the plugin file as well as the readme. This could probably be automated with an Action during the release Action.
Avatar photo


Greg is the head cat at JumbleCat, with over 20 years of experience in the computer field, he has done everything from programming to hardware solutions. You can contact Greg via the contact form on the main menu above.

More Posts - Website

Avatar photo


Greg is the head cat at JumbleCat, with over 20 years of experience in the computer field, he has done everything from programming to hardware solutions. You can contact Greg via the contact form on the main menu above.

Leave a Reply