Compare commits

..

11 commits
v1.0.9 ... main

Author SHA1 Message Date
Alexandre Froger
4847ed1ed7 Merge remote-tracking branch 'origin/dev' into dev 2025-06-06 10:38:37 +08:00
Alexandre Froger
84da98bc6a Fix activation issue - WP_Filesystem call 2025-06-06 10:38:22 +08:00
Alexandre Froger
8356ac6ca2 fix nonce cleanup 2025-06-04 21:40:26 +08:00
Alexandre Froger
8efebb1774 wl to readme links 2025-04-28 10:41:48 +08:00
Alexandre Froger
575c7c3cdb readme update 2025-04-28 10:38:14 +08:00
Alexandre Froger
e1fc90780e typo fix 2025-04-28 10:37:47 +08:00
Alexandre Froger
deda3090c3 readme Companion Plugins 2025-04-28 10:36:13 +08:00
Alexandre Froger
15ce059512 email fix 2025-04-28 10:35:17 +08:00
Alexandre Froger
c6155be1fa Introduce constant PUC_FORCE_BRANCH to bypass tags & releases in VCS detection strategies 2025-04-22 11:33:02 +08:00
Alexandre Froger
ec8856175b Introduce constant PUC_FORCE_BRANCH to bypass tags & releases in VCS detection strategies 2025-04-22 10:18:53 +08:00
Alexandre Froger
d4a206ab1f donate link 2025-04-14 07:47:20 +08:00
10 changed files with 64 additions and 18 deletions

View file

@ -151,7 +151,7 @@ Name | Type | Description
Enable VCS | checkbox | Enables this server to download packages from a Version Control System before delivering updates.<br/>Supports Bitbucket, Github and Gitlab.<br/>If left unchecked, zip packages need to be manually uploaded to `wp-content/plugins/updatepulse-server/packages`. Enable VCS | checkbox | Enables this server to download packages from a Version Control System before delivering updates.<br/>Supports Bitbucket, Github and Gitlab.<br/>If left unchecked, zip packages need to be manually uploaded to `wp-content/plugins/updatepulse-server/packages`.
VCS URL | text | The URL of the Version Control System where packages are hosted.<br/>Must follow the following pattern: `https://version-control-system.tld/username` where `https://version-control-system.tld` may be a self-hosted instance of Gitlab.<br/>Each package repository URL must follow the following pattern: `https://version-control-system.tld/username/package-slug/`; the package files must be located at the root of the repository, and in the case of WordPress plugins the main plugin file must follow the pattern `package-slug.php`. VCS URL | text | The URL of the Version Control System where packages are hosted.<br/>Must follow the following pattern: `https://version-control-system.tld/username` where `https://version-control-system.tld` may be a self-hosted instance of Gitlab.<br/>Each package repository URL must follow the following pattern: `https://version-control-system.tld/username/package-slug/`; the package files must be located at the root of the repository, and in the case of WordPress plugins the main plugin file must follow the pattern `package-slug.php`.
Self-hosted VCS | checkbox | Check this only if the Version Control System is a self-hosted instance of Gitlab. Self-hosted VCS | checkbox | Check this only if the Version Control System is a self-hosted instance of Gitlab.
Packages branch name | text | The branch to download when getting remote packages from the Version Control System. Packages branch name | text | The branch to download when getting remote packages from the Version Control System.<br/>If the VCS supports releases or tags, they will be prioritised over the branch name (release first, then tag, then branch).<br/>To bypass this behaviour, set the `PUC_FORCE_BRANCH` constant to `true` in `wp-config.php`.
VCS credentials | text | Credentials for non-publicly accessible repositories.<br/>In the case of Github and Gitlab, a Personal Access Token; in the case of Bitckucket, an App Password.<br/>**WARNING: Keep these credentials secret, do not share them, and take care of renewing them before they expire!** VCS credentials | text | Credentials for non-publicly accessible repositories.<br/>In the case of Github and Gitlab, a Personal Access Token; in the case of Bitckucket, an App Password.<br/>**WARNING: Keep these credentials secret, do not share them, and take care of renewing them before they expire!**
Use Webhooks | checkbox | Check so that each repository of the Version Control System calls a Webhook when updates are pushed.<br>When checked, UpdatePulse Server will not regularly poll repositories for package version changes, but relies on events sent by the repositories to schedule a package download.<br>Webhook URL: `https://domain.tld/updatepulse-server-webhook/package-type/package-slug` - where `package-type` is the package type (`plugin`, `theme`, or `generic`) and `package-slug` is the slug of the package that needs updates.<br>Note that UpdatePulse Server does not rely on the content of the payload to schedule a package download, so any type of event can be used to trigger the Webhook. Use Webhooks | checkbox | Check so that each repository of the Version Control System calls a Webhook when updates are pushed.<br>When checked, UpdatePulse Server will not regularly poll repositories for package version changes, but relies on events sent by the repositories to schedule a package download.<br>Webhook URL: `https://domain.tld/updatepulse-server-webhook/package-type/package-slug` - where `package-type` is the package type (`plugin`, `theme`, or `generic`) and `package-slug` is the slug of the package that needs updates.<br>Note that UpdatePulse Server does not rely on the content of the payload to schedule a package download, so any type of event can be used to trigger the Webhook.
Remote Download Delay | number | Delay in minutes after which UpdatePulse Server will poll the Version Control System for package updates when the Webhook has been called.<br>Leave at `0` to schedule a package update during the cron run happening immediately after the Webhook notification was received. Remote Download Delay | number | Delay in minutes after which UpdatePulse Server will poll the Version Control System for package updates when the Webhook has been called.<br>Leave at `0` to schedule a package update during the cron run happening immediately after the Webhook notification was received.

View file

@ -172,6 +172,8 @@ class Data_Manager {
* @since 1.0.0 * @since 1.0.0
*/ */
public static function maybe_setup_mu_plugin() { public static function maybe_setup_mu_plugin() {
WP_Filesystem();

global $wp_filesystem; global $wp_filesystem;


$result = true; $result = true;

View file

@ -588,15 +588,17 @@ class Nonce {
$sql = "DELETE FROM {$wpdb->prefix}upserv_nonce $sql = "DELETE FROM {$wpdb->prefix}upserv_nonce
WHERE expiry < %d WHERE expiry < %d
AND ( AND (
JSON_VALID(`data`) = 1 JSON_VALID(`data`) = 0
AND ( OR (
JSON_EXTRACT(`data` , '$.permanent') IS NULL JSON_VALID(`data`) = 1
OR JSON_EXTRACT(`data` , '$.permanent') = 0 AND (
OR JSON_EXTRACT(`data` , '$.permanent') = '0' JSON_EXTRACT(`data` , '$.permanent') IS NULL
OR JSON_EXTRACT(`data` , '$.permanent') = false OR JSON_EXTRACT(`data` , '$.permanent') = 0
OR JSON_EXTRACT(`data` , '$.permanent') = '0'
OR JSON_EXTRACT(`data` , '$.permanent') = false
)
) )
) OR );";
JSON_VALID(`data`) = 0;";
$sql_args = array( time() - self::DEFAULT_EXPIRY_LENGTH ); $sql_args = array( time() - self::DEFAULT_EXPIRY_LENGTH );


/** /**

View file

@ -52,7 +52,7 @@
printf( printf(
// translators: %s is <code>upserv_download_remote_package( string $package_slug, string $type );</code> // translators: %s is <code>upserv_download_remote_package( string $package_slug, string $type );</code>
esc_html__( '[expert] calling the %s method in your own code, with the VCS-related parameters corresponding to a VCS configuration saved in UpdatePulse Server', 'updatepulse-server' ), esc_html__( '[expert] calling the %s method in your own code, with the VCS-related parameters corresponding to a VCS configuration saved in UpdatePulse Server', 'updatepulse-server' ),
'<code>upserv_download_remote_package( string $package_slug, string $type, string $vcs_url = false, string branch = \'main\');</code>' '<code>upserv_download_remote_package( string $package_slug, string $type, string $vcs_url = false, string branch = \'main\' );</code>'
); );
?> ?>
</li> </li>
@ -285,7 +285,7 @@ Licensed With: another-plugin-or-theme-slug</pre><br>
// translators: %1$s is a link to opening an issue, %2$s is a contact email // translators: %1$s is a link to opening an issue, %2$s is a contact email
esc_html__( 'After reading the documentation, for more help on how to use UpdatePulse Server, please %1$s - bugfixes are welcome via pull requests, detailed bug reports with accurate pointers as to where and how they occur in the code will be addressed in a timely manner, and a fee will apply for any other request (if they are addressed). If and only if you found a security issue, please contact %2$s with full details for responsible disclosure.', 'updatepulse-server' ), esc_html__( 'After reading the documentation, for more help on how to use UpdatePulse Server, please %1$s - bugfixes are welcome via pull requests, detailed bug reports with accurate pointers as to where and how they occur in the code will be addressed in a timely manner, and a fee will apply for any other request (if they are addressed). If and only if you found a security issue, please contact %2$s with full details for responsible disclosure.', 'updatepulse-server' ),
'<a target="_blank" href="https://github.com/anyape/updatepulse-server/issues">' . esc_html__( 'open an issue on Github', 'updatepulse-server' ) . '</a>', '<a target="_blank" href="https://github.com/anyape/updatepulse-server/issues">' . esc_html__( 'open an issue on Github', 'updatepulse-server' ) . '</a>',
'<a href="mailto:updatepulse@anyape.come">updatepulse@anyape.com</a>', '<a href="mailto:updatepulse@anyape.com">updatepulse@anyape.com</a>',
); );
?> ?>
</p> </p>

View file

@ -107,7 +107,16 @@
<td> <td>
<input class="vcs-setting regular-text" type="text" id="upserv_vcs_branch" data-prop="branch" value=""> <input class="vcs-setting regular-text" type="text" id="upserv_vcs_branch" data-prop="branch" value="">
<p class="description"> <p class="description">
<?php esc_html_e( 'The branch to download when getting remote packages from the Version Control System.', 'updatepulse-server' ); ?> <?php
printf(
// translators: %1$s line break, %2$s is <code>PUC_FORCE_BRANCH</code>, %3$s is <code>true</code>, %4$s is <code>wp-config.php</code>
esc_html__( 'The branch to download when getting remote packages from the Version Control System.%1$sIf the VCS supports releases or tags, they will be prioritised over the branch name (release first, then tag, then branch).%1$sTo bypass this behaviour and exclusively rely on the branch, set the %2$s constant to %3$s in %4$s.', 'updatepulse-server' ),
'<br/>',
'<code>PUC_FORCE_BRANCH</code>',
'<code>true</code>',
'<code>wp-config.php</code>'
);
?>
</p> </p>
</td> </td>
</tr> </tr>
@ -295,7 +304,16 @@
<td> <td>
<input class="regular-text" type="text" id="upserv_add_vcs_branch" data-prop="branch" value=""> <input class="regular-text" type="text" id="upserv_add_vcs_branch" data-prop="branch" value="">
<p class="description"> <p class="description">
<?php esc_html_e( 'The branch to download when getting remote packages from the Version Control System.', 'updatepulse-server' ); ?> <?php
printf(
// translators: %1$s line break, %2$s is <code>PUC_FORCE_BRANCH</code>, %3$s is <code>true</code>, %4$s is <code>wp-config.php</code>
esc_html__( 'The branch to download when getting remote packages from the Version Control System.%1$sIf the VCS supports releases or tags, they will be prioritised over the branch name (release first, then tag, then branch).%1$sTo bypass this behaviour and exclusively rely on the branch, set the %2$s constant to %3$s in %4$s.', 'updatepulse-server' ),
'<br/>',
'<code>PUC_FORCE_BRANCH</code>',
'<code>true</code>',
'<code>wp-config.php</code>'
);
?>
</p> </p>
</td> </td>
</tr> </tr>

View file

@ -84,7 +84,10 @@ if ( ! class_exists( BitbucketApi::class, false ) ) :
return $this->get_branch( $config_branch ); return $this->get_branch( $config_branch );
}; };


if ( ( 'main' === $config_branch || 'master' === $config_branch ) ) { if (
( 'main' === $config_branch || 'master' === $config_branch ) &&
( ! defined( 'PUC_FORCE_BRANCH' ) || ! (bool) ( constant( 'PUC_FORCE_BRANCH' ) ) )
) {
$strategies[ self::STRATEGY_LATEST_TAG ] = array( $this, 'get_latest_tag' ); $strategies[ self::STRATEGY_LATEST_TAG ] = array( $this, 'get_latest_tag' );
} }



View file

@ -458,7 +458,10 @@ if ( ! class_exists( GitHubApi::class, false ) ) :
protected function get_update_detection_strategies( $config_branch ) { protected function get_update_detection_strategies( $config_branch ) {
$strategies = array(); $strategies = array();


if ( 'main' === $config_branch || 'master' === $config_branch ) { if (
( 'main' === $config_branch || 'master' === $config_branch ) &&
( ! defined( 'PUC_FORCE_BRANCH' ) || ! (bool) ( constant( 'PUC_FORCE_BRANCH' ) ) )
) {
// Use the latest release. // Use the latest release.
$strategies[ self::STRATEGY_LATEST_RELEASE ] = array( $this, 'get_latest_release' ); $strategies[ self::STRATEGY_LATEST_RELEASE ] = array( $this, 'get_latest_release' );
// Failing that, use the tag with the highest version number. // Failing that, use the tag with the highest version number.

View file

@ -440,7 +440,10 @@ if ( ! class_exists( GitLabApi::class, false ) ) :
protected function get_update_detection_strategies( $config_branch ) { protected function get_update_detection_strategies( $config_branch ) {
$strategies = array(); $strategies = array();


if ( ( 'main' === $config_branch ) || ( 'master' === $config_branch ) ) { if (
( 'main' === $config_branch ) || ( 'master' === $config_branch ) &&
( ! defined( 'PUC_FORCE_BRANCH' ) || ! (bool) ( constant( 'PUC_FORCE_BRANCH' ) ) )
) {
$strategies[ self::STRATEGY_LATEST_RELEASE ] = array( $this, 'get_latest_release' ); $strategies[ self::STRATEGY_LATEST_RELEASE ] = array( $this, 'get_latest_release' );
$strategies[ self::STRATEGY_LATEST_TAG ] = array( $this, 'get_latest_tag' ); $strategies[ self::STRATEGY_LATEST_TAG ] = array( $this, 'get_latest_tag' );
} }

View file

@ -1,9 +1,10 @@
=== UpdatePulse Server === === UpdatePulse Server ===
Contributors: frogerme Contributors: frogerme
Donate link: https://paypal.me/frogerme
Tags: Plugin updates, Theme updates, WordPress updates, License Tags: Plugin updates, Theme updates, WordPress updates, License
Requires at least: 6.7 Requires at least: 6.7
Tested up to: 6.7 Tested up to: 6.7
Stable tag: 1.0.9 Stable tag: 1.0.10
Requires PHP: 8.0 Requires PHP: 8.0
License: GPLv2 or later License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-3.0.html License URI: https://www.gnu.org/licenses/gpl-3.0.html
@ -46,6 +47,15 @@ This plugin adds the following major features to WordPress:
* **API:** UpdatePulse Server provides APIs to manage packages and licenses. The APIs keys are secured with a system of tokens: the API keys are never shared over the network, acquiring a token requires signed payloads, and the tokens have a limited lifetime. For more details about tokens and security, see [the Nonce API documentation](https://github.com/anyape/updatepulse-server/blob/main/docs/misc.md#nonce-api). * **API:** UpdatePulse Server provides APIs to manage packages and licenses. The APIs keys are secured with a system of tokens: the API keys are never shared over the network, acquiring a token requires signed payloads, and the tokens have a limited lifetime. For more details about tokens and security, see [the Nonce API documentation](https://github.com/anyape/updatepulse-server/blob/main/docs/misc.md#nonce-api).


To connect their plugins or themes and UpdatePulse Server, developers can find integration examples in the [UpdatePulse Server Integration Examples](https://github.com/Anyape/updatepulse-server-integration) repository - theme and plugin examples rely heavily on the popular [Plugin Update Checker](https://github.com/YahnisElsts/plugin-update-checker) by [Yahnis Elsts](https://github.com/YahnisElsts). To connect their plugins or themes and UpdatePulse Server, developers can find integration examples in the [UpdatePulse Server Integration Examples](https://github.com/Anyape/updatepulse-server-integration) repository - theme and plugin examples rely heavily on the popular [Plugin Update Checker](https://github.com/YahnisElsts/plugin-update-checker) by [Yahnis Elsts](https://github.com/YahnisElsts).
== Companion Plugins ==

The following plugins are compatible with UpdatePulse Server and can be used to extend its functionality:
* [Updatepulse Blocks](https://store.anyape.com/product/updatepulse-blocks/?wl=1): a seamless way to display packages from UpdatePulse Server directly within your site using the WordPress Block Editor or shortcodes.
* [UpdatePulse for WooCommerce](https://store.anyape.com/product/updatepulse-for-woocommerce/?wl=1): a WooCommerce connector for UpdatePulse Server, allowing you to sell licensed packages through your WooCommerce store, either on the same WordPress installation or a separate store site.

Developers are encouraged to build plugins and themes [integrated](https://github.com/anyape/updatepulse-server/blob/main/README.md) with UpdatePulse Server, leveraging its publicly available functions, actions and filters, or by making use of the provided APIs.

If you wish to see your plugin added to this list, please [contact the author](mailto:updatepulse@anyape.com).


== Troubleshooting == == Troubleshooting ==


@ -128,6 +138,11 @@ This section describes how to install the plugin and get it working.


== Changelog == == Changelog ==


= 1.0.10 =
* Introduce constant `PUC_FORCE_BRANCH` to bypass tags & releases in VCS detection strategies
* Minor fix
* Fix activation issue - `WP_Filesystem` call

= 1.0.9 = = 1.0.9 =
* Schedule mode: remove package metadata files when deleting packages * Schedule mode: remove package metadata files when deleting packages
* Schedule mode: make sure to reinitialise the update checker to avoid slug conflicts * Schedule mode: make sure to reinitialise the update checker to avoid slug conflicts

View file

@ -3,7 +3,7 @@
* Plugin Name: UpdatePulse Server * Plugin Name: UpdatePulse Server
* Plugin URI: https://github.com/anyape/updatepulse-server/ * Plugin URI: https://github.com/anyape/updatepulse-server/
* Description: Run your own update server. * Description: Run your own update server.
* Version: 1.0.9 * Version: 1.0.10
* Author: Alexandre Froger * Author: Alexandre Froger
* Author URI: https://froger.me/ * Author URI: https://froger.me/
* License: GPLv2 or later * License: GPLv2 or later