Build Linux ZTS turbo binaries for PHP 8.6+ (2.3.x) - #6658
Merged
Merged
Conversation
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' }} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Merge of #6657 into 2.3.x, with the 2.3.x-only parts: the turbo-origins reuse keys carry the
-ztssuffix (otherwise a ZTS leg would reuse the NTS binary of the same target), the 8.6 ZTS binaries are tested inturbo-differential(gnu-php8.6-zts image) andturbo-differential-musl, andinstall-alpine-php.shis a build input infind-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:
which is what fails the 8.6
turbo-docker-runlegs 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.gnu-php8.6-zts(build-php.shwithPHP_ZTS=1; the tarball pin moved into the script so the glibc image and the musl legs build the same release).github/scripts/install-alpine-php.sh, shared by all musl legs)turbo-docker-runloads the-ztsbinaries into the 8.6 images and gains aphp:8.6-rc-cli-alpinelegTURBO_RETIRED_BINARIESnarrowed 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 phpstanand the token-id probe are green inside the realphp:8.6-rc-cli-bookwormandphp:8.6-rc-cli-alpineimages.Note:
gnu-php8.6-ztsis 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