0083: PHP previews from verified pre-releases

On this page

Status: accepted

Context

Trying an app on the next PHP before it's released catches breakage early, but PHP's pre-releases (alpha, beta and RC) aren't where its releases are. The tarballs live in each release manager's folder on downloads.php.net, listed with their SHA-256 in php.net's pre-release-builds.php?format=json; static-php.dev has no builds of them. On Windows, windows.php.net publishes them as QA builds, in their own downloads/qa/releases.json with a SHA-256 for each zip. Extensions lag behind a new minor: many PECL extensions don't compile against it yet, and Xdebug supports it only once it's close to release. A preview also mustn't land on a site by accident, through Make default or a composer.json constraint such as ^8.2.

Decision

  • Which versions. runtimes::php::PREVIEW lists the minors offered as previews (8.6 today). SUPPORTED stays released versions only: only those can be the default, be suggested, or be picked from composer.json while one fits. ALL_MINORS is PREVIEW then SUPPORTED, and installing, listing and updating use it.
  • Never the default, pinnable per site. Make default and set_php_default refuse a preview, and the tray leaves previews out of its default picker. A site gets a preview only when it's pinned to it on its Site settings (the picker says "8.6 (preview)"), or when its require.php fits no installed released version but fits the preview.
  • macOS: Short Leash's own build. ShortLeash/runtimes builds the newest php.net pre-release of each minor in its workflow's PHP_PREVIEW_MINORS. Its plan reads php.net's pre-release list, takes only a .tar.xz on https://downloads.php.net/ named for that version, and the build checks the tarball against the SHA-256 the list publishes before static-php-cli sees it. The release is a GitHub pre-release tagged like php-8.6.0RC3, attested and published in the signed manifest like Short Leash's other builds (0017, 0019), filed under php/8.6.0RC3/.
  • Windows: windows.php.net's QA builds. When a PREVIEW minor isn't in the stable releases.json, Short Leash fetches downloads/qa/releases.json once, takes only the PREVIEW minors from it (not the RCs of released minors it also lists), and checks the zip against its SHA-256. The compiler is picked by number, so 8.6's vs18 build is taken.
  • Naming. Versions keep php.net's names (8.6.0RC3, 8.6.0beta1). runtimes::updates::version_key sorts alpha before beta before RC before the release, so a newer RC replaces the installed one as an update, and so does the release.
  • No Xdebug for a preview. Its Xdebug switch is disabled ("Not available for previews yet"), set_xdebug(.., true) refuses one before anything is downloaded, and a site's extension check never tells you to turn Xdebug on for it.
  • Extensions it lacks. Extensions that don't build against the preview yet go in ShortLeash/runtimes' scripts/php-extensions-preview-skip.txt, each with a reason; runtimes::php::PREVIEW_MISSING_EXTENSIONS mirrors it, so Short Leash never offers them for a preview on macOS. For 8.6.0RC3 that's 14: apcu, ev, event, excimer, grpc, igbinary, imagick, memcached, msgpack, pcov, pdo_sqlsrv, redis, sqlsrv and swoole. On Windows a preview has what windows.php.net's zip holds, and Short Leash adds no extension DLLs for it.
  • When the release ships. A Short Leash release moves the minor from PREVIEW to SUPPORTED and empties the skip list (the builds skill has the steps); installed previews update to the release.

Consequences

  • People can run their app on the next PHP weeks before release, from the Runtimes screen, without building PHP or adding a package source.
  • A preview build has fewer extensions than a released one until upstream catches up, and the docs list which. Apps that need one of them, or Xdebug, wait for the release.
  • Release candidates replace each other as updates, so a site pinned to 8.6 moves from RC to RC without asking; that's what a preview is for, but an RC can break what the last one ran.
  • Windows reaches one more source, windows.php.net's QA listing, only while a preview minor is missing from the stable one. The Privacy policy says so. CLAUDE.md invariant 7 names both checks.
  • Moving a minor out of PREVIEW is a code change and a Short Leash release, not a manifest update: a release can't become the default before Short Leash knows it's released.