Skip to content

Build Linux ZTS turbo binaries for PHP 8.6+ (2.3.x) - #6658

Merged
ondrejmirtes merged 2 commits into
2.3.xfrom
turbo-linux-zts-86-23x
Oct 2, 2026
Merged

ondrejmirtes merged 2 commits into
2.3.xfrom
turbo-linux-zts-86-23x

Conversation

@ondrejmirtes

Copy link
Copy Markdown
Member

Merge of #6657 into 2.3.x, with the 2.3.x-only parts: the turbo-origins reuse keys carry the -zts suffix (otherwise a ZTS leg would reuse the NTS binary of the same target), the 8.6 ZTS binaries are tested in turbo-differential (gnu-php8.6-zts image) and turbo-differential-musl, and install-alpine-php.sh is a build input in find-turbo-origins.sh.

The official Docker images build every PHP 8.6+ variant thread-safe — cli, fpm, apache and alpine — and publish no NTS 8.6 image any more (docker-library/php#1686, merged 2026-09-29). Our NTS binaries refuse to load there:

phpstan_turbo.so: undefined symbol: executor_globals

which is what fails the 8.6 turbo-docker-run legs on 2.2.x and 2.3.x. php-src 8.6 still defaults to NTS, so distros, ppa:ondrej/php, sury, Remi, setup-php and Homebrew keep shipping NTS — 8.6+ needs both variants on Linux. 8.3–8.5 stay NTS-only.

  • new turbo-build image tag gnu-php8.6-zts (build-php.sh with PHP_ZTS=1; the tarball pin moved into the script so the glibc image and the musl legs build the same release)
  • 8.6 ZTS compile legs for linux-gnu-x86_64, linux-gnu-arm64, linux-musl-x86_64 and linux-musl-arm64; Alpine packages no thread-safe PHP, so the musl legs build the tarball in alpine:3.24 (.github/scripts/install-alpine-php.sh, shared by all musl legs)
  • turbo-docker-run loads the -zts binaries into the 8.6 images and gains a php:8.6-rc-cli-alpine leg
  • TURBO_RETIRED_BINARIES narrowed to the 8.3–8.5 Linux ZTS binaries (the old glob would have deleted the new 8.6 ones from the dist)

Verified locally (arm64): both ZTS builds pass all differential tests, and with the extension loaded the full suite (21858 tests), make phpstan and the token-id probe are green inside the real php:8.6-rc-cli-bookworm and php:8.6-rc-cli-alpine images.

Note: gnu-php8.6-zts is published by a workflow_dispatch of turbo-build-image.yml on this branch (image PRs don't publish).

🤖 Generated with Claude Code

https://claude.ai/code/session_01LcypAP4x58BCa8dzQm5UHQ

ondrejmirtes and others added 2 commits October 2, 2026 14:59
The official Docker images build every PHP 8.6+ variant thread-safe, cli
and alpine included (docker-library/php#1686), and no NTS 8.6 image is
published any more. The NTS binaries refuse to load there ("undefined
symbol: executor_globals"), which failed the 8.6 turbo-docker-run legs.
Distros, ppa:ondrej/php, sury, Remi and setup-php keep shipping an NTS CLI
(php-src 8.6 still defaults to NTS), so 8.6+ needs both variants.

- turbo-build image gnu-php8.6-zts: build-php.sh builds the pinned
  tarball thread-safe when PHP_ZTS=1; the pin moved into the script so
  the glibc image and the musl legs build the same release
- turbo-compile gains linux-gnu-x86_64/arm64 and linux-musl-x86_64 8.6
  ZTS legs, turbo-compile-musl-arm64 a linux-musl-arm64 one; Alpine
  packages no thread-safe PHP, so those build the tarball in alpine:3.24
  (.github/scripts/install-alpine-php.sh, shared by the musl legs)
- turbo-docker-run loads the -zts binaries into the 8.6 images and gains
  a php:8.6-rc-cli-alpine leg for the musl one
- TURBO_RETIRED_BINARIES only retires the 8.3-8.5 Linux ZTS binaries

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LcypAP4x58BCa8dzQm5UHQ
Ports the 8.6 ZTS legs onto 2.3.x's compile jobs, which reuse binaries
from earlier runs: the reuse lookups key each leg by its artifact name,
so they carry the -zts suffix too — otherwise a ZTS leg would take over
the NTS binary of the same target. The binaries are tested in
turbo-differential (gnu, in the gnu-php8.6-zts image) and
turbo-differential-musl (in alpine:3.24 with the same thread-safe PHP the
compile legs build), and install-alpine-php.sh counts as a build input in
find-turbo-origins.sh.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LcypAP4x58BCa8dzQm5UHQ
# or compiled, run in the turbo-differential jobs, so the commit job,
# which needs the binaries, does not wait for them.
runs-on: ${{ fromJSON(needs.turbo-origins.outputs.origins || '{}')[format('{0}-{1}-php{2}', matrix.target.artifact, matrix.target.name, matrix.php-version)] && 'ubuntu-latest' || matrix.target.runs-on }}
runs-on: ${{ fromJSON(needs.turbo-origins.outputs.origins || '{}')[format('{0}-{1}-php{2}{3}', matrix.target.artifact, matrix.target.name, matrix.php-version, matrix.target.suffix || '')] && 'ubuntu-latest' || matrix.target.runs-on }}
# prerelease tarball (see the Dockerfile); the musl ZTS legs build the
# same tarball in alpine:3.24, since Alpine packages no thread-safe PHP.
# Alpine's NTS php86 packages are currently only in edge/testing.
container: ${{ !(fromJSON(needs.turbo-origins.outputs.origins || '{}')[format('{0}-{1}-php{2}{3}', matrix.target.artifact, matrix.target.name, matrix.php-version, matrix.target.suffix || '')]) && (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) || '' }}
ORIGIN_RUN_ID: ${{ fromJSON(needs.turbo-origins.outputs.origins || '{}')[format('{0}-{1}-php{2}', matrix.target.artifact, matrix.target.name, matrix.php-version)] }}
PHP_ZTS: ${{ matrix.target.suffix == '-zts' && '1' || '0' }}
TURBO_ARTIFACT: "${{ matrix.target.artifact }}-${{ matrix.target.name }}-php${{ matrix.php-version }}${{ matrix.target.suffix }}"
ORIGIN_RUN_ID: ${{ fromJSON(needs.turbo-origins.outputs.origins || '{}')[format('{0}-{1}-php{2}{3}', matrix.target.artifact, matrix.target.name, matrix.php-version, matrix.target.suffix || '')] }}
# the musl legs of turbo-compile one for one, including the reuse of a
# binary compiled in an earlier run, whose leg runs on ubuntu-latest.
runs-on: ${{ fromJSON(needs.turbo-origins.outputs.origins || '{}')[format('phpstan_turbo-linux-musl-arm64-php{0}', matrix.php-version)] && 'ubuntu-latest' || 'ubuntu-24.04-arm' }}
runs-on: ${{ fromJSON(needs.turbo-origins.outputs.origins || '{}')[format('phpstan_turbo-linux-musl-arm64-php{0}{1}', matrix.php-version, matrix.ts == 'zts' && '-zts' || '')] && 'ubuntu-latest' || 'ubuntu-24.04-arm' }}
ORIGIN_RUN_ID: ${{ fromJSON(needs.turbo-origins.outputs.origins || '{}')[format('phpstan_turbo-linux-musl-arm64-php{0}', matrix.php-version)] }}
PHP_ZTS: ${{ matrix.ts == 'zts' && '1' || '0' }}
TURBO_ARTIFACT: "phpstan_turbo-linux-musl-arm64-php${{ matrix.php-version }}${{ matrix.ts == 'zts' && '-zts' || '' }}"
ORIGIN_RUN_ID: ${{ fromJSON(needs.turbo-origins.outputs.origins || '{}')[format('phpstan_turbo-linux-musl-arm64-php{0}{1}', matrix.php-version, matrix.ts == 'zts' && '-zts' || '')] }}
# or compiled, run in the turbo-differential jobs, so the commit job,
# which needs the binaries, does not wait for them.
runs-on: ${{ fromJSON(needs.turbo-origins.outputs.origins || '{}')[format('{0}-{1}-php{2}', matrix.target.artifact, matrix.target.name, matrix.php-version)] && 'ubuntu-latest' || matrix.target.runs-on }}
runs-on: ${{ fromJSON(needs.turbo-origins.outputs.origins || '{}')[format('{0}-{1}-php{2}{3}', matrix.target.artifact, matrix.target.name, matrix.php-version, matrix.target.suffix || '')] && 'ubuntu-latest' || matrix.target.runs-on }}
# the musl legs of turbo-compile one for one, including the reuse of a
# binary compiled in an earlier run, whose leg runs on ubuntu-latest.
runs-on: ${{ fromJSON(needs.turbo-origins.outputs.origins || '{}')[format('phpstan_turbo-linux-musl-arm64-php{0}', matrix.php-version)] && 'ubuntu-latest' || 'ubuntu-24.04-arm' }}
runs-on: ${{ fromJSON(needs.turbo-origins.outputs.origins || '{}')[format('phpstan_turbo-linux-musl-arm64-php{0}{1}', matrix.php-version, matrix.ts == 'zts' && '-zts' || '')] && 'ubuntu-latest' || 'ubuntu-24.04-arm' }}
@ondrejmirtes
ondrejmirtes merged commit 6984f7c into 2.3.x Oct 2, 2026
968 of 994 checks passed
@ondrejmirtes
ondrejmirtes deleted the turbo-linux-zts-86-23x branch October 2, 2026 15:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants