UpdatePulse Server 运行你自己的更新服务器

介绍

UpdatePulse Server 允许开发者为未托管在 wordpress.org 上的插件和主题提供更新,或为与 WordPress 完全无关的通用包提供更新。它还允许通过许可证控制更新。
包更新可以直接上传,也可以托管在版本控制系统 (VCS) 中,无论是公开还是私有的,最新版本的包可以存储在本地或云端。它支持 Bitbucket 、 Github 、 Gitlab 和自托管的 Gitlab 安装来获取包更新;支持 S3 兼容的服务提供商来存储包。

main 分支包含 UpdatePulse Server 的测试版。 dev 分支包含 UpdatePulse Server 的 alpha 版本。稳定版本请使用 releases 。  

概述

该插件为 WordPress 添加了以下主要功能:

  • 包概览: 通过表格管理包更新,显示包名称、版本、类型、文件名、大小、最后修改时间和许可证状态;包括批量操作 (删除、下载和更改许可证状态),以及删除所有包的功能。可以从本地机器上传更新到 UpdatePulse Server,或让系统自动从版本控制系统下载更新到 UpdatePulse Server 。包可以存储在本地,也可以使用 S3 兼容的服务存储在云端。包也可以通过其自己的 API 进行管理。
  • 版本控制系统: 配置您选择的版本控制系统 (Bitbucket 、 Github 、 Gitlab 或自托管的 Gitlab 安装),使用安全凭证和托管更新的分支名称;选择定期检查更新,或在收到 Webhook 通知时检查更新。 UpdatePulse Server 充当您的仓库、更新存储 (本地或云端) 和客户端之间的中间人。
  • 许可证: 通过表格管理许可证,显示 ID 、许可证密钥、注册邮箱、状态、包类型、包 slug 、创建日期和到期日期;通过表单添加和编辑它们,或使用 API 进行更多控制。许可证可防止安装在客户端机器上的包在没有有效许可证的情况下被更新。默认情况下,许可证是自动生成的,且值不可猜测 (建议保持默认) 。在检查许可证的有效性时,还会检查额外的许可证签名,以防止在超过配置的允许域上使用许可证。
  • 不仅限于 WordPress: 通过平台无关的 API,可以为任何类型的包提供更新,而不仅仅是 WordPress 插件和主题。在文档中提供了与 Node.js 、 PHP 、 bash 和 Python 集成的基本示例。
  • API 和 Webhooks: 使用包 API 管理包 (浏览、读取、编辑、添加、删除),并请求包的可过期签名 URL 以允许安全下载。使用许可证 API 管理许可证 (浏览、读取、编辑、添加、删除) 并检查、激活或停用许可证。触发 Webhooks 以通知您选择的 URL 有关影响包和许可证的关键事件。

开发者可以在此处找到集成示例以连接他们的包和 UpdatePulse Server:

  • 虚拟插件: 一个包含简单空插件的文件夹 dummy-plugin,其中包含 dummy-plugin.php 主插件文件中的必要代码和 lib 文件夹中的必要库。
  • 虚拟主题: 一个包含 Twenty Seventeen 子主题的简单空主题的文件夹 dummy-theme,其中包含 functions.php 文件中的必要代码和 lib 文件夹中的必要库。
  • 虚拟通用包: 一个包含用 bash 、 Node.js 、 PHP 、 bash 和 Python 编写的简单命令行程序的文件夹 dummy-generic 。通过从命令行调用 ./dummy-generic.[js|php|sh|py] 来执行。请参阅 updatepulse-api.[js|php|sh|py] 以获取 API 调用的简单示例。

此外,安装 UpdatePulse Server 时会自动添加一个可定制的 Must Use Plugin 来优化对各种 API 的请求。原始文件可以在 updatepulse-server/optimisation/upserv-endpoint-optimizer.php 中找到。  

特别感谢

衷心感谢 Yahnis Elsts,他是 Plugin Update CheckerWP Update Server 库的作者,没有他,这个插件的创建将不可能实现。  
此处已慷慨授予使用这些库的自由,前提是包含相关许可证。

兼容性

  • 已在 PHP 8.x 上测试 – 可能在 PHP 7.x 版本上大部分情况下也能工作,但不能保证
  • WordPress 包的集成示例使用 Plugin Update Checker 库 5.3

欢迎并强烈鼓励提交拉取请求以解决任何错误、提高性能并保持库的最新状态。  
不会处理调试或排除特定设置的请求。

截图

注意:截图会定期更新,但实际界面可能会略有不同。

包概览

包概览

版本控制系统

版本控制系统

许可证

许可证

API 和 Webhooks

API 和 Webhooks

客户端 – 插件界面

插件
插件详情

客户端 – 主题界面

主题
主题详情
主题许可证

客户端 – 更新界面

更新

用户界面

UpdatePulse Server 提供了一个用户界面来管理包、管理许可证、管理版本控制系统连接以及配置 API 和 Webhooks 。

包概览

此选项卡允许管理员:

  • 查看 UpdatePulse Server 中当前可用的包列表,显示包名称、版本、类型 (插件或主题) 、文件名、大小、最后修改时间和许可证状态 (如果启用)
  • 下载包
  • 删除包
  • 对包列表应用批量操作 (下载、删除)
  • 添加包 (可以直接上传,或通过从配置的版本控制系统中拉取来注册包)
  • 配置和测试云存储服务
  • 配置其他与包相关的设置 – 文件上传、缓存和日志的最大大小。

可用的设置如下:

名称                               类型     描述
使用云存储                   复选框勾选以使用云存储服务 – S3 兼容。
如果不存在,将在选择的存储单元中创建一个虚拟文件夹 updatepulse-packages 用于包存储。
云存储访问密钥           文本     云存储服务提供商提供的访问密钥。
云存储密钥           文本     云存储服务提供商提供的密钥。
云存储端点             文本     云存储服务的端点域名 (不带 http://https://) 。
云存储单元                 文本     通常称为 「bucket」 或 「container」,具体取决于云存储服务提供商。
云存储区域               文本     云存储单元的区域,由云存储服务提供商指示。
压缩包最大大小 (MB)           数字   上传或下载包时的最大文件大小。
缓存最大大小 (MB)             数字   wp-content/updatepulse-server/cache 目录的最大大小 (MB) 。如果目录的大小超过此值,将在下次 cron 运行时删除其内容 (每小时检查一次) 。 「强制清理」 按钮中显示的大小是实际当前大小。
日志最大大小 (MB)               数字   wp-content/updatepulse-server/logs 目录的最大大小 (MB) 。如果目录的大小超过此值,将在下次 cron 运行时删除其内容 (每小时检查一次) 。 「强制清理」 按钮中显示的大小是实际当前大小。

提供了一个按钮,用于向云存储服务发送测试请求。该请求检查提供商是否可访问以及存储单元是否存在且可写。  
如果在测试期间不存在,将在选择的存储单元中创建一个虚拟文件夹 updatepulse-packages 用于包存储。  

版本控制系统

此选项卡允许管理员配置如何处理远程源,并提供以下设置:

名称                         类型     描述
启用 VCS                   复选框 启用此服务器以在提供更新之前从版本控制系统下载包。
支持 Bitbucket 、 Github 和 Gitlab 。
如果未勾选,则需要手动将 zip 包上传到 wp-content/plugins/updatepulse-server/packages
VCS URL                       文本     托管包的版本控制系统的 URL 。
必须遵循以下模式:https://version-control-system.tld/username,其中 https://version-control-system.tld 可能是自托管的 Gitlab 实例。
每个包仓库的 URL 必须遵循以下模式:https://version-control-system.tld/username/package-slug/;包文件必须位于仓库的根目录,对于 WordPress 插件,主插件文件必须遵循 package-slug.php 的模式。
自托管 VCS               复选框 仅当版本控制系统是自托管的 Gitlab 实例时才勾选此项。
包分支名称         文本     从版本控制系统获取远程包时要下载的分支。
VCS 凭证               文本     用于非公开访问仓库的凭证。
对于 Github 和 Gitlab,使用个人访问令牌;对于 Bitbucket,使用应用密码。
警告:请保密这些凭证,不要共享它们,并注意在它们过期之前续订!
使用 Webhooks                 复选框 勾选此项以便版本控制系统的每个仓库在推送更新时调用 Webhook 。
勾选后,UpdatePulse Server 将不会定期轮询仓库以检查包版本更改,而是依赖仓库发送的事件来安排包下载。
Webhook URL:https://domain.tld/updatepulse-server-webhook/package-type/package-slug – 其中 package-type 是包类型 (pluginthemegeneric),package-slug 是需要更新的包的 slug 。
请注意,UpdatePulse Server 不依赖有效负载的内容来安排包下载,因此可以使用任何类型的事件来触发 Webhook 。
远程下载延迟         数字   在调用 Webhook 后,UpdatePulse Server 将轮询版本控制系统以获取包更新的延迟时间 (分钟) 。
设置为 0 以在收到 Webhook 通知后立即安排包更新。
VCS Webhook 密钥           文本     理想情况下是一个随机字符串,仓库服务在调用 Webhook 时包含在请求中的密钥字符串。
警告:更改此值将使所有包仓库上设置的所有现有 Webhook 失效。
更改此设置后,请确保更新仓库服务中的 Webhook 密钥。
远程更新检查频率选择   仅在不使用 Webhooks 时可用 – UpdatePulse Server 将轮询每个版本控制系统以获取包更新的频率 – 检查过于频繁可能会减慢服务器速度 (建议 「每天一次」) 。

提供了一个按钮,用于向版本控制系统发送测试请求。该请求检查服务是否可访问以及请求是否可以验证。  
不支持通过此按钮测试 Bitbucket;如果使用 Bitbucket,应在保存设置后尝试在 「包概览」 选项卡中注册包进行测试。  

如果不使用 Webhooks,以下操作可用于强制更改包的计划 (维护、测试等):

  • 清除所有计划的远程更新
  • 重新安排所有远程更新

许可证

此选项卡允许管理员:

  • 完全启用/禁用包许可证。它会影响所有由 UpdatePulse Server 提供的具有 「需要许可证」 状态的包。
  • 查看 UpdatePulse Server 当前存储的许可证列表,显示许可证密钥、注册邮箱、状态、包类型 (插件或主题) 、包 slug 、创建日期、到期日期、 ID
  • 添加许可证
  • 编辑许可证
  • 删除许可证
  • 对许可证列表应用批量操作 (删除、更改许可证状态)

API 和 Webhooks

此选项卡允许管理员配置:

  • 包 API 以管理包 (浏览、读取、编辑、添加、删除),请求包的可过期签名 URL 以允许安全下载,并请求令牌和真正的 nonce 。
  • 许可证 API 以管理许可证 (浏览、读取、编辑、添加、删除) 并检查、激活或停用许可证。
  • 通过 Webhooks 通知的 URL 列表,提供以下可用事件: –  包事件 (package) – 包添加或更新 (package_update) – 包删除 (package_delete) – 通过签名 URL 下载包 (package_download)
    • 许可证事件 (license)
      • 许可证激活 (license_activate)
      • 许可证停用 (license_deactivate)
      • 许可证添加 (license_add)
      • 许可证编辑 (license_edit)
      • 许可证删除 (license_delete)

可用设置:

名称                                     描述
私有 API 密钥 (包 API)           多个值;创建密钥需要 「包密钥 ID」 用于标识包密钥。
用于签名请求以获取用于包管理操作 (浏览、读取、编辑、添加、删除) 和获取包的签名 URL 的令牌。
包密钥 ID 只能包含数字、字母、-_
警告:请保密这些密钥,不要与客户共享任何密钥!
IP 白名单 (包 API)               多个值。
授权使用包私有 API 的远程站点的 IP 地址和/或 CIDR 列表 (每行一个 IP 地址或 CIDR) 。
留空以接受任何 IP 地址 (不推荐) 。
私有 API 密钥 (许可证 API)         多个值;创建密钥需要 「许可证密钥 ID」 用于标识包密钥。
用于签名请求以获取用于许可证管理操作 (浏览、读取、编辑、添加、删除) 的令牌。
许可证密钥 ID 只能包含数字、字母、-_
警告:请保密这些密钥,不要与客户共享任何密钥!
IP 白名单 (许可证 API)               多个值。
授权使用许可证私有 API 的远程站点的 IP 地址和/或 CIDR 列表 (每行一个 IP 地址或 CIDR) 。
留空以接受任何 IP 地址 (不推荐) 。
Webhook                                 多个值;创建 Webhook 需要 「有效负载 URL」 、 secret-key 和事件列表。
Webhooks 是在下次 cronjob 时 (事件发生后 1 分钟内,服务器 cron 配置为每分钟执行一次) 发送到任意 URL 的事件通知。事件与数据有效负载一起发送,用于第三方服务集成。
为了允许接收者验证通知,有效负载使用 secret-key 密钥通过 sha256 算法进行签名;生成的哈希值在 X-UpdatePulse-Signature-256 标头中提供。
secret-key 必须至少 16 个字符长,理想情况下是一个随机字符串。
有效负载通过 POST 请求以 JSON 格式发送。
警告:仅添加您信任的 URL!

性能

以下性能数据是在一个廉价的共享主机服务器 (每月不到 10 美元) 上收集的,内存为 256 MB,没有挂接到 UpdatePulse Server 操作或过滤器的任何功能,没有 Webhook,并且启用了 MU 插件端点优化器。根据您的服务器配置和您可能添加到 WordPress 安装的各种优化,您的实际性能可能会有所不同。  

总体结论是,大多数 API 调用的负载比加载绝大多数 WordPress 主页 (可能是任何网站上访问量最大的页面) 更轻、更快,并且比 WordPress ajax 调用更轻 (不考虑额外的优化和激进的缓存) 。

基准测试

使用 dummy-theme 、空静态主页且没有活动插件加载全新 WordPress 安装的前端页面的性能:  

--- 开始加载测试 ---
耗时:0.031
总服务器内存使用量:3.5 M / 4096M
总查询数:11
总脚本数:455
--- 结束加载测试 ---

更新 API

性能可以通过位于插件根目录的 tests.php 脚本进行评估。只有在 wp-config.php 常量 UPSERV_ENABLE_TEST 为真时才会包含该脚本。  
以下是未勾选 「使用云存储」 选项时更新 API 的测试结果。  

客户端检查更新时的性能 (无许可证):

--- 开始加载测试 ---
耗时:0.017
总服务器内存使用量:2.17 M / 4096M
总查询数:5
总脚本数:416
插件使用的服务器内存:118.57 K / 4096M
插件执行的查询数:4
插件包含/需要的脚本数:52
--- 结束加载测试 ---

客户端下载更新时的性能 (YMMV:下载 dummy-plugin – 无许可证):

--- 开始加载测试 ---
耗时:0.018
总服务器内存使用量:2.17 M / 4096M
总查询数:6
总脚本数:415
插件使用的服务器内存:118.57 K / 4096M
插件执行的查询数:5
插件包含/需要的脚本数:51
--- 结束加载测试 ---

客户端检查更新时的性能 (有许可证):

--- 开始加载测试 ---
耗时:0.017
总服务器内存使用量:2.18 M / 4096M
总查询数:7
总脚本数:417
插件使用的服务器内存:118.57 K / 4096M
插件执行的查询数:6
插件包含/需要的脚本数:53
--- 结束加载测试 ---

客户端下载更新时的性能 (YMMV:下载 dummy-plugin – 有许可证):

--- 开始加载测试 ---
耗时:0.029
总服务器内存使用量:2.18 M / 4096M
总查询数:7
总脚本数:417
插件使用的服务器内存:118.57 K / 4096M
插件执行的查询数:6
插件包含/需要的脚本数:53
--- 结束加载测试 ---

公共许可证 API

性能可以通过位于插件根目录的 tests.php 脚本进行评估。只有在 wp-config.php 常量 UPSERV_ENABLE_TEST 为真时才会包含该脚本。  

客户端激活/停用虚假许可证密钥时的性能:

--- 开始加载测试 ---
耗时:0.019
总服务器内存使用量:2.44 M / 4096M
总查询数:4
总脚本数:412
插件使用的服务器内存:395.28 K / 4096M
插件执行的查询数:3
插件包含/需要的脚本数:39
--- 结束加载测试 ---

客户端激活许可证密钥时的性能:

--- 开始加载测试 ---
耗时:0.025
总服务器内存使用量:2.54 M / 4096M
总查询数:9
总脚本数:423
插件使用的服务器内存:460.91 K / 4096M
插件执行的查询数:8
插件包含/需要的脚本数:50
--- 结束加载测试 ---

客户端停用许可证密钥时的性能:

--- 开始加载测试 ---
耗时:0.029
总服务器内存使用量:2.54 M / 4096M
总查询数:9
总脚本数:423
插件使用的服务器内存:461.04 K / 4096M
插件执行的查询数:8
插件包含/需要的脚本数:50
--- 结束加载测试 ---

帮助

以下内容也可以在 UpdatePulse Server 管理页面的 「帮助」 选项卡下找到。  

使用版本控制系统注册插件包

可以通过以下方法注册插件包:

  • [简单] 使用 UpdatePulse Server 的 「包概览」 选项卡中的 「使用 VCS 注册包」 功能
  • [简单] 从已添加到 UpdatePulse Server 的 VCS 触发 Webhook  
    Webhook URL:https://domain.tld/updatepulse-server-webhook/package-type/package-slug – 其中 package-type 是包类型 (pluginthemegeneric),package-slug 是要注册的包的 slug 。
  • [高级] 在命令行中调用 wp updatepulse download_remote_package <package-slug> <plugin|theme|generic>,其中 VCS 相关参数对应于 UpdatePulse Server 中保存的 VCS 配置
  • [专家] 在您自己的代码中调用 upserv_download_remote_package 方法,其中 VCS 相关参数对应于 UpdatePulse Server 中保存的 VCS 配置
  • [专家] 调用 包 APIadd 方法,其中请求有效负载中包含对应于 UpdatePulse Server 中保存的 VCS 配置的 VCS 相关参数

使用 UpdatePulse Server 提供更新 – 插件包的要求

要将您的插件包连接到 UpdatePulse Server,并可选地防止用户在没有许可证的情况下获取包的更新,您的插件包需要包含一些额外的代码。  

对于插件和主题,这相当简单:

  • 在包的根目录中添加一个 lib 目录,其中包含 plugin-update-checkerupdatepulse-updater 库,如 dummy-[plugin|theme] 中提供的;updatepulse-updater 可以根据您的需要进行自定义,但 plugin-update-checker 应保持不变。
  • 在主插件文件 (对于插件) 或 functions.php 文件 (对于主题) 中添加以下代码:
/** 启用更新
&nbsp;* 将 `$prefix_` 替换为 `$prefix_updater` 变量中的唯一字符串以标识您的包。
&nbsp;* 将 vX_X 替换为您使用的 UpdatePulse Updater 的版本。
&nbsp;**/
require_once __DIR__ . '/lib/updatepulse-updater/class-updatepulse-updater.php';

$prefix_updater = new UpdatePulse_Updater(
    wp_normalize_path( __FILE__ ),
    0 === strpos( __DIR__, WP_PLUGIN_DIR ) ? wp_normalize_path( __DIR__ ) : get_stylesheet_directory()
);
  • 可选地在主插件文件或主题的 style.css 文件中添加标头以启用许可证检查:
Require License: yes
Licensed With: another-plugin-or-theme-slug

「Require License」 标头可以是 yestrue1:所有其他值均视为 false;它用于为您的包启用许可证检查。  
「Licensed With」 标头用于将包链接在一起 (例如,在用户已经拥有主插件许可证的情况下,如果此标头存在于扩展中,则许可证检查将针对主插件进行) 。它必须是您 UpdatePulse Server 中已存在的另一个插件或主题的 slug 。  

  • 在包的根目录中添加一个 updatepulse.json 文件,内容如下 – 将 "server" 的值更改为您自己的 (必需):
{
&nbsp; &nbsp;"server": "https://server.domain.tld/"
}
  • 将 UpdatePulse Server 与您的仓库连接并注册您的包,或手动将您的包上传到 UpdatePulse Server 。

对于通用包,涉及的步骤完全取决于编写包所使用的语言和目标平台的更新过程。  
您可以参考此处的文档。

虚拟包可在 UpdatePulse Server 集成 仓库中找到。

除非在 「版本控制系统」 中勾选 「启用 VCS」,否则您需要手动将包的 zip 存档 (及后续更新) 上传到 wp-content/updatepulse-server/packagesCloudStorageUnit://updatepulse-packages/。  包必须是有效的通用包,或有效的 WordPress 插件或主题包,对于插件,主插件文件必须与 zip 存档同名。例如,package-slug.zip 中的主插件文件应为 package-slug.php 。  

计划任务优化

默认情况下,UpdatePulse Server 使用 WordPress cron 系统来安排任务。这意味着任务在访问者访问站点时执行,这可能导致任务执行的延迟。  
这不是最优的:安装 UpdatePulse Server 的网站很可能不打算由用户访问,任务应尽可能接近计划时间执行。

为了确保任务按时执行,建议通过将 WP-Cron 挂接到系统任务调度程序设置真正的 cron 作业。

对于更高级的调度,建议使用 Action Scheduler 插件。  
只需安装并激活该插件,UpdatePulse Server 将自动使用它来安排任务,而不是默认的核心调度程序。

请求优化

当安装插件、主题或通用包的远程客户端发送请求以检查更新、下载包或检查或更改许可证状态时,安装 UpdatePulse Server 的 WordPress 也会加载,包括其自己的插件和主题。  
这不是最优的:请求应尽快处理,并且应尽可能少地加载 WordPress 核心。

为了解决这个问题,Must-Use 插件文件 upserv-default-optimizer.php 在激活 UpdatePulse Server 时会自动复制到 /wp-content/mu-plugins/upserv-default-optimizer.php 。  
它在其他所有内容之前运行,并提供机制以防止 WordPress 核心执行超出严格必要的内容。  
此文件不会影响其他插件的激活状态,在 UpdatePulse 停用时不会产生任何影响,并且在卸载 UpdatePulse Server 时会自动删除。

除了默认优化器外,UpdatePulse Server 集成 仓库还包含更多生产就绪的 Must-Use 插件,开发者可以下载并添加到他们的 UpdatePulse Server 安装中。  
欢迎通过拉取请求贡献。

要更改优化器的行为,请参阅 杂项 中的 upserv_mu_optimizer_* 过滤器。

更多帮助…

有关如何使用 UpdatePulse Server 的更多帮助,请提出问题 – 欢迎通过拉取请求提交错误修复,详细的错误报告 (准确指出代码中发生错误的位置和方式) 将及时处理,其他请求 (如果处理) 将收取费用。  
如果您发现安全问题,请通过 updatepulse@anyape.com 联系并提供完整详细信息以进行负责任的披露。