So GitHub Updater v4.0.0 is out. It includes a huge refactoring and now requires PHP 5.3 or better. GitHub Updater now uses namespacing and PSR 4 autoloading.
I read a recent WP Tavern article and showed me what others are doing in the same space. I was intrigued. WP Pusher has done terrific work in creating a solution to remote installation and updating. I wondered, how difficult would it be to add remote installation of WordPress plugins or themes to the existing framework. It turns out, not that difficult.
GitHub Updater and Remote Installation
What’s next for v4.1.0?
The develop branch has a working method of remote installation of both public and private GitHub or Bitbucket repositories.
I must confess, the hardest part was getting everything in the Settings API functioning. I used some code from WordPress Zero Spam by Ben Marshall and borrowed a couple of lines from TGM Plugin Activation by Thomas Griffin.
I was quite familiar with WordPress Zero Spam; I’ve been a contributor on GitHub. Ben has done a nice job of creating a modularized approach to coding a tabbed Settings interface.
Thomas and Gary Jones have done a great job with TGM Plugin Activation and I highly recommend it when other plugins are required for any other single plugin to function. I am very familiar with Gary’s work as he has helped tremendously with GitHub Updater.
After setting up the tabs in the Settings page I was able to simply create the correct endpoint for GitHub and Bitbucket. I thought allowing for private repository remote installation my prove more difficult but a couple of modifications in other parts of the plugin made this relatively painless. Well, painless once I figured out what I needed to do and where in the existing code I needed to do it. 😉
Thanks to a couple of lines from TGM Plugin Activation I could figure out what I needed to do to create a new instance of both the Plugin_Upgrader and Theme_Upgrader for remote installation.
So now it’s all wrapped up in a nice little package. Remote installation and automatic updating in GitHub Updater. So go grab a copy from the develop branch, or just change the branch designation of your existing copy to be automatically updated, and try to break it. If you do be sure to put an issue up on GitHub and let me know. Remember to change your header back to GitHub Branch: master unless you want to stay on the develop branch.
I must say this is all pretty slick. It certainly makes downloading a repo from GitHub, renaming it correctly, and then uploading it a single click experience.
Remember, if you’ve installed a private plugin or theme, you must visit the settings page and enter the appropriate credentials, GitHub Access Token and/or checkbox to ensure that automatic updating works.
Please let me know your thoughts.
There are always a couple of plugins that require either constant care and upkeep or you just want to keep making them better. I have 2 plugins that I put more care and feeding into than others. These are GitHub Updater and The Events Calendar Category Colors. Both of these projects are free and open sourced. They both live on GitHub and this allows for both of these plugins to be much better than I, alone, could make them.
I’ve written a number of posts lately about GitHub Updater so let me just say that recently I’ve been get PRs for translations and I think it’s very cool. I continue to refactor GitHub Updater and requiring PHP 5.3 is probably not a big deal as most users of it developers and are probably already using at least this version. Eventually I’ll add namespacing support, when I figure it out. 🙂
The Events Calendar Category Colors
The Events Calendar Category Colors is an add-on plugin to Modern Tribe’s The Events Calendar. I’ve been very fortunate to have lots of help and assistance from Modern Tribe and especially from Barry Hughes. Modern Tribe develops The Events Calendar (TEC) on GitHub. This allows be to see what’s coming and what I see coming is a major refactoring of the plugin in anticipation of PSR 4 autoloading. This is clearly in anticipation of WordPress moving their minimum PHP requirement to 5.3. I can also see that namespacing is coming.
This has spurred me to figure out how users of current and past versions of TEC will continue to use The Events Calendar Category Colors without fatal errors. Modern Tribe has used a method of creating class aliases, mostly so they don’t inadvertently break anything. In looking at this I found that I could use a similar method to support their upcoming release and previous releases. While Modern Tribe isn’t yet using namespacing, I’ve decided to use namespacing. I’ve done this mostly because I wrote a generic Autoloader class and to use it in multiple plugins I would either need to rename the funtions to be unique or I could just create a unique namespace for each plugin. Because of this The Events Calendar Category Colors will require at least PHP 5.3. Of course, Barry re-wrote it better. 😉
Using spl_autoload_register is a great function to simply your code and hopefully make it more memory efficient by only loading classes when needed. As such, more complex plugins will benefit from this more than simple plugins. Technically, spl_autoload_register is in PHP 5.2.
So here I am working on refactoring The Events Calendar Category Colors to run in a namespaced environment. You can follow my progress as development is on GitHub. As usual Barry’s already been a great help and sounding board.
There is a side benefit to keeping this plugin refactored and running as efficiently as possible. It makes it much easier to eventually drop it in to The Events Calendar core, if Modern Tribe has such thoughts. 😉
A new update to GitHub Updater reorganizes the Settings page.
Now the individual user enters their Bitbucket username and password. They must have at least Read privileges for each private Bitbucket repository. The next section of the Settings page has a checkbox for identifying private Bitbucket repositories.
This setup should allow developers to add clients as Read-only users to their private repositories and have the client able to update as the repository updates.
This should be a substantial security improvement as it no longer exposes the developer’s Bitbucket password to the client. As always, please create an issue if there are any problems or if you have any ideas for improvement of GitHub Updater.
I’ve been doing a lot of tweaking to GitHub Updater. The plugin now runs on the front-end and only for privileged users. This allows for a couple of things.
It makes less overhead for the non-admin user.
Second it allows for update services to do their thing.
I’ve tested with several update services and iThemes Sync works great out of the box. I’ve been told MainWP works and ManageWP works. ManageWP does not yet have support for child themes but I’ve been told it’s in the works. I’ve been told mixed things with InfiniteWP and I’m unable to test well against it.
Classes are autoloaded using spl_autoload_register and I’m now using Parsedown to render the change logs. Additionally, efficiency gains are achieved by only parsing remote file headers and saving those headers to transients. I’ve also added 2 new headers ( Requires PHP and Requires WP ) to set the minimum requirements of both PHP and WordPress for your plugins or themes. If the minimum requirements aren’t met on the user’s system then your plugin or theme will show an update.
One of the biggest changes is a Settings Page. No longer are GitHub Access Tokens or Bitbucket passwords required to be stored within the repository. They can be added after plugin or theme installation. This should help with security.
Update Bitbucket Private Repositories
One of the most glaring bugs was my inability to update Bitbucket private repositories. Somewhere along the path to add Settings API functionality or more precisely improving HTTP Authentication headers only for the proper plugins or themes, it seems that Bitbucket private repositories now update correctly.
If anyone’s interested in working on a Gitlab module please ping me.
In Part 1, I tried to describe some of the why and a little of the how I’ve gotten to this point with GitHub Updater. In this point I’ll try to go into a bit about how the plugin works.
The basic premise and design of GitHub Updater is to be very lightweight to both the developer and the end user. For the developer, inclusion of only one or two lines of code in the plugin or theme header will allow it to get automatic updates via GitHub Updater. All the end user needs to do is install and activate (or network activate) the GitHub Updater plugin.
GitHub Updater is even smart enough to allow for plugins to be hosted on WP.org and get updates from WP.org as long as the branch header is master. If the developer wants to update from GitHub all they need to do is change the branch header to something other than master. I use this for development by designating GitHub Branch: develop on my development site. Please refer to the README for a better explanation.
When the branch is master and there are tagged releases, these tagged released are preferentially used for updates. When the branch is something other than master, tagged versions are ignored and the specified branch is used during the update.
In the plugin’s evolution I think I’m using some better OOP practices. As such, as I search though all the plugins and themes in the user’s installation I parse out those that don’t have the requisite header. When I find a plugin or theme that has the appropriate header, either GitHub Plugin URI, GitHub Theme URI, Bitbucket Plugin URI, or Bitbucket Theme URI what happens is that the URI is parsed and data from the local plugin is placed into a class object. As you’ve no doubt just noticed the GitHub Updater does also works with Bitbucket hosted code too.
After gathering the local data, the plugin reaches out to GitHub via the GitHub API to get the remote info. At this point there is lots of transient setting and getting so the GitHub API doesn’t get hit too frequently. This is necessary because GitHub’s API only allows 60 unauthenticated requests per hour. More than 60 requests per hour yields a 403 error. Bitbucket’s API doesn’t seem to have this limitation, but the results are cached nonetheless.
Each API class, so far just GitHub and Bitbucket, is written as an extender class. Doing it this way should allow for adding additional API classes for additional git repos in a more logical fashion. Think Gitlab.
A CHANGES.md file is also parsed, if present, to add into the View Details screen. At this time parsing a standard readme.txt isn’t done, but it’s certainly something on the horizon. I’ve also created a pseudo-rating based upon the number of stars, forks and issues the repo has.
The updating is hooked into WordPress’ core methods, as is renaming of the downloaded plugin/theme update. So far so good and GitHub Updater just works in WordPress 4.0beta.
I’m sure there’s probably another post, Automatic Plugin & Theme Updating from GitHub – Part 3, coming.