From d41fa7403be28c872c039ee56d13cee76389a5c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20S=C3=B8derlind?= Date: Fri, 13 Jun 2025 15:04:48 +0200 Subject: [PATCH 1/4] Refactor plugin updater implementation - Replaced the existing `Additional_JavaScript_Updater` class with a more generic `GitHub_Plugin_Updater` class to enhance maintainability and reusability. - Updated `additional-javascript.php` to include the new updater class and initialize it with configuration parameters for GitHub integration. - Removed the old updater class file `class-additional-javascript-updater.php` to eliminate redundancy. - Added comprehensive documentation in `README-UPDATER.md` detailing the usage and configuration of the new updater class, including examples for basic and advanced setups. --- README-UPDATER.md | 316 ++++++++++++++++++++++++ additional-javascript.php | 16 +- class-additional-javascript-updater.php | 55 ----- class-github-plugin-updater.php | 146 +++++++++++ 4 files changed, 472 insertions(+), 61 deletions(-) create mode 100644 README-UPDATER.md delete mode 100644 class-additional-javascript-updater.php create mode 100644 class-github-plugin-updater.php diff --git a/README-UPDATER.md b/README-UPDATER.md new file mode 100644 index 0000000..b84b972 --- /dev/null +++ b/README-UPDATER.md @@ -0,0 +1,316 @@ +# WordPress Plugin GitHub Updater + +A reusable WordPress plugin updater class that handles automatic updates from GitHub repositories using the `yahnis-elsts/plugin-update-checker` library. + +## Table of Contents + +- [Files Overview](#files-overview) +- [Quick Start](#quick-start) +- [Configuration Parameters](#configuration-parameters) +- [GitHub Workflow for Automatic Release Assets](#github-workflow-for-automatic-release-assets) +- [Usage Examples](#usage-examples) +- [Customizing the Class](#customizing-the-class) +- [Dependencies](#dependencies) +- [Key Features](#key-features) +- [Best Practices](#best-practices) +- [Error Handling](#error-handling) +- [License](#license) + +## Files Overview + +- `class-github-plugin-updater.php` - **Recommended generic class** with better error handling +- `class-additional-javascript-updater.php` - Modified original class with backward compatibility +- `example-generic-updater.php` - Example implementations + +## Quick Start + +### 1. Copy the updater class to your plugin +Copy `class-github-plugin-updater.php` to your plugin directory. + +### 2. Include the class in your main plugin file +```php +require_once plugin_dir_path( __FILE__ ) . 'class-github-plugin-updater.php'; +``` + +### 3. Initialize with your plugin's configuration + +#### Simple Usage (Recommended) +```php + 'https://github.com/username/plugin-name', + 'plugin_file' => __FILE__, + 'plugin_slug' => 'plugin-name', + 'branch' => 'main', + 'name_regex' => '/plugin-name-v[\d\.]+\.zip/', + 'enable_release_assets' => true, +) ); +``` + +## Configuration Parameters + +| Parameter | Required | Description | Example | +|-----------|----------|-------------|---------| +| `github_url` | Yes | GitHub repository URL | `'https://github.com/username/plugin-name'` | +| `plugin_file` | Yes | Path to main plugin file | `__FILE__` or `PLUGIN_CONSTANT_FILE` | +| `plugin_slug` | Yes | Plugin slug for WordPress | `'my-awesome-plugin'` | +| `branch` | No | Git branch to check for updates | `'master'` (default), `'main'`, `'develop'`.
[Caveat](https://github.com/YahnisElsts/plugin-update-checker?tab=readme-ov-file#how-to-release-an-update-1): If you set the branch to `master` , the update checker will look for recent releases and tags first. It'll only use the master branch if it doesn't find anything else suitable. | +| `name_regex` | No | Regex pattern for release assets | `'/plugin-name\.zip/'` | +| `enable_release_assets` | No | Whether to enable release assets | `true` if name_regex provided | + +## GitHub Workflow for Automatic Release Assets + +To automatically create zip files when you publish a GitHub release, include this workflow file in your repository. This is especially useful when using the `name_regex` parameter to filter release assets. + +### Setup: Create `.github/workflows/on-release-add.zip.yml` + +```yaml +name: On Release, Build release zip + +on: + release: + types: [published] + +jobs: + build: + name: Build release zip + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Build plugin # Remove or modify this step as needed + run: | + composer install --no-dev + + - name: Archive Release + uses: thedoctor0/zip-release@b57d897cb5d60cb78b51a507f63fa184cfe35554 #0.7.6 + with: + type: 'zip' + filename: 'your-plugin-name.zip' # Change this to match your plugin + exclusions: '*.git* .editorconfig composer* *.md package.json package-lock.json' + + - name: Release + uses: softprops/action-gh-release@c95fe1489396fe8a9eb87c0abf8aa5b2ef267fda #v2 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + files: your-plugin-name.zip # Change this to match your plugin + tag_name: ${{ github.event.release.tag_name }} +``` + +### How it Works + +1. **Trigger**: Automatically runs when you publish a GitHub release +2. **Build**: Installs production dependencies with `composer install --no-dev` +3. **Archive**: Creates a zip file excluding development files +4. **Attach**: Adds the zip file to the GitHub release as an asset + +### Customizing the Workflow + +- **Change filename**: Update both `filename:` and `files:` to match your plugin name +- **Modify exclusions**: Add or remove files/patterns from the `exclusions:` list +- **Build step**: Modify the build process (npm, webpack, etc.) as needed for your plugin + +### Example Release Asset URLs + +After the workflow runs, your release assets will be available at URLs like: + +``` +https://github.com/username/plugin-name/releases/latest/download/plugin-name.zip +``` + +**Real example from this plugin:** +``` +https://github.com/soderlind/additional-javascript/releases/latest/download/additional-javascript.zip +``` + +### Using with the Updater + +When using release assets, configure your updater like this: + +```php + 'https://github.com/mycompany/premium-plugin', + 'plugin_file' => __FILE__, + 'plugin_slug' => 'premium-plugin', + 'branch' => 'stable', + 'name_regex' => '/premium-plugin-pro-v[\d\.]+\.zip/', + 'enable_release_assets' => true, +) ); +``` + +## Customizing the Class + +### Option 1: Rename the Class +If you want to avoid conflicts, rename the class: + +```php +updater = \Soderlind\WordPress\GitHub_Plugin_Updater::create( + 'https://github.com/yourcompany/your-plugin', + YOUR_PLUGIN_FILE, + 'your-plugin' + ); + } +} +``` + +## Dependencies + +This updater requires the `yahnis-elsts/plugin-update-checker` library: + +```bash +composer require yahnis-elsts/plugin-update-checker +``` + +Or download it manually from: https://github.com/YahnisElsts/plugin-update-checker + +## Key Features + +- ✅ **Automatic updates** from GitHub releases +- ✅ **Custom branch support** for development/staging +- ✅ **Release asset filtering** with regex patterns +- ✅ **Error handling** with debug logging +- ✅ **Multiple initialization methods** (static factories) +- ✅ **Parameter validation** with meaningful error messages +- ✅ **Flexible configuration** options +- ✅ **Fully documented** with examples + +## Best Practices + +1. **Use Constants**: Define your plugin file as a constant for consistency +2. **Static Factory Methods**: Use `::create()` methods for simpler initialization +3. **Error Handling**: The updater includes proper validation and debug logging +4. **Testing**: Test with different branch names and release asset patterns +5. **Documentation**: Document your specific configuration for future reference +6. **Namespace**: Consider using your own namespace to avoid conflicts + +## Error Handling + +The `GitHub_Plugin_Updater` class includes robust error handling: + +- **Parameter Validation**: Required parameters are validated on construction +- **Exception Handling**: Gracefully handles errors during update check setup +- **Debug Logging**: Errors are logged when `WP_DEBUG` is enabled +- **Graceful Degradation**: Plugin continues to work even if updater fails + + +## License + +GPL-2.0+ (same as the original plugin) diff --git a/additional-javascript.php b/additional-javascript.php index 898f995..bf4ecef 100644 --- a/additional-javascript.php +++ b/additional-javascript.php @@ -30,12 +30,16 @@ define( 'ADDITIONAL_JAVASCRIPT_PATH', plugin_dir_path( ADDITIONAL_JAVASCRIPT_FILE ) ); require_once ADDITIONAL_JAVASCRIPT_PATH . 'vendor/autoload.php'; -/** - * Load the plugin updater class. - */ -require_once dirname( __FILE__ ) . '/class-additional-javascript-updater.php'; -// Initialize the updater. -$additional_javascript_updater = new Additional_JavaScript_Updater(); +// Include the generic updater class +require_once dirname( __FILE__ ) . '/class-github-plugin-updater.php'; +// Initialize the updater with configuration. +$additional_javascript_updater = \Soderlind\WordPress\GitHub_Plugin_Updater::create_with_assets( + 'https://github.com/soderlind/additional-javascript', + ADDITIONAL_JAVASCRIPT_FILE, + 'additional-javascript', + '/additional-javascript\.zip/', + 'main' +); add_action( 'init', __NAMESPACE__ . '\register_post_type_javascript', 0 ); add_action( 'wp_head', __NAMESPACE__ . '\soderlind_custom_javascript_cb', 110 ); diff --git a/class-additional-javascript-updater.php b/class-additional-javascript-updater.php deleted file mode 100644 index edaf2bc..0000000 --- a/class-additional-javascript-updater.php +++ /dev/null @@ -1,55 +0,0 @@ -github_url, - ADDITIONAL_JAVASCRIPT_FILE, - $this->plugin_slug - ); - - $update_checker->setBranch( $this->branch ); - $update_checker->getVcsApi()->enableReleaseAssets( $this->name_regex ); - } -} diff --git a/class-github-plugin-updater.php b/class-github-plugin-updater.php new file mode 100644 index 0000000..e0899aa --- /dev/null +++ b/class-github-plugin-updater.php @@ -0,0 +1,146 @@ +github_url = $config[ 'github_url' ]; + $this->plugin_file = $config[ 'plugin_file' ]; + $this->plugin_slug = $config[ 'plugin_slug' ]; + $this->branch = isset( $config[ 'branch' ] ) ? $config[ 'branch' ] : 'main'; + $this->name_regex = isset( $config[ 'name_regex' ] ) ? $config[ 'name_regex' ] : ''; + $this->enable_release_assets = isset( $config[ 'enable_release_assets' ] ) + ? $config[ 'enable_release_assets' ] + : ! empty( $this->name_regex ); + + // Initialize the updater + add_action( 'init', array( $this, 'setup_updater' ) ); + } + + /** + * Set up the update checker using GitHub integration + */ + public function setup_updater() { + try { + $update_checker = PucFactory::buildUpdateChecker( + $this->github_url, + $this->plugin_file, + $this->plugin_slug + ); + + $update_checker->setBranch( $this->branch ); + + // Enable release assets if configured + if ( $this->enable_release_assets && ! empty( $this->name_regex ) ) { + $update_checker->getVcsApi()->enableReleaseAssets( $this->name_regex ); + } + + } catch (\Exception $e) { + // Log error if WordPress debug is enabled + if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { + error_log( 'GitHub Plugin Updater Error: ' . $e->getMessage() ); + } + } + } + + /** + * Create updater instance with minimal configuration + * + * @param string $github_url GitHub repository URL + * @param string $plugin_file Main plugin file path + * @param string $plugin_slug Plugin slug + * @param string $branch Branch name (default: 'main') + * + * @return GitHub_Plugin_Updater + */ + public static function create( $github_url, $plugin_file, $plugin_slug, $branch = 'main' ) { + return new self( array( + 'github_url' => $github_url, + 'plugin_file' => $plugin_file, + 'plugin_slug' => $plugin_slug, + 'branch' => $branch, + ) ); + } + + /** + * Create updater instance for plugins with release assets + * + * @param string $github_url GitHub repository URL + * @param string $plugin_file Main plugin file path + * @param string $plugin_slug Plugin slug + * @param string $name_regex Regex pattern for release assets + * @param string $branch Branch name (default: 'main') + * + * @return GitHub_Plugin_Updater + */ + public static function create_with_assets( $github_url, $plugin_file, $plugin_slug, $name_regex, $branch = 'main' ) { + return new self( array( + 'github_url' => $github_url, + 'plugin_file' => $plugin_file, + 'plugin_slug' => $plugin_slug, + 'branch' => $branch, + 'name_regex' => $name_regex, + ) ); + } +} From 0ee0a1edcab36c35f85446bb6f37e4743025fdaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20S=C3=B8derlind?= Date: Fri, 13 Jun 2025 15:05:26 +0200 Subject: [PATCH 2/4] Bump version to 1.1.3 in additional-javascript.php, package.json, and readme.txt for release. Update stable tag to reflect the new version. --- additional-javascript.php | 2 +- package.json | 2 +- readme.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/additional-javascript.php b/additional-javascript.php index bf4ecef..3429d6e 100644 --- a/additional-javascript.php +++ b/additional-javascript.php @@ -12,7 +12,7 @@ * Plugin URI: https://github.com/soderlind/additional-javascript * GitHub Plugin URI: https://github.com/soderlind/additional-javascript * Description: Add additional JavaScript using the WordPress Customizer. - * Version: 1.1.2 + * Version: 1.1.3 * Author: Per Soderlind * Author URI: https://soderlind.no * Text Domain: additional-javascript diff --git a/package.json b/package.json index 1e96ca5..d9d491a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "additional-javascript", - "version": "1.1.2", + "version": "1.1.3", "description": "Add additional JavaScript using the WordPress Customizer.", "keywords": [ "wordpress", diff --git a/readme.txt b/readme.txt index c0c695c..023af54 100644 --- a/readme.txt +++ b/readme.txt @@ -4,7 +4,7 @@ Tags: javascript, customizer, code, custom code, js Donate link: https://paypal.me/PerSoderlind Requires at least: 6.5 Tested up to: 6.8 -Stable tag: 1.1.2 +Stable tag: 1.1.3 Requires PHP: 8.2 License: GPL-2.0+ License URI: http://www.gnu.org/licenses/gpl-2.0.txt From 22f23630ecfe19338e339f4c91e96d87e550ae88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20S=C3=B8derlind?= Date: Fri, 13 Jun 2025 15:19:18 +0200 Subject: [PATCH 3/4] Update changelog for version 1.1.3 and add reference to WordPress Plugin GitHub Updater --- README.md | 6 ++++++ readme.txt | 3 +++ 2 files changed, 9 insertions(+) diff --git a/README.md b/README.md index 9023077..4bb93e6 100644 --- a/README.md +++ b/README.md @@ -68,6 +68,12 @@ The JavaScript is added at the end of the `` section of your site with a p ## Changelog +### 1.1.3 +* Use generic [WordPress Plugin GitHub Updater](https://github.com/soderlind/wordpress-plugin-gitHub-updater?tab=readme-ov-file#wordpress-plugin-github-updater) + +### 1.1.2 +* Minor code improvements + ### 1.1.1 - Add plugin updater diff --git a/readme.txt b/readme.txt index 023af54..023d5b1 100644 --- a/readme.txt +++ b/readme.txt @@ -62,6 +62,9 @@ The JavaScript is added at the end of the `` section of your site with a p == Changelog == += 1.1.3 = +* Use generic [WordPress Plugin GitHub Updater](https://github.com/soderlind/wordpress-plugin-gitHub-updater?tab=readme-ov-file#wordpress-plugin-github-updater) + = 1.1.2 = * Minor code improvements From 3f973b4872341da90eeac944ad7f5977366e2811 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20S=C3=B8derlind?= Date: Wed, 2 Jul 2025 13:01:12 +0200 Subject: [PATCH 4/4] Bump version to 1.1.4 in additional-javascript.php, package.json, package-lock.json, and readme.txt. Update stable tag to reflect the new version. Adjusted version reference in installed.php for consistency. Enhanced class loading for the GitHub plugin updater. --- README.md | 3 +++ additional-javascript.php | 8 +++++--- package-lock.json | 4 ++-- package.json | 2 +- readme.txt | 5 ++++- vendor/composer/installed.php | 4 ++-- 6 files changed, 17 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 4bb93e6..6d8a4f6 100644 --- a/README.md +++ b/README.md @@ -68,6 +68,9 @@ The JavaScript is added at the end of the `` section of your site with a p ## Changelog +### 1.1.4 +* Enhanced class loading for the GitHub plugin updater. + ### 1.1.3 * Use generic [WordPress Plugin GitHub Updater](https://github.com/soderlind/wordpress-plugin-gitHub-updater?tab=readme-ov-file#wordpress-plugin-github-updater) diff --git a/additional-javascript.php b/additional-javascript.php index 3429d6e..d81bebe 100644 --- a/additional-javascript.php +++ b/additional-javascript.php @@ -12,7 +12,7 @@ * Plugin URI: https://github.com/soderlind/additional-javascript * GitHub Plugin URI: https://github.com/soderlind/additional-javascript * Description: Add additional JavaScript using the WordPress Customizer. - * Version: 1.1.3 + * Version: 1.1.4 * Author: Per Soderlind * Author URI: https://soderlind.no * Text Domain: additional-javascript @@ -25,13 +25,15 @@ die(); } -define( 'ADDITIONAL_JAVASCRIPT_VERSION', '1.1.1' ); +define( 'ADDITIONAL_JAVASCRIPT_VERSION', '1.1.4' ); define( 'ADDITIONAL_JAVASCRIPT_FILE', __FILE__ ); define( 'ADDITIONAL_JAVASCRIPT_PATH', plugin_dir_path( ADDITIONAL_JAVASCRIPT_FILE ) ); require_once ADDITIONAL_JAVASCRIPT_PATH . 'vendor/autoload.php'; // Include the generic updater class -require_once dirname( __FILE__ ) . '/class-github-plugin-updater.php'; +if ( ! class_exists( 'Soderlind\WordPress\GitHub_Plugin_Updater' ) ) { + require_once ADDITIONAL_JAVASCRIPT_PATH . 'class-github-plugin-updater.php'; +} // Initialize the updater with configuration. $additional_javascript_updater = \Soderlind\WordPress\GitHub_Plugin_Updater::create_with_assets( 'https://github.com/soderlind/additional-javascript', diff --git a/package-lock.json b/package-lock.json index 7870853..84c6d06 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "additional-javascript", - "version": "1.1.2", + "version": "1.1.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "additional-javascript", - "version": "1.1.2", + "version": "1.1.4", "license": "GPLv2", "devDependencies": { "@soderlind/wp-project-version-sync": "^2.0.2" diff --git a/package.json b/package.json index d9d491a..62ed0f5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "additional-javascript", - "version": "1.1.3", + "version": "1.1.4", "description": "Add additional JavaScript using the WordPress Customizer.", "keywords": [ "wordpress", diff --git a/readme.txt b/readme.txt index 023d5b1..d29c5a5 100644 --- a/readme.txt +++ b/readme.txt @@ -4,7 +4,7 @@ Tags: javascript, customizer, code, custom code, js Donate link: https://paypal.me/PerSoderlind Requires at least: 6.5 Tested up to: 6.8 -Stable tag: 1.1.3 +Stable tag: 1.1.4 Requires PHP: 8.2 License: GPL-2.0+ License URI: http://www.gnu.org/licenses/gpl-2.0.txt @@ -62,6 +62,9 @@ The JavaScript is added at the end of the `` section of your site with a p == Changelog == += 1.1.4 = +* Enhanced class loading for the GitHub plugin updater. + = 1.1.3 = * Use generic [WordPress Plugin GitHub Updater](https://github.com/soderlind/wordpress-plugin-gitHub-updater?tab=readme-ov-file#wordpress-plugin-github-updater) diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php index 334a0d5..8119b0d 100644 --- a/vendor/composer/installed.php +++ b/vendor/composer/installed.php @@ -3,7 +3,7 @@ 'name' => 'soderlind/additional-javascript', 'pretty_version' => 'dev-main', 'version' => 'dev-main', - 'reference' => 'f75e4faf5bf987362eca6385bb4c10d6dd9dbf9b', + 'reference' => '22f23630ecfe19338e339f4c91e96d87e550ae88', 'type' => 'wordpress-plugin', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), @@ -13,7 +13,7 @@ 'soderlind/additional-javascript' => array( 'pretty_version' => 'dev-main', 'version' => 'dev-main', - 'reference' => 'f75e4faf5bf987362eca6385bb4c10d6dd9dbf9b', + 'reference' => '22f23630ecfe19338e339f4c91e96d87e550ae88', 'type' => 'wordpress-plugin', 'install_path' => __DIR__ . '/../../', 'aliases' => array(),