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 readme.md
  • Deploy a release to wordpress.org

Auto Generate a readme.md from readme.txt

WordPress.org 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 readme.md 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) {

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

grunt.loadNpmTasks('grunt-wp-readme-to-markdown');

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:

node_modules/
package-lock.json

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

npm i
grunt

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.

grunt
Running "wp_readme_to_markdown:convert" (wp_readme_to_markdown) task
File "readme.md" 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 readme.md from readme.txt

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

jobs:
  build:
    runs-on: ubuntu-latest

    strategy:
      matrix:
        node-version: [18.x]

    steps:
    - uses: actions/checkout@v3

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

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

This action will regenerate your readme.md 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 readme.md file in the future.

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

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

Deploy a release to wordpress.org

Once you have readme file auto generating, the next big issue is deploying to wordpress.org. 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 wordpress.org
  • SVN_PASSWORD: your SVN password on wordpress.org.

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

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

This action will deploy a new version of your plugin to wordpress.org 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 readme.md generator, this is the location of your wordpress.org 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.

Conclusion

And that’s it!

You now have an automated way to generate readme.md for GitHub and automated deployment to wordpress.org for your plugins.

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

  • 10up has the “WordPress.org 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.

SSL on Jumblecat… Update 2!

[sc:wordpress-category ]I’ve posted twice before about installing SSL on JumbleCat and this is just a quick follow up with some new information from BraveNet.

In the original post I mentioned that BraveNet uses a reverse proxy and I had to add the following code to the WordPress config file:

if ($_SERVER[‘HTTP_X_FORWARDED_PROTO’] == ‘https’)
 $_SERVER[‘HTTPS’]=’on';

Apparently BraveNet had been working on this problem in the background and after I had contacted them about the issue in the second post they followed up (great customer service by the way) and let me know that they were implementing a fix on their end for that exact problem.

As of last Tuesday (June 30th), you no longer have to add the above code as the BraveNet web servers know when a client connection has been made with HTTPS and sets the variable to ‘on’.

They’re also looking at setting the port value correctly (WordPress doesn’t use this but some software does) in a future update.

SSL on Jumblecat… Update!

[sc:wordpress-category ]When I posted a few weeks ago about install SSL on JumbleCat I had a pretty easy time of it.

However after working a bit with and Android device I noticed I couldn’t get access to JumbleCat, Chrome came up with an error:

NET: ERR_CERT_AUTHORITY_INVALID

I took a look around the net and it turns out that this error is caused by an incomplete SSL chain.  This turns out to be on the server side and after a quick e-mail to the BraveNet support folks I had a fix.  When you install the certificate on the BraveNet hosting control panel, you have to include both the StartSSL certificate you generated for you site, as well as the intermediary certificate for StartSSL (which can be found here).

You do this by pasting the intermediary certificate to the end of the file site certificate and upload both to BraveNet at the same time.

Once done, Chrome on Android works fine.

SSL on Jumblecat

[sc:wordpress-category ]So a few weeks ago I mentioned in my hosting post that Bravenet didn’t support SSL, however apparently they do, it’s just a little bit buried.

So I decided to move JumbleCat over to https to give it a try.  First of course was getting an SSL certificate.

Traditionally SSL certificates are expensive and hard to get, primarily due to a decision made when the SSL standard was being made to combine identity and encryption in to the certificate.  There is a trend starting though to separate the two to some degree and providers like GoDaddy and StartSSL provide SSL certificates with just an e-mail confirmation.

I’ve used GoDaddy before and they provide a good service, however there is still a cost associated with the cert and I decided to give StartSSL a try.  When I first tried to sign up I received a message that they were too busy to process my request, but I tried again a few minutes later and go in all right.

The sign up process was straight forward, however once complete the site takes you back to the main screen without telling you a message has been sent to your e-mail with the next steps.

That e-mail takes a little while to get to you, but once it does it has the steps to install your e-mail certificate that they use to authenticate you in their dashboard.  If you try to connect to the dashboard before installing the cert you get a strange error message that isn’t very obvious.

Once I had the cert installed though everything was smooth and getting a certificate for JumbleCat was straight forward.

Installing the certificate on Bravenet was easy enough as well, there’s no configuration required once you have set the private key and certificate information.

The next step was to configure WordPress to use https and this is where the first real problem came up.

The first step is to go to the admin dashboard in WordPress and then change the WordPress and Site URL’s to use https.  This broke pretty badly and didn’t let me login to JumbleCat again.  After hunting around a bit I found that Bravenet uses a reverse proxy between the internet and the actual webhosts, which meant I had to add the following lines to wp-config.php:

if ($_SERVER[‘HTTP_X_FORWARDED_PROTO’] == ‘https’)
$_SERVER[‘HTTPS’]=’on’;

I also added the following to force the admin pages and login page to use https:

define( ‘FORCE_SSL_LOGIN’, true );
define( ‘FORCE_SSL_ADMIN’, true );

After that things went smoothly and the site came back up.

I also installed “WordPress Force HTTPS” in WordPress to force everything over to https.

There are a few things that need to be update after https is working:

  • If you have an avatar image you’ll need to reselect it to use https.
  • Links in your posts which use http will need to be converted to https.

The second issue is the biggest by far.  A blog like JumbleCat currently has hundreds of posts and updating them by hand.  Instead I used “Velvet Blues Update URLs” which automatically updated all the links for me.

I’m sure I’ll find a few more small things over the next few weeks, but for now everything seems to be working well.

Happy 4th Birthday JumbleCat! AKA JumbleCat WordPress Plugins Update

[sc:wordpress-category ]It’s hard to believe that this blog is four years old and that this is my 262nd post.  That seems like a lot of writing 🙂

In the past I’ve done a series of posts about what WordPress plugins I use and I thought at four years out it would be a good time to do so again.

Instead of going over the add/delete’s (it’s getting hard to keep track of them any more), I’m just going to list all the plugins I use:

 

Add Admin CSS

Plugin’s Description: Interface for easily defining additional CSS (inline and/or by URL) to be added to all administration pages.

At the moment I have this installed but no CSS in it.  The WordPress admin interface has come a long way and no longer needs nearly as much help.

Add Admin JavaScript

Plugin’s Description: Allows Interface for easily defining additional JavaScript (inline and/or by URL) to be added to all administration pages.

I use this to add a little JavaScript to the admin pages so that when I click on a link (either for the front end or an external site) it opens in a new tab instead of “stealing” my current session.

Admin Post Navigation

Plugin’s Description: Adds links to navigate to the next and previous posts when editing a post in the WordPress admin.

This is handy if you want to move between posts without having to go back to the post list.  Just one of those little plugins that are useful in certain circumstances and probably should be part of the core WordPress install.

Advanced Automatic Updates

Plugin’s Description: Adds links to navigate to the next and previous posts when editing a post in the WordPress admin.

Advanced Automatic Updates does pretty much what it says, when an update to either the WP Core, plugin or theme is available, it automatically installs it.  You can select which of the three you want to do and it sends you a nice little e-mail when it runs so you know something has changed on your site.

After The Deadline for Comments

Plugin’s Description: Makes your comments form have After The Deadline capabilities.

This plugin allows your users to use After the Deadline when writing comments, a nice touch that hopefully improves the quality of the writing!

Always Remember Me

Plugin’s Description: One year auth cookie and ‘Remember Me’ checkbox always checked. “Log in” less often..

Nuff said.

Better WordPress reCAPTCHA

Plugin’s Description: This plugin utilizes reCAPTCHA (with support for Akismet) to help your blog stay clear of spams.

In this day and age, reCAPTCHA is pretty much the only way to keep spam bots off your site.

Bing Translator

Plugin’s Description: Enable visitors to translate your site in their language in one click with the Bing Translator.

I used to use Google to auto translate my site, but since they now charge for the service I’ve moved to Bing.

Configure SMTP

Plugin’s Description: Configure SMTP mailing in WordPress, including support for sending e-mail via SSL/TLS (such as GMail).

Most hosting providers don’t let PHP directly send e-mail, this plug allows WordPress to use a specified host and user/password information to send authenticated mail.  It will even use gmail if your hosting provider has no SMTP capabilities.

This is another configuration page that really should be built in to WordPress.

Contextual Related Posts

Plugin’s Description: Show user defined number of contextually related posts.

This plugin providers the list of “Related Posts” at the bottom of each article, it’s not the most accurate set of related posts, but is nice and simple and doesn’t rely on any extended information beyond what’s in the articles by default.

CYAN Backup

Plugin’s Description: Backup your entire WordPress site and its database into a zip file on a schedule.

Backing up your site is important and having some way to automatically move the backups to a remote host is nice as well.

Default Post Date and Time

Plugin’s Description: Set the default date and time when you create a new post.

I publish my blog posts on a schedule, this plugin simply makes it easier to set the schedule up for new posts.

Delete Me

Plugin’s Description: Allow users with specific WordPress roles to delete themselves from the Users → Your Profile subpanel.

This plugin allows a user to delete themselves.  Simple and to the point.

Duplicate Post

Plugin’s Description: Clone posts and pages.

A very handy plugin if you tend to write similar posts quite a lot.  Not so useful on JumbleCat but still nice to have.

Fast Secure Contact Form

Plugin’s Description: Fast Secure Contact Form for WordPress. The contact form lets your visitors send you a quick E-mail message. Super customizable with a multi-form feature, optional extra fields, and an option to redirect visitors to any URL after the message is sent. Includes CAPTCHA and Akismet support to block all common spammer tactics. Spam is no longer a problem.

This plugin allows for a contact form that doesn’t require a registered user to use it.

This plugin places its settings under the plugin’s menu in WordPress, which seems strange, but not a deal breaker by any means.

Grey Admin Color Schemes

Plugin’s Description: Grey color schemes for WordPress 3.8’s admin area.

When WordPress 3.8 came out, the admin area changed radically and the new colour scheme wasn’t much to my liking, this plugin adds a few more options.

Highlight Search Terms

Plugin’s Description: Wraps search terms in the HTML5 mark tag when referer is a search engine or within wp search results.

Another plugin that is aptly named.  If a user searches your site, this plugin highlights the search terms that were found on the page.

Inactive User Deleter

Plugin’s Description: When your project lives so long, and site got a lot of fake user’s registrations (usually made by spammers). This tool will help you to clean this mess up. You can filter, select and delete users.

Finally this plugin allows you to search for users based on various criteria and then delete them in bulk.  Useful if you have a lot of spam users that register.

Just Writing

Plugin’s Description: Adds buttons to the Distraction Free Writing Mode for all kinds of extra functions.

Distraction Free Writing Mode has been completely changed in WordPress 4.1, Just Writing adds in a whole new mode that brings back the old style and expands on it.

Login LockDown

Plugin’s Description: Adds some extra security to WordPress by restricting the rate at which failed logins can be re-attempted from a given IP range.

A simple enough plugin that gives the administrator some control over anyone trying a brute force attack against the site.  Another plugin that really should be part of the core.

OS Integration

Plugin’s Description: Integrate your site in to your users OS, Windows Live Tiles, icons for Apple and Android, iOS Web App!

Messing with all kinds of different favicons and other resources is a pain, this plugin makes it nice and simple.

P3 (Plugin Performance Profiler)

Plugin’s Description: See which plugins are slowing down your site. Create a profile of your WordPress site’s plugins’ performance by measuring their impact on your site’s load time.

This is a great performance tools, but I keep it disabled normally and just check the site every once in a while to make sure nothing is going wrong.

Posts by Type Access

Plugin’s Description: Adds a link to Drafts, posted and scheduled items under the Posts, Pages, and other custom post type sections in the admin menu.

A simple little plugin that expands the Posts menu in the admin console to include direct access to different post types.

Profile Links

Plugin’s Description: Adds links to each of the major sections of your profile at the top of the page.

A users profile page can get kind of long, this adds some nice jump links to the top of the page.

Rich Text Editor For Comments

Plugin’s Description: Replaces the regular dry textarea in comments with a lightweight fully customizable WYSIWYG Rich text editor.

Much like After the Deadline for Comments, this plugin enhances your users commenting life with the same kind of rich editor found when creating posts etc.   This plugin seems to have disappeared from WordPress.org and the author’s site doesn’t seem to be available right now either.

RSS Syndication Options

Plugin’s Description: Allows the administrator to set the update period and update frequency parameters for RSS feeds.

Such a simple but effective plugin, anyone who wants just a bit of control over their RSS feed should have it.

Schedule Posts Calendar

Plugin’s Description: Adds a javascript calendar to the schedule posts options.

Something that has always seemed missing from the WordPress admin interface for creating new posts was a way to schedule them with a popup calendar.  This plugin lets you do that and also adds a quick link to the posts list so you can reschedule a post without opening it.

Shareaholic

Plugin’s Description: Shareaholic adds a (X)HTML compliant list of social bookmarking icons to each of your posts.

A nice sharing link plugin, it has several options I didn’t find in other’s, namely printing and e-mail options.

The one thing I don’t like about the plugin is that it adds a new top-level menu instead of nesting itself under one of the existing menu’s, but it’s a small price to pay.

Shortcoder

Plugin’s Description: Shortcoder is a plugin which allows to create a custom shortcode and store HTML, Javascript and other snippets in it.

A while ago I decided to jazz up my posts with an image indicating the category they were in, but I didn’t want to hardcode the media so I use this plugin to insert the image in to the post.  That way if I change a category image all I have to do is update the shortcode and all related posts will automatically be updated as well.  There might be a better way to do this, but it seems to work well so I’m happy with it.

Shutter Reloaded

Plugin’s Description: Darkens the current page and displays an image on top like Lightbox, Thickbox, etc. However this script is a lot smaller and faster.

A nice little plugin to make screen shots and other images pop up over the current page instead of a new window or replacing the existing one.

Sidebar Login

Plugin’s Description: Easily add an ajax-enhanced login widget to your site’s sidebar.

The Sidebar Login plugin is a nice widget for WordPress that seems like a no brainer.  It does have a small issue with the theme I use and I have to manually make a change to it each time it’s updated, but it otherwise functions flawlessly.

Simple Custom CSS

Plugin’s Description: The simple, solid way to add custom CSS to your WordPress website.

Sometimes you just need to add some extra CSS to your main site.  Some theme’s have this option built in but then when you change the theme you have to hope the next one does as well.  This plugin makes your extra CSS theme independent.

Simple Feed Stats

Plugin’s Description: Tracks feeds, displays subscriber counts, custom feed content, and much more.

It’s a little simple and doesn’t exclude robots from the stats, but it does provide some useful view of how many subscribers you have to your blog through RSS.

Simple Local Avatars

Plugin’s Description: Adds an avatar upload field to user profiles. Generates requested sizes on demand, just like Gravatar! Simple and lightweight.

I have been using the “User Avatar” plugin since the start of my blog and it’s a good plugin, however it hasn’t been updated for WordPress 3.8 and it was getting kind of annoying.  The issue is that it uses a floated “div” to display your profile picture in your profile page and with the new admin color scheme’s layout it obscured some of the color schemes.

Simple Local Avatars does everything that User Avatar did but uses the standard WordPress API to add a section to the profile page, avoiding any conflicts in the future as well.

Simple Trackback Validation with Topsy Blocker

Plugin’s Description: Enhancement and REPLACEMENT of the original STV plugin from Michael Woehrer. Added automated blocking of topsy.com Trackbacks.

For the first 8 months of running JumbleCat I would every few weeks get ping back spam, this plugin has completely eliminated it.  Nuff said.

Subscribe2

Plugin’s Description: Notifies an email list when new entries are posted.

A great plugin I use to allow everyone to subscribe to my blog via e-mail.

Subscribe Sidebar

Plugin’s Description: Adds a list of Subscribe links to your sidebar. Options include your blog and podcast feed, Twitter page, iTunes, Facebook Fan Page and more.

A simple widget that let’s you setup different subscription options for your users.  Nice and clean.

SULly

Plugin’s Description: System Update Logger – Record system updates including plugins, themes and core updates.

With the automatic updates now active in WordPress it’s hard to keep track of when things have been updated.  SULly keeps track of everything for you.

TinyMCE Spellcheck

Plugin’s Description: Adds a contextual spell, style, and grammar checker to WordPress 3.6+.

I used to use After the Deadline to do spellchecking but that was rolled in to JetPack and I don’t want to use JetPack so this is a fork of the code that works without linking to WordPress.com.

User Registration Aide

Plugin’s Description: Forces new users to register additional fields with the option to add additional fields other than those supplied with the default WordPress Installation.

I use this to let new users that I delete inactive accounts.

Users Registered List

Plugin’s Description: Adds sortable `Registered` column to the list of users in wp-admin area.

Pretty self explanitory.

User Avatar

Plugin’s Description: Allows users to associate photos with their accounts by accessing their “Your Profile” page that default as Gravatar or WordPress Default image (from Discussion Page).

I use this to allow users (and me) to have avatar icons instead of just the default ones, I tried several but I found this to be the simplest and easiest.

WordPress phpinfo()

Plugin’s Description: This simple plugin adds an option to an adminstrator’s Tools menu which displays standard phpinfo() feedback details to the user.

I had been using a plugin to do this for a while but it added a top level menu item, which as it was only a once in a while thing was a little obtrusive.  This plugin adds it’s menu item under tools, which seems more logical.

WP About Author

Plugin’s Description: Easily display customizable author bios below your posts

This was one of the first plugin’s I installed and is still my favorite “about” plugin.

WP Last Login

Plugin’s Description: Displays the date of the last login in user lists.

Its nice to see when the last login for a user was.

WP Statistics

Plugin’s Description: Website statistics tracking.

I had been using BAW Post Views Count for quite a while and it does provide a good view of what posts are being read, but that’s all it does.  WordPress Statistics takes it a step farther and give a detailed view of all the hits on your site.