Skip to content

Commit 9bd33f6

Browse files
ondrejmirtesclaude
andcommitted
Build Linux ZTS turbo binaries for PHP 8.3-8.5 too
Thread-safe PHP on Linux before 8.6 got no binary since the Linux ZTS legs were retired: the php:*-zts Docker images (the base of FrankenPHP) and the musl variants never had one. With the shared core a ZTS leg only compiles the per-version shim, so every Linux target now builds both variants for every minor. - build-php.sh builds the newest release of the minor, resolved from php.net at build time (the releases API, or the pre-release one for a minor without a stable release yet, like 8.6) and verified against the published sha256, instead of a pinned tarball, so the weekly image rebuild and the musl legs follow new patch releases and release candidates on their own; turbo-build-image.yml publishes gnu-php8.3-zts, gnu-php8.4-zts and gnu-php8.5-zts - turbo-compile and turbo-compile-musl-arm64 gain a ts dimension instead of 8.6-only include entries; macOS stays NTS-only - turbo-differential runs the gnu ZTS legs in their build image, turbo-differential-musl every musl ZTS leg - turbo-docker-run loads the 8.5 ZTS binaries into php:8.5-zts-bookworm and php:8.5-zts-alpine - TURBO_RETIRED_BINARIES is empty again Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LSeeJXEA18Ma6X4qyx1xMx
1 parent fe2440a commit 9bd33f6

6 files changed

Lines changed: 148 additions & 103 deletions

File tree

‎.github/scripts/install-alpine-php.sh‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ set -eu
99
apk add --no-cache bash curl git make g++ musl-dev linux-headers patch tar zstd
1010

1111
if [ "${PHP_ZTS:-0}" = "1" ]; then
12-
apk add --no-cache pkgconf xz libxml2-dev oniguruma-dev curl-dev openssl-dev zlib-dev
12+
apk add --no-cache jq pkgconf xz libxml2-dev oniguruma-dev curl-dev openssl-dev zlib-dev
1313
PHP_MINOR="$PHP_MINOR" PHP_ZTS=1 sh "$(dirname "$0")/../turbo-build/build-php.sh"
1414
exit 0
1515
fi

‎.github/turbo-build/Dockerfile‎

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Prebuilt image for the turbo-compile gnu legs in phar.yml, published to
22
# ghcr.io/phpstan/turbo-build by turbo-build-image.yml (tags gnu-php8.3,
3-
# gnu-php8.4, gnu-php8.5, gnu-php8.6, gnu-php8.6-zts; each a linux/amd64 +
4-
# linux/arm64 manifest).
3+
# gnu-php8.4, gnu-php8.5, gnu-php8.6 and the thread-safe gnu-php8.3-zts to
4+
# gnu-php8.6-zts; each a linux/amd64 + linux/arm64 manifest).
55
#
66
# Baking the PHP toolchain in keeps apt and the ondrej/php PPA out of the
77
# compile jobs entirely: ports.ubuntu.com (the only Ubuntu arm64 mirror,
@@ -18,8 +18,9 @@ ARG PHP_MINOR
1818
ARG PHP_ZTS=0
1919
ENV DEBIAN_FRONTEND=noninteractive
2020

21-
# These images build PHP from the official release tarball pinned in
22-
# build-php.sh instead of installing it from ondrej/php:
21+
# These images build PHP from the newest official tarball of the minor
22+
# (build-php.sh resolves it from php.net) instead of installing it from
23+
# ondrej/php:
2324
# - PHP 8.6 is a prerelease, and ondrej/php trails its tags by weeks: on
2425
# 2026-09-25 it still served 8.6.0beta3, whose module API (20250926) the
2526
# 8.6.0RC2 that the php:8.6-rc images ship had already replaced
@@ -50,7 +51,7 @@ RUN test -n "$PHP_MINOR"; \
5051
}; \
5152
apt_install software-properties-common gnupg ca-certificates curl git make g++ patch unzip zstd \
5253
&& if [ "$PHP_MINOR" = "8.6" ] || [ "$PHP_ZTS" = "1" ]; then \
53-
apt_install pkg-config xz-utils libxml2-dev libonig-dev libcurl4-openssl-dev libssl-dev zlib1g-dev \
54+
apt_install jq pkg-config xz-utils libxml2-dev libonig-dev libcurl4-openssl-dev libssl-dev zlib1g-dev \
5455
&& PHP_MINOR="$PHP_MINOR" PHP_ZTS="$PHP_ZTS" sh /tmp/build-php.sh; \
5556
else \
5657
add-apt-repository -y ppa:ondrej/php \

‎.github/turbo-build/build-php.sh‎

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/bin/sh
2-
# Builds and installs PHP $PHP_MINOR into /usr/local from the official
3-
# release tarball pinned below, thread-safe when $PHP_ZTS is 1. Used by the
2+
# Builds and installs the newest release of PHP $PHP_MINOR into /usr/local
3+
# from the official tarball, thread-safe when $PHP_ZTS is 1. Used by the
44
# Dockerfile for the PHP builds ondrej/php does not ship (prerelease
55
# minors, and every thread-safe build), and by the musl ZTS legs in
66
# phar.yml, which run it in Alpine — Alpine packages no thread-safe PHP.
@@ -11,19 +11,39 @@
1111
# and curl, mbstring, openssl, xml and zlib for Composer.
1212
set -eu
1313

14-
# The tarball for each minor this script builds; one pin shared by the
15-
# glibc image and the musl legs, so both build the same release.
16-
case "$PHP_MINOR" in
17-
8.6)
18-
PHP_VERSION=8.6.0RC2
19-
PHP_URL=https://downloads.php.net/~mbeccati/php-8.6.0RC2.tar.xz
20-
PHP_SHA256=ef3fba21c311e9bbace0e2102702446d322c275b8a10e6b33b28f2561299671c
21-
;;
14+
# The release is resolved from php.net at build time, so the weekly image
15+
# rebuild and every musl leg pick up a new patch release (or the next
16+
# release candidate of a prerelease minor) without a change here: an
17+
# extension built against one patch release loads into every other of the
18+
# minor. The sha256 published next to the tarball guards the download. A
19+
# minor without a stable release yet is not in the releases API; its
20+
# current release candidate is in the pre-release one, under <minor>.0.
21+
php_net() {
22+
curl -fsSL --retry 3 "$1"
23+
}
24+
RELEASE_JSON="$(php_net "https://www.php.net/releases/index.php?json&version=$PHP_MINOR")"
25+
PHP_VERSION="$(printf '%s' "$RELEASE_JSON" | jq -r '.version // empty')"
26+
if [ -n "$PHP_VERSION" ]; then
27+
PHP_URL="https://www.php.net/distributions/php-$PHP_VERSION.tar.xz"
28+
PHP_SHA256="$(printf '%s' "$RELEASE_JSON" | jq -r --arg file "php-$PHP_VERSION.tar.xz" '.source[] | select(.filename == $file) | .sha256')"
29+
else
30+
PRERELEASE_JSON="$(php_net "https://www.php.net/pre-release-builds.php?format=json" | jq --arg minor "$PHP_MINOR.0" '.[$minor].release // empty')"
31+
PHP_VERSION="$(printf '%s' "$PRERELEASE_JSON" | jq -r '.version // empty')"
32+
PHP_URL="$(printf '%s' "$PRERELEASE_JSON" | jq -r '.files.xz.path // empty')"
33+
PHP_SHA256="$(printf '%s' "$PRERELEASE_JSON" | jq -r '.files.xz.sha256 // empty')"
34+
fi
35+
case "$PHP_VERSION" in
36+
"$PHP_MINOR".*) ;;
2237
*)
23-
echo "build-php.sh: no tarball pinned for PHP $PHP_MINOR" >&2
38+
echo "build-php.sh: php.net lists no release of PHP $PHP_MINOR (resolved \"$PHP_VERSION\")" >&2
2439
exit 1
2540
;;
2641
esac
42+
if [ -z "$PHP_URL" ] || [ -z "$PHP_SHA256" ]; then
43+
echo "build-php.sh: php.net lists no tar.xz with a sha256 for PHP $PHP_VERSION" >&2
44+
exit 1
45+
fi
46+
echo "build-php.sh: building PHP $PHP_VERSION from $PHP_URL"
2747
export PHP_VERSION
2848
PHP_ZTS="${PHP_ZTS:-0}"
2949
export PHP_ZTS

0 commit comments

Comments
 (0)