Skip to content

Commit d41fa74

Browse files
committed
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.
1 parent 6cee73e commit d41fa74

File tree

4 files changed

+472
-61
lines changed

4 files changed

+472
-61
lines changed

README-UPDATER.md

Lines changed: 316 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,316 @@
1+
# WordPress Plugin GitHub Updater
2+
3+
A reusable WordPress plugin updater class that handles automatic updates from GitHub repositories using the `yahnis-elsts/plugin-update-checker` library.
4+
5+
## Table of Contents
6+
7+
- [Files Overview](#files-overview)
8+
- [Quick Start](#quick-start)
9+
- [Configuration Parameters](#configuration-parameters)
10+
- [GitHub Workflow for Automatic Release Assets](#github-workflow-for-automatic-release-assets)
11+
- [Usage Examples](#usage-examples)
12+
- [Customizing the Class](#customizing-the-class)
13+
- [Dependencies](#dependencies)
14+
- [Key Features](#key-features)
15+
- [Best Practices](#best-practices)
16+
- [Error Handling](#error-handling)
17+
- [License](#license)
18+
19+
## Files Overview
20+
21+
- `class-github-plugin-updater.php` - **Recommended generic class** with better error handling
22+
- `class-additional-javascript-updater.php` - Modified original class with backward compatibility
23+
- `example-generic-updater.php` - Example implementations
24+
25+
## Quick Start
26+
27+
### 1. Copy the updater class to your plugin
28+
Copy `class-github-plugin-updater.php` to your plugin directory.
29+
30+
### 2. Include the class in your main plugin file
31+
```php
32+
require_once plugin_dir_path( __FILE__ ) . 'class-github-plugin-updater.php';
33+
```
34+
35+
### 3. Initialize with your plugin's configuration
36+
37+
#### Simple Usage (Recommended)
38+
```php
39+
<?php
40+
$updater = \Soderlind\WordPress\GitHub_Plugin_Updater::create(
41+
'https://github.com/username/plugin-name',
42+
__FILE__,
43+
'plugin-name'
44+
);
45+
```
46+
47+
#### With Custom Branch
48+
```php
49+
<?php
50+
$updater = \Soderlind\WordPress\GitHub_Plugin_Updater::create(
51+
'https://github.com/username/plugin-name',
52+
__FILE__,
53+
'plugin-name',
54+
'develop' // Branch name
55+
);
56+
```
57+
58+
#### With Release Assets
59+
```php
60+
<?php
61+
$updater = \Soderlind\WordPress\GitHub_Plugin_Updater::create_with_assets(
62+
'https://github.com/username/plugin-name',
63+
__FILE__,
64+
'plugin-name',
65+
'/plugin-name\.zip/' // Regex pattern for zip file
66+
);
67+
```
68+
69+
#### Advanced Configuration
70+
```php
71+
<?php
72+
$updater = new \Soderlind\WordPress\GitHub_Plugin_Updater( array(
73+
'github_url' => 'https://github.com/username/plugin-name',
74+
'plugin_file' => __FILE__,
75+
'plugin_slug' => 'plugin-name',
76+
'branch' => 'main',
77+
'name_regex' => '/plugin-name-v[\d\.]+\.zip/',
78+
'enable_release_assets' => true,
79+
) );
80+
```
81+
82+
## Configuration Parameters
83+
84+
| Parameter | Required | Description | Example |
85+
|-----------|----------|-------------|---------|
86+
| `github_url` | Yes | GitHub repository URL | `'https://github.com/username/plugin-name'` |
87+
| `plugin_file` | Yes | Path to main plugin file | `__FILE__` or `PLUGIN_CONSTANT_FILE` |
88+
| `plugin_slug` | Yes | Plugin slug for WordPress | `'my-awesome-plugin'` |
89+
| `branch` | No | Git branch to check for updates | `'master'` (default), `'main'`, `'develop'`.<br> [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. |
90+
| `name_regex` | No | Regex pattern for release assets | `'/plugin-name\.zip/'` |
91+
| `enable_release_assets` | No | Whether to enable release assets | `true` if name_regex provided |
92+
93+
## GitHub Workflow for Automatic Release Assets
94+
95+
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.
96+
97+
### Setup: Create `.github/workflows/on-release-add.zip.yml`
98+
99+
```yaml
100+
name: On Release, Build release zip
101+
102+
on:
103+
release:
104+
types: [published]
105+
106+
jobs:
107+
build:
108+
name: Build release zip
109+
runs-on: ubuntu-latest
110+
permissions:
111+
contents: write
112+
steps:
113+
- name: Checkout
114+
uses: actions/checkout@v4
115+
116+
- name: Build plugin # Remove or modify this step as needed
117+
run: |
118+
composer install --no-dev
119+
120+
- name: Archive Release
121+
uses: thedoctor0/zip-release@b57d897cb5d60cb78b51a507f63fa184cfe35554 #0.7.6
122+
with:
123+
type: 'zip'
124+
filename: 'your-plugin-name.zip' # Change this to match your plugin
125+
exclusions: '*.git* .editorconfig composer* *.md package.json package-lock.json'
126+
127+
- name: Release
128+
uses: softprops/action-gh-release@c95fe1489396fe8a9eb87c0abf8aa5b2ef267fda #v2
129+
env:
130+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
131+
with:
132+
files: your-plugin-name.zip # Change this to match your plugin
133+
tag_name: ${{ github.event.release.tag_name }}
134+
```
135+
136+
### How it Works
137+
138+
1. **Trigger**: Automatically runs when you publish a GitHub release
139+
2. **Build**: Installs production dependencies with `composer install --no-dev`
140+
3. **Archive**: Creates a zip file excluding development files
141+
4. **Attach**: Adds the zip file to the GitHub release as an asset
142+
143+
### Customizing the Workflow
144+
145+
- **Change filename**: Update both `filename:` and `files:` to match your plugin name
146+
- **Modify exclusions**: Add or remove files/patterns from the `exclusions:` list
147+
- **Build step**: Modify the build process (npm, webpack, etc.) as needed for your plugin
148+
149+
### Example Release Asset URLs
150+
151+
After the workflow runs, your release assets will be available at URLs like:
152+
153+
```
154+
https://github.com/username/plugin-name/releases/latest/download/plugin-name.zip
155+
```
156+
157+
**Real example from this plugin:**
158+
```
159+
https://github.com/soderlind/additional-javascript/releases/latest/download/additional-javascript.zip
160+
```
161+
162+
### Using with the Updater
163+
164+
When using release assets, configure your updater like this:
165+
166+
```php
167+
<?php
168+
$updater = \Soderlind\WordPress\GitHub_Plugin_Updater::create_with_assets(
169+
'https://github.com/username/plugin-name',
170+
__FILE__,
171+
'plugin-name',
172+
'/plugin-name\.zip/' // This regex will match the zip created by the workflow
173+
);
174+
```
175+
176+
## Usage Examples
177+
178+
### Example 1: Basic Plugin Update
179+
```php
180+
<?php
181+
// In your main plugin file
182+
define( 'MY_PLUGIN_FILE', __FILE__ );
183+
184+
require_once plugin_dir_path( __FILE__ ) . 'class-github-plugin-updater.php';
185+
186+
$my_plugin_updater = \Soderlind\WordPress\GitHub_Plugin_Updater::create(
187+
'https://github.com/myusername/my-awesome-plugin',
188+
MY_PLUGIN_FILE,
189+
'my-awesome-plugin'
190+
);
191+
```
192+
193+
### Example 2: With Custom Branch and Asset Pattern
194+
```php
195+
<?php
196+
$updater = \Soderlind\WordPress\GitHub_Plugin_Updater::create_with_assets(
197+
'https://github.com/company/enterprise-plugin',
198+
__FILE__,
199+
'enterprise-plugin',
200+
'/enterprise-plugin-v[\d\.]+\.zip/',
201+
'release' // Custom branch
202+
);
203+
```
204+
205+
### Example 3: Multiple Plugins in Same Project
206+
```php
207+
<?php
208+
// Plugin A
209+
$plugin_a_updater = \Soderlind\WordPress\GitHub_Plugin_Updater::create_with_assets(
210+
'https://github.com/mycompany/plugin-suite',
211+
plugin_dir_path( __FILE__ ) . 'plugin-a/plugin-a.php',
212+
'plugin-a',
213+
'/plugin-a\.zip/'
214+
);
215+
216+
// Plugin B
217+
$plugin_b_updater = \Soderlind\WordPress\GitHub_Plugin_Updater::create_with_assets(
218+
'https://github.com/mycompany/plugin-suite',
219+
plugin_dir_path( __FILE__ ) . 'plugin-b/plugin-b.php',
220+
'plugin-b',
221+
'/plugin-b\.zip/'
222+
);
223+
```
224+
225+
### Example 4: Full Configuration Control
226+
```php
227+
<?php
228+
$updater = new \Soderlind\WordPress\GitHub_Plugin_Updater( array(
229+
'github_url' => 'https://github.com/mycompany/premium-plugin',
230+
'plugin_file' => __FILE__,
231+
'plugin_slug' => 'premium-plugin',
232+
'branch' => 'stable',
233+
'name_regex' => '/premium-plugin-pro-v[\d\.]+\.zip/',
234+
'enable_release_assets' => true,
235+
) );
236+
```
237+
238+
## Customizing the Class
239+
240+
### Option 1: Rename the Class
241+
If you want to avoid conflicts, rename the class:
242+
243+
```php
244+
<?php
245+
namespace YourCompany\YourPlugin;
246+
247+
use YahnisElsts\PluginUpdateChecker\v5\PucFactory;
248+
249+
class Your_Plugin_Updater extends \Soderlind\WordPress\GitHub_Plugin_Updater {
250+
// Inherit all functionality, customize as needed
251+
}
252+
```
253+
254+
### Option 2: Create Plugin-Specific Wrapper
255+
Create a plugin-specific version:
256+
257+
```php
258+
<?php
259+
namespace YourCompany\YourPlugin;
260+
261+
class Your_Plugin_Updater {
262+
private $updater;
263+
264+
public function __construct() {
265+
$this->updater = \Soderlind\WordPress\GitHub_Plugin_Updater::create(
266+
'https://github.com/yourcompany/your-plugin',
267+
YOUR_PLUGIN_FILE,
268+
'your-plugin'
269+
);
270+
}
271+
}
272+
```
273+
274+
## Dependencies
275+
276+
This updater requires the `yahnis-elsts/plugin-update-checker` library:
277+
278+
```bash
279+
composer require yahnis-elsts/plugin-update-checker
280+
```
281+
282+
Or download it manually from: https://github.com/YahnisElsts/plugin-update-checker
283+
284+
## Key Features
285+
286+
-**Automatic updates** from GitHub releases
287+
-**Custom branch support** for development/staging
288+
-**Release asset filtering** with regex patterns
289+
-**Error handling** with debug logging
290+
-**Multiple initialization methods** (static factories)
291+
-**Parameter validation** with meaningful error messages
292+
-**Flexible configuration** options
293+
-**Fully documented** with examples
294+
295+
## Best Practices
296+
297+
1. **Use Constants**: Define your plugin file as a constant for consistency
298+
2. **Static Factory Methods**: Use `::create()` methods for simpler initialization
299+
3. **Error Handling**: The updater includes proper validation and debug logging
300+
4. **Testing**: Test with different branch names and release asset patterns
301+
5. **Documentation**: Document your specific configuration for future reference
302+
6. **Namespace**: Consider using your own namespace to avoid conflicts
303+
304+
## Error Handling
305+
306+
The `GitHub_Plugin_Updater` class includes robust error handling:
307+
308+
- **Parameter Validation**: Required parameters are validated on construction
309+
- **Exception Handling**: Gracefully handles errors during update check setup
310+
- **Debug Logging**: Errors are logged when `WP_DEBUG` is enabled
311+
- **Graceful Degradation**: Plugin continues to work even if updater fails
312+
313+
314+
## License
315+
316+
GPL-2.0+ (same as the original plugin)

additional-javascript.php

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,16 @@
3030
define( 'ADDITIONAL_JAVASCRIPT_PATH', plugin_dir_path( ADDITIONAL_JAVASCRIPT_FILE ) );
3131

3232
require_once ADDITIONAL_JAVASCRIPT_PATH . 'vendor/autoload.php';
33-
/**
34-
* Load the plugin updater class.
35-
*/
36-
require_once dirname( __FILE__ ) . '/class-additional-javascript-updater.php';
37-
// Initialize the updater.
38-
$additional_javascript_updater = new Additional_JavaScript_Updater();
33+
// Include the generic updater class
34+
require_once dirname( __FILE__ ) . '/class-github-plugin-updater.php';
35+
// Initialize the updater with configuration.
36+
$additional_javascript_updater = \Soderlind\WordPress\GitHub_Plugin_Updater::create_with_assets(
37+
'https://github.com/soderlind/additional-javascript',
38+
ADDITIONAL_JAVASCRIPT_FILE,
39+
'additional-javascript',
40+
'/additional-javascript\.zip/',
41+
'main'
42+
);
3943

4044
add_action( 'init', __NAMESPACE__ . '\register_post_type_javascript', 0 );
4145
add_action( 'wp_head', __NAMESPACE__ . '\soderlind_custom_javascript_cb', 110 );

class-additional-javascript-updater.php

Lines changed: 0 additions & 55 deletions
This file was deleted.

0 commit comments

Comments
 (0)