Skip to content

Commit dc6b72f

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 pins the 8.3.35, 8.4.26 and 8.5.11 release tarballs (sha256 matching php.net and docker-library), and 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 dc6b72f

5 files changed

Lines changed: 131 additions & 89 deletions

File tree

‎.github/turbo-build/Dockerfile‎

Lines changed: 2 additions & 2 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,

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

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,26 @@
1212
set -eu
1313

1414
# 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.
15+
# glibc image and the musl legs, so both build the same release. The stable
16+
# minors are only built thread-safe (their NTS images come from ondrej/php);
17+
# an extension built against one patch release loads into every other of the
18+
# minor, so these pins only need a bump for a build fix, not per release.
1619
case "$PHP_MINOR" in
20+
8.3)
21+
PHP_VERSION=8.3.35
22+
PHP_URL=https://www.php.net/distributions/php-8.3.35.tar.xz
23+
PHP_SHA256=ff4630fbbbd94359134b7d3c223db59329905bdc4f5a9ef93d257b48e358619a
24+
;;
25+
8.4)
26+
PHP_VERSION=8.4.26
27+
PHP_URL=https://www.php.net/distributions/php-8.4.26.tar.xz
28+
PHP_SHA256=32a2de53862ad44ed4a5005244ce4f1b50c271e74dced215449a4443b40569f1
29+
;;
30+
8.5)
31+
PHP_VERSION=8.5.11
32+
PHP_URL=https://www.php.net/distributions/php-8.5.11.tar.xz
33+
PHP_SHA256=d9be75c08e8c316f4c8f4194d8fbe1750a15f6a6d9d4e3fe72082abeeb800360
34+
;;
1735
8.6)
1836
PHP_VERSION=8.6.0RC2
1937
PHP_URL=https://downloads.php.net/~mbeccati/php-8.6.0RC2.tar.xz

‎.github/workflows/phar.yml‎

Lines changed: 104 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@ env:
2424
# more (paths under turbo-ext/, shell globs). The commit job deletes them
2525
# from the dist; without this, the torn-set guard there would refuse every
2626
# version bump, since a retired binary has no freshly built replacement.
27-
# Linux ZTS binaries are built from PHP 8.6 on again (see turbo-compile),
28-
# so only the older minors' are retired.
29-
TURBO_RETIRED_BINARIES: "linux-gnu-x86_64/phpstan_turbo-8.[345]-zts.so linux-gnu-arm64/phpstan_turbo-8.[345]-zts.so"
27+
# None at the moment: the Linux ZTS binaries retired for 8.3-8.5 are built
28+
# again (see turbo-compile).
29+
TURBO_RETIRED_BINARIES: ""
3030
# The php-parser version whose grammar tables and semantic actions the
3131
# native parser engine (turbo-ext/src/parser/) was ported against.
3232
SUPPORTED_PHP_PARSER_VERSION: "v5.9.0"
@@ -718,21 +718,22 @@ jobs:
718718
# the same core.
719719
runs-on: ${{ matrix.target.runs-on }}
720720
# Container legs pin the binaries' userland floor independently of the
721-
# runner image, like turbo-compile-core. Linux ZTS legs (suffix -zts)
722-
# exist from PHP 8.6 on: the official Docker images build every 8.6+
723-
# variant thread-safe, cli and alpine included (docker-library/php#1686),
724-
# while distros, ppa:ondrej/php, sury, Remi and setup-php keep shipping
725-
# an NTS CLI — so 8.6+ needs both. Up to 8.5 thread-safe PHP on Linux
726-
# (FrankenPHP, php:*-zts images) is a few percent of hosts and gets no
727-
# binary; the commit job deletes those from phpstan/phpstan
728-
# (TURBO_RETIRED_BINARIES). The thread-safe extension links against the
729-
# same core: the core never touches TSRM (turbo-shared-core-gate compares
730-
# the two builds too). The gnu-php8.6 and gnu-php8.6-zts images build the
731-
# official 8.6 prerelease tarball (see the Dockerfile); the musl ZTS legs
732-
# build the same tarball in alpine:3.24, since Alpine packages no
733-
# thread-safe PHP. Alpine's NTS php86 packages are currently only in
734-
# edge/testing.
735-
container: ${{ matrix.target.family == 'gnu' && format('ghcr.io/phpstan/turbo-build:gnu-php{0}{1}', matrix.php-version, matrix.target.suffix || '') || matrix.target.family == 'musl' && matrix.php-version == '8.6' && matrix.target.suffix != '-zts' && 'alpine:edge' || matrix.target.container || '' }}
721+
# runner image, like turbo-compile-core. Every Linux target has a ZTS
722+
# leg (ts: zts, artifact suffix -zts) next to the NTS one for every
723+
# minor: distros, ppa:ondrej/php, sury, Remi and setup-php ship an NTS
724+
# CLI, while the official Docker images build every 8.6+ variant
725+
# thread-safe, cli and alpine included (docker-library/php#1686), and
726+
# their php:*-zts tags (the base of FrankenPHP) do so for older minors.
727+
# The thread-safe extension is only the per-version shim — it links
728+
# against the platform's one core, which never touches TSRM
729+
# (turbo-shared-core-gate compares the two builds too) — so a ZTS leg
730+
# compiles only those few sources. ondrej/php packages no thread-safe
731+
# PHP, so the gnu-php<minor>-zts images build the official tarball
732+
# pinned in build-php.sh (as does gnu-php8.6, a prerelease), and the
733+
# musl ZTS legs build the same tarball in alpine:3.24, since Alpine
734+
# packages no thread-safe PHP either. Alpine's NTS php86 packages are
735+
# currently only in edge/testing.
736+
container: ${{ matrix.target.family == 'gnu' && format('ghcr.io/phpstan/turbo-build:gnu-php{0}{1}', matrix.php-version, matrix.ts == 'zts' && '-zts' || '') || matrix.target.family == 'musl' && matrix.php-version == '8.6' && matrix.ts != 'zts' && 'alpine:edge' || matrix.target.container || '' }}
736737
needs: turbo-compile-core
737738
# one platform's failed core must not skip every platform's legs: a leg
738739
# whose core is missing fails at its download instead
@@ -741,13 +742,14 @@ jobs:
741742

742743
env:
743744
PHP_MINOR: ${{ matrix.php-version }}
744-
PHP_ZTS: ${{ matrix.target.suffix == '-zts' && '1' || '0' }}
745-
TURBO_ARTIFACT: "phpstan_turbo-${{ matrix.target.name }}-php${{ matrix.php-version }}${{ matrix.target.suffix }}"
745+
PHP_ZTS: ${{ matrix.ts == 'zts' && '1' || '0' }}
746+
TURBO_ARTIFACT: "phpstan_turbo-${{ matrix.target.name }}-php${{ matrix.php-version }}${{ matrix.ts == 'zts' && '-zts' || '' }}"
746747

747748
strategy:
748749
fail-fast: false
749750
matrix:
750751
php-version: ["8.3", "8.4", "8.5", "8.6"]
752+
# the musl arm64 legs are in turbo-compile-musl-arm64
751753
target:
752754
- name: "linux-gnu-x86_64"
753755
runs-on: "ubuntu-latest"
@@ -763,28 +765,15 @@ jobs:
763765
- name: "macos-arm64"
764766
runs-on: "macos-latest"
765767
family: "macos"
766-
# thread-safe builds, 8.6+ only (see above); the musl arm64 one is in
767-
# turbo-compile-musl-arm64
768-
include:
769-
- php-version: "8.6"
770-
target:
771-
name: "linux-gnu-x86_64"
772-
runs-on: "ubuntu-latest"
773-
family: "gnu"
774-
suffix: "-zts"
775-
- php-version: "8.6"
776-
target:
777-
name: "linux-gnu-arm64"
778-
runs-on: "ubuntu-24.04-arm"
779-
family: "gnu"
780-
suffix: "-zts"
781-
- php-version: "8.6"
782-
target:
783-
name: "linux-musl-x86_64"
784-
runs-on: "ubuntu-latest"
785-
container: "alpine:3.24"
786-
family: "musl"
787-
suffix: "-zts"
768+
ts: ["nts", "zts"]
769+
# Homebrew and setup-php ship an NTS PHP on macOS, and no
770+
# thread-safe distribution is common enough there to build for
771+
exclude:
772+
- target:
773+
name: "macos-arm64"
774+
runs-on: "macos-latest"
775+
family: "macos"
776+
ts: "zts"
788777

789778
steps:
790779
- name: Harden the runner (Audit all outbound calls)
@@ -899,11 +888,8 @@ jobs:
899888
fail-fast: false
900889
matrix:
901890
php-version: ["8.3", "8.4", "8.5", "8.6"]
902-
ts: ["nts"]
903-
# thread-safe from 8.6 on, see turbo-compile
904-
include:
905-
- php-version: "8.6"
906-
ts: "zts"
891+
# thread-safe for every minor too, see turbo-compile
892+
ts: ["nts", "zts"]
907893

908894
steps:
909895
- name: Harden the runner (Audit all outbound calls)
@@ -1027,14 +1013,16 @@ jobs:
10271013
# turbo-differential. The 8.6+ images are thread-safe
10281014
# (docker-library/php#1686), so those legs load the -zts binaries, and
10291015
# an Alpine leg covers the musl one — php:*-alpine is the other image
1030-
# family people run PHPStan in. No macOS/Windows legs: those runners
1016+
# family people run PHPStan in. The 8.5 php:*-zts pair (the base of
1017+
# FrankenPHP's images) does the same for the older minors' ZTS
1018+
# binaries, which are compiled against our own build of the tarball. No macOS/Windows legs: those runners
10311019
# cannot run Linux containers, and no alternative-numbered official
10321020
# build is distributed for either platform today.
10331021
runs-on: "ubuntu-latest"
10341022
timeout-minutes: 60
10351023

10361024
env:
1037-
IMAGE: ${{ matrix.php-version == '8.6' && format('phpstan-turbo-test:{0}', matrix.binary) || matrix.image }}
1025+
IMAGE: ${{ (matrix.php-version == '8.6' || contains(matrix.image, 'alpine')) && format('phpstan-turbo-test:{0}', matrix.binary) || matrix.image }}
10381026

10391027
permissions:
10401028
contents: read
@@ -1047,6 +1035,8 @@ jobs:
10471035
- "php:8.3.22-cli-bookworm"
10481036
- "php:8.4-cli-bookworm"
10491037
- "php:8.5-cli-bookworm"
1038+
- "php:8.5-zts-bookworm"
1039+
- "php:8.5-zts-alpine"
10501040
- "php:8.6-rc-cli-bookworm"
10511041
- "php:8.6-rc-cli-alpine"
10521042
check: ["tests", "phpstan"]
@@ -1063,6 +1053,12 @@ jobs:
10631053
- image: "php:8.5-cli-bookworm"
10641054
php-version: "8.5"
10651055
binary: "linux-gnu-x86_64-php8.5"
1056+
- image: "php:8.5-zts-bookworm"
1057+
php-version: "8.5"
1058+
binary: "linux-gnu-x86_64-php8.5-zts"
1059+
- image: "php:8.5-zts-alpine"
1060+
php-version: "8.5"
1061+
binary: "linux-musl-x86_64-php8.5-zts"
10661062
- image: "php:8.6-rc-cli-bookworm"
10671063
php-version: "8.6"
10681064
binary: "linux-gnu-x86_64-php8.6-zts"
@@ -1112,8 +1108,8 @@ jobs:
11121108
name: "phpstan_turbo-${{ matrix.binary }}"
11131109
path: "turbo-ext"
11141110

1115-
- name: "Add mbstring to the PHP 8.6 prerelease image"
1116-
if: matrix.php-version == '8.6'
1111+
- name: "Add mbstring, bash and make to the 8.6 prerelease and Alpine images"
1112+
if: matrix.php-version == '8.6' || contains(matrix.image, 'alpine')
11171113
env:
11181114
PHP_IMAGE: ${{ matrix.image }}
11191115
# Unlike the stable images, the 8.6 prerelease omits mbstring,
@@ -1126,14 +1122,19 @@ jobs:
11261122
ARG PHP_IMAGE
11271123
FROM ${PHP_IMAGE}
11281124
RUN if command -v apk > /dev/null; then \
1129-
apk add --no-cache bash make oniguruma \
1130-
&& apk add --no-cache --virtual .mbstring-build-deps $PHPIZE_DEPS oniguruma-dev \
1131-
&& docker-php-ext-install mbstring \
1132-
&& apk del .mbstring-build-deps; \
1133-
else \
1134-
apt-get update && apt-get install -y --no-install-recommends libonig-dev \
1135-
&& docker-php-ext-install mbstring \
1136-
&& rm -rf /var/lib/apt/lists/*; \
1125+
apk add --no-cache bash make; \
1126+
fi \
1127+
&& if ! php -m | grep -qx mbstring; then \
1128+
if command -v apk > /dev/null; then \
1129+
apk add --no-cache oniguruma \
1130+
&& apk add --no-cache --virtual .mbstring-build-deps $PHPIZE_DEPS oniguruma-dev \
1131+
&& docker-php-ext-install mbstring \
1132+
&& apk del .mbstring-build-deps; \
1133+
else \
1134+
apt-get update && apt-get install -y --no-install-recommends libonig-dev \
1135+
&& docker-php-ext-install mbstring \
1136+
&& rm -rf /var/lib/apt/lists/*; \
1137+
fi; \
11371138
fi
11381139
DOCKERFILE
11391140
@@ -1493,9 +1494,11 @@ jobs:
14931494
# binary is built for. Kept out of the compile jobs so the commit job,
14941495
# which only needs the binaries, does not wait for them (see there).
14951496
# The musl binaries are tested in turbo-differential-musl. The linux-gnu
1496-
# 8.6 legs run in the image the binary is compiled in instead: setup-php's
1497-
# Linux 8.6 is a nightly snapshot that can predate the release the binary
1498-
# targets, and a module API mismatch refuses to load it at all.
1497+
# 8.6 and ZTS legs run in the image the binary is compiled in instead:
1498+
# setup-php's Linux 8.6 is a nightly snapshot that can predate the
1499+
# release the binary targets, and a module API mismatch refuses to load
1500+
# it at all; the ZTS legs so as not to depend on setup-php's thread-safe
1501+
# Linux builds.
14991502
needs:
15001503
- turbo-compile
15011504
- turbo-compile-windows
@@ -1516,13 +1519,8 @@ jobs:
15161519
php-version: ["8.3", "8.4", "8.5", "8.6"]
15171520
target: ["linux-gnu-x86_64", "linux-gnu-arm64", "macos-arm64", "windows-x86_64"]
15181521
ts: ["nts", "zts"]
1519-
# Windows ships ZTS binaries for every minor, Linux from 8.6 on —
1520-
# added by the include entries below (see turbo-compile)
1522+
# macOS ships no ZTS binary (see turbo-compile)
15211523
exclude:
1522-
- target: "linux-gnu-x86_64"
1523-
ts: "zts"
1524-
- target: "linux-gnu-arm64"
1525-
ts: "zts"
15261524
- target: "macos-arm64"
15271525
ts: "zts"
15281526
include:
@@ -1537,10 +1535,44 @@ jobs:
15371535
runs-on: "windows-latest"
15381536
- target: "linux-gnu-x86_64"
15391537
php-version: "8.6"
1538+
ts: "nts"
15401539
container: "ghcr.io/phpstan/turbo-build:gnu-php8.6"
15411540
- target: "linux-gnu-arm64"
15421541
php-version: "8.6"
1542+
ts: "nts"
15431543
container: "ghcr.io/phpstan/turbo-build:gnu-php8.6"
1544+
# the linux-gnu ZTS legs, in the image the binary is compiled in
1545+
# (see above); the official php:*-zts images get turbo-docker-run
1546+
- target: "linux-gnu-x86_64"
1547+
php-version: "8.3"
1548+
ts: "zts"
1549+
runs-on: "ubuntu-latest"
1550+
container: "ghcr.io/phpstan/turbo-build:gnu-php8.3-zts"
1551+
- target: "linux-gnu-arm64"
1552+
php-version: "8.3"
1553+
ts: "zts"
1554+
runs-on: "ubuntu-24.04-arm"
1555+
container: "ghcr.io/phpstan/turbo-build:gnu-php8.3-zts"
1556+
- target: "linux-gnu-x86_64"
1557+
php-version: "8.4"
1558+
ts: "zts"
1559+
runs-on: "ubuntu-latest"
1560+
container: "ghcr.io/phpstan/turbo-build:gnu-php8.4-zts"
1561+
- target: "linux-gnu-arm64"
1562+
php-version: "8.4"
1563+
ts: "zts"
1564+
runs-on: "ubuntu-24.04-arm"
1565+
container: "ghcr.io/phpstan/turbo-build:gnu-php8.4-zts"
1566+
- target: "linux-gnu-x86_64"
1567+
php-version: "8.5"
1568+
ts: "zts"
1569+
runs-on: "ubuntu-latest"
1570+
container: "ghcr.io/phpstan/turbo-build:gnu-php8.5-zts"
1571+
- target: "linux-gnu-arm64"
1572+
php-version: "8.5"
1573+
ts: "zts"
1574+
runs-on: "ubuntu-24.04-arm"
1575+
container: "ghcr.io/phpstan/turbo-build:gnu-php8.5-zts"
15441576
- target: "linux-gnu-x86_64"
15451577
php-version: "8.6"
15461578
ts: "zts"
@@ -1677,15 +1709,8 @@ jobs:
16771709
matrix:
16781710
arch: ["x86_64", "arm64"]
16791711
php-version: ["8.3", "8.4", "8.5", "8.6"]
1680-
ts: ["nts"]
1681-
# thread-safe from 8.6 on, see turbo-compile
1682-
include:
1683-
- arch: "x86_64"
1684-
php-version: "8.6"
1685-
ts: "zts"
1686-
- arch: "arm64"
1687-
php-version: "8.6"
1688-
ts: "zts"
1712+
# thread-safe for every minor too, see turbo-compile
1713+
ts: ["nts", "zts"]
16891714

16901715
steps:
16911716
- name: Harden the runner (Audit all outbound calls)
@@ -1784,9 +1809,8 @@ jobs:
17841809
php-version: ["8.3", "8.4", "8.5", "8.6"]
17851810
ts: ["nts", "zts"]
17861811
script: ["make tests", "make phpstan"]
1787-
# Linux ships ZTS binaries only from 8.6 on (see turbo-compile), and
1788-
# the ubuntu 8.6 legs are excluded below — turbo-docker-run runs the
1789-
# 8.6 ZTS binaries in the official, thread-safe 8.6 images instead.
1812+
# The Linux ZTS binaries run the same checks in turbo-docker-run, in
1813+
# the official thread-safe images, instead of under setup-php.
17901814
exclude:
17911815
- operating-system: "ubuntu-latest"
17921816
ts: "zts"

‎.github/workflows/turbo-build-image.yml‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ name: "Build Turbo compile images"
44

55
# Builds .github/turbo-build/Dockerfile natively on x86_64 and arm64
66
# runners and publishes ghcr.io/phpstan/turbo-build:gnu-php{8.3,8.4,8.5,8.6}
7-
# and the thread-safe gnu-php8.6-zts as multi-arch manifests. The
7+
# and the thread-safe gnu-php{8.3,8.4,8.5,8.6}-zts as multi-arch manifests. The
88
# turbo-compile gnu legs in phar.yml run in these images, so their only
99
# network dependency is a GHCR pull — no apt, no ports.ubuntu.com, no PPA at
1010
# compile time.
@@ -47,7 +47,7 @@ jobs:
4747
fail-fast: false
4848
matrix:
4949
# <minor>[-zts]; a -zts tag builds a thread-safe PHP of that minor
50-
tag: ["8.3", "8.4", "8.5", "8.6", "8.6-zts"]
50+
tag: ["8.3", "8.4", "8.5", "8.6", "8.3-zts", "8.4-zts", "8.5-zts", "8.6-zts"]
5151
platform:
5252
- arch: "amd64"
5353
runs-on: "ubuntu-latest"
@@ -106,7 +106,7 @@ jobs:
106106

107107
strategy:
108108
matrix:
109-
tag: ["8.3", "8.4", "8.5", "8.6", "8.6-zts"]
109+
tag: ["8.3", "8.4", "8.5", "8.6", "8.3-zts", "8.4-zts", "8.5-zts", "8.6-zts"]
110110

111111
env:
112112
TAG: "ghcr.io/phpstan/turbo-build:gnu-php${{ matrix.tag }}"

‎src/Turbo/TurboExtensionSelector.php‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@
3434
* instead. Only non-debug builds for PHP >= MINIMUM_PHP_VERSION_ID are
3535
* shipped; a ZTS variant (-zts filename
3636
* suffix) exists for Windows, where XAMPP, WampServer and Scoop default
37-
* to thread-safe PHP, and for Linux from PHP 8.6 on, where the official
38-
* Docker images are thread-safe — a thread-safe PHP on macOS, or on Linux
39-
* before 8.6, finds no binary and runs without the extension. Workers run the regular
37+
* to thread-safe PHP, and for Linux, where the official Docker images are
38+
* thread-safe from 8.6 on (and the php:*-zts ones before) — a thread-safe
39+
* PHP on macOS finds no binary and runs without the extension. Workers run the regular
4040
* entrypoint, so TurboExtensionEnabler still gates activation on the
4141
* expected extension version.
4242
*

0 commit comments

Comments
 (0)