Skip to content

Use the runner's preinstalled PHP to run static-php-cli on macOS - #4889

Merged
wojtekn merged 2 commits into
trunkfrom
fix-macos-intel-php-setup
Sep 18, 2026
Merged

wojtekn merged 2 commits into
trunkfrom
fix-macos-intel-php-setup

Conversation

@wojtekn

@wojtekn wojtekn commented Sep 18, 2026 •

Copy link
Copy Markdown
Contributor

Related issues

How AI was used in this PR

Claude Code investigated the failing macos-x86_64 builds, identified the root cause, and wrote the change. I reviewed the diff and test-dispatched the workflow from this branch.

Proposed Changes

Every PHP CLI binary rebuild has been failing on macos-x86_64 for weeks, which blocks all PHP binary releases: publish-apps-cdn needs all five targets to succeed, so one broken target means nothing ever reaches the CDN. The last four dispatches all failed on this target alone, while the other four passed.

The cause is upstream. The Setup PHP for static-php-cli step uses shivammathur/setup-php, which installs PHP from the shivammathur/php Homebrew tap. That tap's php@8.4 formula no longer publishes x86_64 macOS bottles — it ships arm64_golden_gate, arm64_tahoe, arm64_sequoia, arm64_sonoma, arm64_linux and x86_64_linux, with no Intel macOS entry. With no bottle available, brew falls back to compiling PHP from source on macos-15-intel, which runs past the time budget and dies after ~26–31 minutes. The action discards the underlying output (add_php ... >/dev/null 2>&1), so all anyone saw was a long silence followed by ✗ Could not setup PHP 8.4 — which reads like a transient network problem and invites a pointless retry. It's deterministic, not flaky.

The host PHP here is disposable: it exists only to run Composer and the spc tool, and has nothing to do with the PHP being built for Studio. static-php-cli needs php >= 8.3 with mbstring and zlib.

The two macOS runner images differ in a way that matters, so they're now handled separately:

  • macos-15-intel preinstalls PHP 8.5.9 and Composer 2.10.2, and is the image where the tap is broken. It now uses that preinstalled toolchain and verifies the version and extensions up front, so a future image change fails immediately with a clear message instead of silently burning half an hour.
  • macos-15 (arm64) preinstalls no PHP or Composer at all, and the tap resolves an arm64 bottle for it quickly. It keeps using the action.

The action's extension list is also trimmed to what SPC actually requires; curl and openssl were never needed.

Testing Instructions

The real test is a green build on both macOS targets. Dispatch Build PHP CLI Binaries from this branch with apps_cdn_visibility: none (builds everything, skips the upload):

gh workflow run build-php-cli-binaries.yml --ref fix-macos-intel-php-setup \
  -f php_version=8.4.25 -f package_version=studio-2 \
  -f xdebug_version=3.5.3 -f apps_cdn_visibility=none

Expect all five targets to succeed. On macos-x86_64, Verify preinstalled PHP for static-php-cli should finish in seconds and print the php -v / composer --version it will use, instead of hanging. On macos-aarch64, Setup PHP for static-php-cli should behave as before.

Pre-merge Checklist

  • Have you checked for TypeScript, React or other console errors?

🤖 Generated with Claude Code

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@wojtekn
wojtekn requested a review from a team as a code owner September 18, 2026 13:16
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@wojtekn
wojtekn merged commit ba5fd4f into trunk Sep 18, 2026
21 of 27 checks passed
@wojtekn
wojtekn deleted the fix-macos-intel-php-setup branch September 18, 2026 14:02
wojtekn added a commit that referenced this pull request Sep 18, 2026
## Related issues

- Follow-up to #4889
- Unblocks the SOAP binary rebuild for #4888

## How AI was used in this PR

Claude Code diagnosed the failure and wrote the fix. I reviewed the
diff.

## Proposed Changes

The `Verify preinstalled PHP for static-php-cli` step added in #4889
fails on `macos-x86_64` with:

```
Required PHP extension missing: mbstring.
```

That message is wrong — mbstring is present on the runner image. The
check itself was broken.

`php -m | grep -qix mbstring` lets grep exit the moment it matches,
which closes the pipe while `php -m` is still writing. PHP is killed by
SIGPIPE and exits 255. Because the step runs under `set -o pipefail`,
the pipeline inherits that failure even though grep succeeded.
Reproduced locally on a PHP that definitely has mbstring:

```
PIPESTATUS=255 0    # php killed by SIGPIPE, grep matched fine
```

It tripped on `mbstring` and not `zlib` purely because of ordering:
mbstring appears near the top of `php -m` and zlib near the bottom, so
only the mbstring match leaves enough unwritten output to trigger
SIGPIPE. That asymmetry is what made it read like a genuine
missing-extension result.

The module list is now captured once and matched against in the loop, so
nothing is piped out of `php` and there is no early-closed pipe.

## Testing Instructions

Verified locally by extracting the step from the workflow and running it
under the same shell GitHub uses (`/bin/bash --noprofile --norc -e -o
pipefail`):

- with the real `mbstring zlib` list → exits 0 and prints `php -v` /
`composer --version`
- with a bogus extension name → still exits 1 with `Required PHP
extension missing: …`, so the check hasn't been defanged

End to end, dispatch **Build PHP CLI Binaries** from this branch with
`apps_cdn_visibility: none`:

```sh
gh workflow run build-php-cli-binaries.yml --ref fix-php-verify-sigpipe \
  -f php_version=8.4.25 -f package_version=studio-2 \
  -f xdebug_version=3.5.3 -f apps_cdn_visibility=none
```

Expect all five targets green.

## Pre-merge Checklist

- [x] Have you checked for TypeScript, React or other console errors?

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
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.

1 participant