honemo / wp-github-updater
A WordPress library to update plugins from GitHub repositories.
Requires (Dev)
- brain/monkey: ^2.6
- dealerdirect/phpcodesniffer-composer-installer: ^1.0
- mockery/mockery: ^1.6
- phpcompatibility/phpcompatibility-wp: ^2.1
- phpstan/phpstan: ^1.10
- phpunit/phpunit: ^9.6
- roots/wordpress: @stable
- squizlabs/php_codesniffer: ^3.7
- szepeviktor/phpstan-wordpress: ^1.3
- wp-coding-standards/wpcs: ^3.0
- yoast/wp-test-utils: ^1.2
README
A modern PHP library to automatically update WordPress plugins from public or private GitHub repositories.
✨ Features
- 🔒 Secure: Multiple token sources support (wp-config, environment variables, WP options)
- 🏷️ Flexible: Support for tags with or without
vprefix (v1.0.0 or 1.0.0) - 🎯 Modern: Strict PHP 8 typing, complete PHPDoc, fully tested
- ✅ Tested: Complete PHPUnit test suite with 15 tests
- 📦 Zero config: Works directly with public repositories, no token needed
- 🔐 Private repos: Full support with GitHub authentication
- 🌐 URL parsing: Accepts multiple GitHub URL formats (HTTPS, Git, SSH)
- 🔄 Smart caching: Respects WordPress transients to avoid API rate limits
- 🛡️ Error handling: Graceful degradation if GitHub API is unavailable
- 📝 Standards compliant: Follows WordPress Coding Standards and PSR-12
📋 Requirements
- PHP 7.4 or higher
- WordPress 6.0 or higher
- Composer
🚀 Installation
composer require honemo/wp-github-updater
📖 Usage
Basic usage (public repository)
<?php use honemo\updater\Updater; if ( is_admin() ) { require_once plugin_dir_path( __FILE__ ) . 'vendor/autoload.php'; $updater = new Updater( __FILE__, // Main plugin file 'https://github.com/Honemo/wp-github-updater' // Repository URL ); $updater->init(); }
Private repository (Recommended secure method)
Option 1: Constant in wp-config.php ⭐ (Recommended)
// In wp-config.php (BEFORE require_once(ABSPATH . 'wp-settings.php')) define( 'GITHUB_UPDATER_TOKEN', 'ghp_your_secret_token' );
// In your plugin - NO TOKEN in clear text! use honemo\updater\Updater; if ( is_admin() ) { $updater = new Updater( __FILE__, 'https://github.com/Honemo/my-private-plugin' // Token is automatically retrieved from wp-config.php ); $updater->init(); }
Supported URL formats
The updater accepts various GitHub URL formats:
// Standard HTTPS URL 'https://github.com/username/repository' // With .git extension 'https://github.com/username/repository.git' // With trailing slash 'https://github.com/username/repository/' // Without https:// 'github.com/username/repository' // Git SSH format (converted automatically) 'git@github.com:username/repository.git'
Option 2: Environment variable
# In .env (never versioned)
GITHUB_UPDATER_TOKEN=ghp_your_secret_token
The code remains the same - the updater automatically searches in environment variables.
Option 3: WordPress option
// Via WordPress admin or in functions.php update_option( 'github_updater_token', 'ghp_your_secret_token' );
Token priority order
The updater searches for the token in this order:
- Parameter passed to constructor
GITHUB_UPDATER_TOKENconstant (wp-config.php)GITHUB_UPDATER_TOKENenvironment variablegithub_updater_tokenWordPress option
� API Reference
Constructor
new Updater( string $file, string $repository_url, string $github_token = '' )
Parameters:
$file(string, required): Absolute path to your main plugin file (typically__FILE__)$repository_url(string, required): GitHub repository URL. Accepts multiple formats:https://github.com/username/repositoryhttps://github.com/username/repository.gitgithub.com/username/repositorygit@github.com:username/repository.git
$github_token(string, optional): GitHub personal access token. If not provided, the updater will attempt to retrieve it from:GITHUB_UPDATER_TOKENconstantGITHUB_UPDATER_TOKENenvironment variablegithub_updater_tokenWordPress option
Example:
$updater = new \honemo\updater\Updater( __FILE__, 'https://github.com/tcacamou-ops/all-in-one-download' ); $updater->init();
Methods
init(): void
Initialize the updater by hooking into WordPress filters. Must be called after instantiation.
$updater->init();
�🔐 Generate a GitHub token
- Go to GitHub → Settings → Developer Settings → Personal access tokens
- Generate new token (classic)
- Minimum required permissions:
- ✅
repo(for private repositories) - ✅
public_repo(for public repositories only)
- ✅
- Copy the token and store it securely
📦 Creating a release
Automated release (Recommended) 🤖
A GitHub Actions workflow is included to automatically create releases when you push a tag:
Step 1: Update the version in your plugin file
/** * Version: 1.2.0 */
Step 2: Commit your changes
git add . git commit -m "Release version 1.2.0"
Step 3: Create and push a tag
git tag v1.2.0 # or simply 1.2.0
git push origin main
git push origin v1.2.0
That's it! The workflow will automatically:
- ✅ Build a distribution package (without dev dependencies)
- ✅ Generate a changelog from git commits
- ✅ Create a GitHub release with the package attached
- ✅ Upload the distributable ZIP file
The workflow supports both formats:
- Tags with prefix:
v1.0.0,v2.3.4 - Tags without prefix:
1.0.0,2.3.4
Manual release
If you prefer to create releases manually:
-
Create a version tag:
git tag v1.0.0 # or simply 1.0.0 git push origin v1.0.0 -
Create a release on GitHub:
- Go to "Releases" → "Create a new release"
- Select the tag
- Add release notes
- Publish the release
-
The version in your main file must match:
/** * Version: 1.0.0 */
What gets included in the distribution?
The .distignore file controls what's excluded from releases:
- ❌ Development dependencies (
/vendor/dev packages,/tests/) - ❌ Configuration files (
phpcs.xml,phpstan.neon) - ❌ Git files (
.git,.github,.gitignore) - ✅ Production code (
/src/) - ✅ Composer autoloader
- ✅ README.md and LICENSE
📝 Complete example
<?php /** * Plugin Name: My Awesome Plugin * Version: 1.0.0 * Plugin URI: https://github.com/Honemo/my-plugin * Description: An awesome plugin with auto-update from GitHub * Author: Honemo * Author URI: https://github.com/Honemo */ // Prevent direct access if ( ! defined( 'ABSPATH' ) ) { exit; } // Composer autoloader require_once plugin_dir_path( __FILE__ ) . 'vendor/autoload.php'; // Initialize updater (admin only) if ( is_admin() ) { $updater = new \honemo\updater\Updater( __FILE__, 'https://github.com/Honemo/my-plugin' ); $updater->init(); } // Rest of your code...
🐛 Troubleshooting
Updates not showing up
Check these points:
-
Version mismatch: Ensure the version in your plugin header matches exactly with the GitHub release tag (without
vprefix)// Plugin header Version: 1.0.0 // GitHub tag should be: v1.0.0 or 1.0.0
-
Release published: Make sure you've created and published a release on GitHub, not just a tag
-
Token authentication: For private repositories, verify your token has the correct permissions:
reposcope for private repositoriespublic_reposcope for public repositories
-
Clear transients: WordPress caches update information. Clear it with:
delete_site_transient( 'update_plugins' );
Invalid repository URL error
If you get an InvalidArgumentException, ensure your URL:
- Points to
github.com(not GitLab, Bitbucket, etc.) - Contains both username and repository name
- Follows one of the supported formats
Valid formats:
'https://github.com/username/repository' 'github.com/username/repository' 'git@github.com:username/repository.git'
Invalid formats:
'https://gitlab.com/username/repository' // ❌ Not GitHub 'https://github.com/username' // ❌ Missing repository 'username/repository' // ❌ Missing domain
Token not being recognized
Verify the token is accessible:
// Add this temporarily to debug if ( defined( 'GITHUB_UPDATER_TOKEN' ) ) { error_log( 'Token is defined in wp-config.php' ); }
Make sure the constant is defined before wp-settings.php is loaded in wp-config.php.
🛠️ Development
# Clone repository git clone https://github.com/Honemo/wp-github-updater.git cd wp-github-updater # Install dependencies composer install # Run tests composer test # Check code quality composer check:all
📄 License
GPL-3.0 License. See LICENSE for more details.
🤝 Contributing
Contributions are welcome! Feel free to:
- Open an issue to report a bug
- Submit a pull request to improve the code
- Suggest new features