Adding a GitHub version checker to my Minecraft plugin

Adding a GitHub version checker to my Minecraft plugin

Hello everyone, in this post I'll explain how I implemented a version checker into my latest plugin KitPvP Plus. It uses GitHub Releases to check and notify the server administrator when their plugin is out of date and needs updating. It's a nifty little feature to have, and I'm glad I added it.

What exactly is a "version checker"?

A version checker is a bit of code that will compare the current version of a plugin or program with the latest version. The latest version is usually fetched using a rest API. In this particular instance, through GitHub's API. Whenever I release a new version, I make it a release on GitHub. Even when you download my plugin off of spigot, it actually takes you to the link which downloads the file off GitHub and then takes you back to spigot. So in short, my system checks the latest release version on GitHub, compares it to the current version and then will notify the server admin if necessary.

Accessing the GitHub API.

You would assume this process is the easiest, but it was actually the hardest. I first looked for a pre-existing Java API wrapper for the GitHub API. What this would do is have a bunch of objects (for things such as repositories & accounts) and make the http requests under the hood. I was only able to find one, however, it required a sign in. You could use an access token so as not to leak your password, but still with that, anyone could get into my GitHub account. I didn't really want to do that and since I couldn't find any alternative libraries, I decided to make my own. There is one upside to this, which is the fact I only need to add the methods that I need to use, instead of shading in an entire API.

For making the HTTP requests, I'm using jodd and using gson to parse the json response. I made a simple utility to easily make http requests as seen here and after a bit of poking around in the GitHub API docs, I came up with this.

Comparing versions.

I made a version class that could parse a string into an object. In order to compare a version, you've got to understand what goes into a version string.

For example, here we have "1.4.6". The "1" stands for the version. When KitPvPPlus was in beta, the version was "0". If I was to do a complete redo of all the code, it would probably increment to "2". The "4" stands for the sub version or release version. When one or more features are released, it will make a new release version. Furthermore, the "6" stands for the fix version. This is for updates that simply add bug fixes or too small a feature to be counted as a release update. Finally, you may notice some versions end with "-HOTFIX". If it is a hotfix, it means that the code has been update to get it working but will need a further update.

The version class I made was able to parse all of this information and then compare it with this block of code:

     * @return true if v2 is greater
    public static boolean compare(Version v1, Version v2) {
        if(v2.getMainAsInt() > v1.getMainAsInt()) return true;
        if(v2.getSubAsInt() > v1.getSubAsInt()) return true;
        if(v2.getFixAsInt() > v1.getSubAsInt()) return true;
        return v2.isHotfix();

Now we can fetch and parse our current and latest version and compare them. I run this on my onEnable method as well as in a runnable that repeats every 10 minutes or so.

Pre-release checks

Now there are two methods of fetching the latest release. First by going to the end point and the other just going to the end point and getting the 0th index in the array. The one thing the latter method does is include pre-releases as latest updates. I fixed this from triggering in version BETA-1.0.3 however, also implementing the latter method as a feature by adding a configurable option to check for pre-releases.

Auto downloading

The final thing left for me to do is add a download feature, allowing admins to press one button/run one command and reboot their server to have the latest version ready to go. I have already implemented the basics of downloading it, however the hard part is deleting the old jar as well as making sure any new values added to the config are added to the server config. This is a challenge that I'll probably tackle some time in the near future.


Anyway, I'm gonna focus on other parts of the plugin. If you have any suggestions for it, I'm all ears and if you want to improve any of my code, you're always welcome to make a pull request on my repo! I hope to see you round some time soon, have a great day/night!

Show Comments