Download the PHP package webshr/wp-update-server without Composer
On this page you can find all versions of the php package webshr/wp-update-server. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download webshr/wp-update-server
More information about webshr/wp-update-server
Files in webshr/wp-update-server
Package wp-update-server
Short Description Headless standalone update server for WordPress plugins and themes.
License MIT
Homepage https://github.com/webshr/wp-update-server/
Informations about the package wp-update-server
Webshr WP Update Server
A modern, headless, standalone PHP update server for WordPress plugins and themes.
It serves WordPress-compatible update metadata and package downloads without adding a WordPress admin UI or requiring a WordPress installation. Filesystem ZIP packages are supported out of the box, and GitHub Releases can be used as an optional remote package source.
Requirements
- PHP 8.2+
- Composer
- PHP extensions:
json,zip - Writable
storage/packages/,storage/cache/, andstorage/logs/directories
Install
Recommended: start from the ready-to-run app skeleton.
The app skeleton lives at webshr/wp-update-server-app. It includes the deployable project layout: public/index.php, root wpus, config/, storage/, and .env.example.
Create your environment file and configure the server:
Edit .env, then add your packages in config/packages.php.
Validate the app:
Point your web server document root to:
For local testing:
Open:
For installed clients, include their current version:
Library Usage
If you are embedding this library into your own project instead of using the app skeleton, install it with Composer:
Copy the app stubs into your project root:
The copied stubs are bootable files. In particular, stubs/config/packages.php and stubs/config/licenses.php should become config/packages.php and config/licenses.php, not *.example.php files.
When using the library directly, the Composer binary is:
The php wpus ... command is provided by the app skeleton's root wpus file. If you want that command shape in a custom app, copy or create a root wpus launcher there.
Configuration
By default, the server reads configuration from the config/ directory. The HTTP/server settings live in config/server.php, packages in config/packages.php, and licenses in config/licenses.php. config/server.php is required. config/packages.php and config/licenses.php are optional and default to empty arrays when they do not exist.
For custom wiring, copy stubs/update-server.php to a root-level update-server.php aggregate config and edit it. When present, update-server.php overrides the conventional config/*.php loading. A path passed with --config takes precedence over both.
Example config/server.php:
Packages and licenses are provided via config/packages.php and config/licenses.php respectively. These files return arrays that map package slugs and license IDs to their configuration. The stubs at stubs/config/packages.php and stubs/config/licenses.php are bootable defaults with commented examples.
Put a ZIP archive at storage/packages/my-plugin/1.3.0/my-plugin.zip. The ZIP must contain exactly one top-level directory matching the slug:
Validate the setup:
config validate checks signing configuration, writable storage paths, package source definitions, license shape, and trusted proxy settings. It prints warnings for non-fatal operator issues and exits nonzero on errors.
Endpoint Design
The server exposes a fresh path-based API:
/metadata/{slug} selects the best available update version and returns JSON metadata including version, name, requirements, sections, icons/banners, and a download_url when the request is authorized.
/download/{slug}/{version} streams the selected package ZIP through this server with safe download headers. GitHub packages are proxied through this endpoint; clients never need to receive the GitHub asset URL.
There is also a cache invalidation endpoint:
When download signing is enabled, cache invalidation must include a valid signed query.
Filesystem Packages
Versioned packages:
Directory scan mode:
The server extracts metadata from:
- plugin headers in a top-level PHP file
- theme headers in
style.css - WordPress.org-style
readme.txtsections
Global package metadata overrides extracted metadata. Per-version metadata overrides both.
Single-file packages still work as a convenience, but versioned packages are recommended for production.
GitHub Releases Packages
Public release asset:
Asset selected by pattern:
Private release asset:
GitHub release sources use GITHUB_TOKEN automatically when it is set in the server environment:
Use tokenEnv only when the token lives in a differently named environment variable.
Release list metadata is cached in storage/cache/github-release-list by default. Single release metadata is cached in storage/cache/github-release-metadata. Downloaded assets are cached in storage/cache/github-assets by slug, version, asset name, and asset identity. GitHub ZIP assets are written to temporary files first, validated as ZIP archives, and then renamed into place.
Version tags such as v1.2.3 and 1.2.3 normalize to the same package version.
Version Selection
Package identity is always the slug. Versions are available artifacts for that slug.
The metadata endpoint chooses a version using:
installed_version: if present, select the highest available version greater than the installed version.channel: defaults tostable.wp_version: optional query value. If omitted, the server attempts to read the WordPress version from the requestUser-Agent.php_version: optional query value for filtering releases byrequires_php.version_compare(): used for sorting WordPress/PHP-style versions.- compatibility metadata: candidates with
requiresorrequires_phpgreater than the client environment are skipped when that environment is known.
Examples:
If no newer compatible version is available, the server returns a clean no-update response without download_url:
Stable excludes prerelease versions by default. Channels can be configured per package:
Supported prerelease forms include 1.2.3-alpha, 1.2.3-alpha.1, 1.2.3-beta, 1.2.3-beta.2, 1.2.3-rc, and 1.2.3-rc.3.
Metadata Overrides
Each package or version can override extracted metadata:
Assets
Package icons and banners can be placed in:
The server includes matching asset URLs in metadata responses.
Signed Downloads
Enable signed download URLs by configuring config/server.php and the corresponding environment variables. You can toggle signing with the WP_UPDATE_SERVER_SIGN_DOWNLOADS env var and provide the secret via WP_UPDATE_SERVER_SECRET.
Example environment configuration:
The downloadSignatureTtl setting in config/server.php controls the signature lifetime (seconds). Signed URLs include slug, version, expires, and signature query parameters. The server validates the HMAC before streaming a ZIP, and a signature for one version cannot download another version.
If signDownloads is enabled without a configured secret, the server fails closed during startup/config validation instead of serving unsigned downloads.
Authorization
The default authorization provider allows all metadata and downloads. The architecture includes AuthorizationProviderInterface, so license checks, API keys, or custom customer rules can be added later without changing package source code.
Unauthorized metadata responses can omit download_url or block metadata entirely depending on the provider implementation.
Rate Limiting
Downloads use a simple IP-based throttle by default:
The limiter is replaceable through RateLimiterInterface.
When the server runs behind a reverse proxy, forwarded client IP headers are ignored unless the proxy address is explicitly trusted:
Use WP_UPDATE_SERVER_TRUSTED_PROXIES and WP_UPDATE_SERVER_TRUSTED_PROXY_HEADERS as comma-separated environment variables if you use the default config/server.php.
Logging
Runtime events are written as newline-delimited JSON in storage/logs/ by default. Logs rotate by UTC date and size:
The default maximum log file size is 10 MB. Override it with logMaxBytes or WP_UPDATE_SERVER_LOG_MAX_BYTES.
CLI
Use a custom aggregate config path:
Client Integration
The first-party WordPress client for this server is webshr/wp-update-sdk. Use it in your plugins or themes when you want the Webshr update flow, including support for this server's metadata, signed downloads, and licensing conventions.
Install and usage details live in the SDK repository:
The metadata endpoint you pass to client integrations is:
Plugin Update Checker Compatibility
The server also exposes WordPress-compatible metadata that can be consumed by Yahnis Elsts' Plugin Update Checker.
Theme Compatibility
Plugin Update Checker also supports themes:
Deployment Notes
Apache should point the document root at public/. If serving from the project root is unavoidable, keep the .htaccess protections from stubs/config/, stubs/storage/, and other private directories.
Nginx should route requests to public/index.php and deny direct access to:
Security Notes
- Never commit
WP_UPDATE_SERVER_SECRETorGITHUB_TOKEN. - Prefer signed download URLs for private or paid packages.
- Keep
storage/cache/,storage/logs/, and rawstorage/packages/non-public. - GitHub private assets are downloaded server-side and cached locally.
- Configure
trustedProxiesbefore relying onX-Forwarded-For,X-Real-IP, or CDN client IP headers. - Validate package ZIPs before publishing.
- Tune download rate limits for your traffic.
Development Checks
Run:
composer lint runs PHPCS with the project PSR-12 ruleset. composer analyse runs PHPStan. composer check runs linting, static analysis, and tests in the same sequence used by CI.
The current test suite covers config loading and validation, download signing, trusted proxy IP handling, log rotation, plugin/theme ZIP validation, metadata extraction, filesystem version config, filesystem directory scanning, GitHub release version discovery and asset caching, prerelease channel selection, versioned download URLs, and the path-based metadata endpoint.
All versions of wp-update-server with dependencies
ext-zip Version *
erusev/parsedown Version ^1.8
vlucas/phpdotenv Version ^5.6
php Version >=8.2