build: ship the CLI as a standalone native binary#2
Merged
Conversation
Add a build pipeline that turns the CLI into (a) a self-contained PHAR and (b) a static native executable that runs without a system PHP. - box.json.dist: Box 4 config that compiles src/ + vendor/ into build/durable-workflow.phar with PHP + JSON compactors and gzip compression. - scripts/build.sh + Makefile: local "make phar" and "make binary" targets. The binary target downloads static-php-cli (spc) on demand, compiles phpmicro with the extensions the CLI actually uses (curl, mbstring, openssl, phar, tokenizer, ctype, filter, fileinfo, iconv, sockets, pcntl, posix), and splices the PHAR onto the micro SAPI via "spc micro:combine". - .github/workflows/build.yml: PR/push CI. Runs PHPUnit across PHP 8.2/8.3/8.4 and smoke-builds the PHAR. - .github/workflows/release.yml: on "v*" tags, builds the PHAR once and then a native binary per platform (linux x86_64/aarch64, macos x86_64/aarch64) using spc, then publishes a GitHub release with SHA256SUMS. - README: document the three install paths (standalone binary, PHAR, Composer) and the "make" targets. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds a windows-latest job that builds phpmicro + spc on MSVC and splices the PHAR into a durable-workflow-windows-x86_64.exe. The Windows extension list drops pcntl/posix (Unix-only). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The committed composer.lock pins symfony/string v8.0.8, which requires PHP >= 8.4. Updates both CI workflows and scripts/build.sh to build against 8.4 (the lowest resolvable version for the locked deps). Also drops pcntl and posix from the extension list. They are only used by symfony/console for graceful signal handling and TTY detection, both of which degrade cleanly when missing, and removing them gives Unix and Windows builds the same extension set. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Building phpmicro from source per platform takes ~15-30 minutes (especially on Windows). Running it on every feature-branch commit is too expensive. Drop the feature-branch trigger so the workflow only runs on 'v*' tag pushes or explicit workflow_dispatch. Note: the in-flight branch build will still complete. This change just prevents future commits from kicking off a new one. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add --debug to the Windows phpmicro build and always upload the
build/.tools/log/ directory so MSVC errors are recoverable.
- Retry the spc binary download up to 5 times on Linux/macOS/Windows.
The bare curl call was hitting transient CDN failures on
dl.static-php.dev (observed HTTP errors on linux-x86_64 and
macos-aarch64 in the previous run).
- Drop the macos-x86_64 matrix entry. The macos-13 runner label is
not available to this org ("macos-13-us-default is not supported"),
and Apple Silicon is the practical target anyway.
- Temporarily re-enable the branch push trigger while we iterate on
the Windows fix. Will be removed before merge.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Drop ext-openssl from the Windows phpmicro build. PHP 8.4 on Windows fails to compile its openssl extension against OpenSSL 3.x because php_openssl.h still references the removed ERR_NUM_ERRORS constant (upstream php-src issue). The CLI does not need ext-openssl on Windows: curl is built with -DCURL_USE_SCHANNEL=ON, so HTTPS via Symfony HttpClient -> ext-curl -> Schannel continues to work. - Export GITHUB_TOKEN as a workflow-level env so every spc step can authenticate against the GitHub API when resolving source tarballs and pre-built static-php-cli-hosted libs. The unauthenticated calls were hitting HTTP 403 and failing the macos-aarch64 download step. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The Windows phpmicro build is blocked on an upstream bug: PHP 8.4's
Windows ext-openssl references ERR_NUM_ERRORS (removed in OpenSSL 3),
and spc pulls ext-openssl in as a transitive dependency of ext-curl
even though curl on Windows uses Schannel. Fixing this requires an
spc dep-map change or a php-src patch.
Until that is resolved upstream:
- The Windows job keeps running (so regressions vs. a future fix
are visible) but uses continue-on-error so it does not block the
Linux/macOS binary release.
- The publish-release job only hard-depends on build-phar and
build-binary (Linux + macOS). If Windows succeeds, its artifact
is still picked up.
- README lists only the platforms we actually ship.
Also drops the temporary standalone-binary-build push trigger; the
release workflow is back to tag/dispatch-only.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
PHP 8.4's Windows ext-openssl fails to compile against OpenSSL 3.x because php_openssl.h still references the removed ERR_NUM_ERRORS constant. PHP 8.3's openssl extension doesn't have this reference and compiles cleanly on spc's Windows pipeline. Using 8.3 phpmicro to run the PHAR that was built with 8.4 Composer resolution is acceptable here: the locked runtime code is expected to be ABI-compatible with 8.3. If any locked dep actually uses 8.4-only syntax, the smoke test at the end of the job will catch it before the artifact is uploaded. Also re-adds the temporary feature-branch push trigger and drops continue-on-error on the Windows job so this iteration reports a real result. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Both PHP 8.3 and 8.4 fail to compile ext-openssl on Windows against
OpenSSL 3.x — php_openssl.h references the removed ERR_NUM_ERRORS
constant. spc's dependency map (config/ext.json) hard-codes openssl
as a Windows-only transitive dep of ext-curl, so even removing
openssl from --for-extensions does not help: spc still pulls it in.
The prebuilt spc binary embeds ext.json, so overriding it externally
is impossible. Switch the Windows job to run spc from a source clone:
- shivammathur/setup-php installs PHP 8.3 on the runner
- git clone static-php-cli, then a small Python patch strips
"openssl" from curl.ext-depends-windows in config/ext.json
- composer install inside the spc clone
- php bin\spc download/build/micro:combine
libcurl itself still links libopenssl at the transport layer for TLS,
so HTTPS via Symfony HttpClient -> ext-curl continues to work without
the PHP-side ext-openssl.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…can enumerate shells
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.
Summary
Adds a build pipeline that turns this CLI into a standalone native executable (no system PHP required on the target machine) in addition to the existing Composer install path.
durable-workflow.pharwith src/ + vendor/, PHP/JSON compactors, gzip.spc) — the PHAR is embedded into thephpmicroSAPI, producing a single statically-linked executable per OS/arch.make pharormake binary(downloads Box andspcon demand intobuild/.tools/)..github/workflows/build.yml— PRs run PHPUnit on PHP 8.2/8.3/8.4 and smoke-build the PHAR..github/workflows/release.yml— onv*tags, builds the PHAR once then fans out a matrix for linux x86_64/aarch64 and macOS x86_64/aarch64, then publishes a GitHub Release with all assets +SHA256SUMS.Extensions baked into the phpmicro build match what the CLI actually uses today:
curl, mbstring, openssl, phar, tokenizer, ctype, filter, fileinfo, iconv, sockets, pcntl, posix. The list is defined once inscripts/build.shand referenced from the release workflow viaSPC_EXTENSIONS.Test plan
make pharlocally produces a workingbuild/durable-workflow.phar(requires PHP >= 8.2).make binarylocally producesbuild/durable-workflow-<platform>that runs on a machine without PHP.v0.0.0-testtag (or use theworkflow_dispatchinput) and confirm the release workflow produces all four native binaries + the PHAR +SHA256SUMS.build.yml) still runs the full PHPUnit matrix and Box smoke build.🤖 Generated with Claude Code