Skip to content

Instantly share code, notes, and snippets.

@slfrsn
Last active August 24, 2025 16:00
Show Gist options
  • Select an option

  • Save slfrsn/a75b2b9ef7074e22ce3b to your computer and use it in GitHub Desktop.

Select an option

Save slfrsn/a75b2b9ef7074e22ce3b to your computer and use it in GitHub Desktop.
Automatic WordPress theme updates from a GitHub repository using the native WordPress update system.

WordPress Theme Updates from GitHub

Adding automatic theme updates from a GitHub repository is actually pretty simple. The following function will hook into WordPress's native update system and grab the latest release from the repo of your choosing (if the version number has increased).

Place the following in your functions.php

// Automatic theme updates from the GitHub repository
add_filter('pre_set_site_transient_update_themes', 'automatic_GitHub_updates', 100, 1);
function automatic_GitHub_updates($data) {
  // Theme information
  $theme   = get_stylesheet(); // Folder name of the current theme
  $current = wp_get_theme()->get('Version'); // Get the version of the current theme
  // GitHub information
  $user = 'YOUR USERNAME'; // The GitHub username hosting the repository
  $repo = 'YOUR-REPO-NAME'; // Repository name as it appears in the URL
  // Get the latest release tag from the repository. The User-Agent header must be sent, as per
  // GitHub's API documentation: https://developer.github.com/v3/#user-agent-required
  $file = @json_decode(@file_get_contents('https://api.github.com/repos/'.$user.'/'.$repo.'/releases/latest', false,
      stream_context_create(['http' => ['header' => "User-Agent: ".$user."\r\n"]])
  ));
  if($file) {
	$update = filter_var($file->tag_name, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION);
    // Only return a response if the new version number is higher than the current version
    if($update > $current) {
  	  $data->response[$theme] = array(
	      'theme'       => $theme,
	      // Strip the version number of any non-alpha characters (excluding the period)
	      // This way you can still use tags like v1.1 or ver1.1 if desired
	      'new_version' => $update,
	      'url'         => 'https://github.com/'.$user.'/'.$repo,
	      'package'     => $file->assets[0]->browser_download_url,
      );
    }
  }
  return $data;
}

This is a pretty standard disclaimer, but make sure your releases don't contain any .git files. You'd hate for that to muck up someone's WordPress installation. If you're on a Mac you can use my Automator script to exclude .git files automagically.

Tested with WordPress 4.3

@eduardo-marcolino
Copy link

eduardo-marcolino commented Jun 9, 2023

Hey @TONYCRE8 and @gasparas, I missed add_filter's accepted_args definition on the example (updated):

<?php

add_filter('http_request_args', function($parsed_args, $url) 
{
  //code goes here..
  return $parsed_args;
}, 10, 2);

Another thing a forgot to mention was that the zip file have the same name of the theme.

@peraknezevic
Copy link

peraknezevic commented Jan 16, 2024

I can't get this to work. Any idea what I'm doing wrong?

When I tested in my local wordpress install I have the option to update but the update fails with these errors:

Warning: Undefined array key 0 in (theme folder path)/functions.php on line 29
Warning: Attempt to read property "browser_download_url" on null in (theme folder path)/functions.php on line 29
Warning: Undefined array key 0 in (theme folder path)/functions.php on line 29
Warning: Attempt to read property "browser_download_url" on null in  (theme folder path)/functions.php on line 29 

line 29 is:

'package'     => $file->assets[0]->browser_download_url,

What's even weirder is that I don't get any update options when this is online.

@TonyIngall
Copy link

I can't get this to work. Any idea what I'm doing wrong?

When I tested in my local wordpress install I have the option to update but the update fails with these errors:

Warning: Undefined array key 0 in (theme folder path)/functions.php on line 29
Warning: Attempt to read property "browser_download_url" on null in (theme folder path)/functions.php on line 29
Warning: Undefined array key 0 in (theme folder path)/functions.php on line 29
Warning: Attempt to read property "browser_download_url" on null in  (theme folder path)/functions.php on line 29 

line 29 is:

'package'     => $file->assets[0]->browser_download_url,

What's even weirder is that I don't get any update options when this is online.

Hi @peraknezevic , have you taken a look at the code I posted and tested if this solution works for you instead?

@anphira
Copy link

anphira commented Aug 19, 2025

Thank you! This worked very well, except for the child themes & semantic versioning.
Note if you use child themes, you need to change this line: $theme = get_stylesheet(); // Folder name of the current theme
to use the get_template() call instead.
You'll also need to $current = wp_get_theme($theme)->get('Version');
Anyone having trouble, make sure that you've uploaded the correct zip file. So my theme is kaya, so I zip the folder to get kaya.zip and make sure to upload that to github release.

Also note that it uses a float comparison, so if you use versioning with 1.1.2 the comparison won't work correctly. Use this instead:
// Clean the version string by removing common prefixes like 'v', 'ver', etc.
$update = preg_replace('/^(v|ver|version)?\s*/', '', $file->tag_name);
// Only return a response if the new version number is higher than the current version
// Use version_compare() for proper semantic version comparison
if(version_compare($update, $current, '>')) {

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment