Build the PHP micro on your own runners (the standalone workflow)
bin/jumphp export:standalone and app:export glue a game or an app onto a micro: PHP built statically (StaticPHP) with the
extensions JumPHP needs. The micros are built by the workflow .github/workflows/standalone.yml and published as the release
standalone-<key> (the key is a hash of PHP's version, the extension list, StaticPHP's commit and JumPHP's registry and patches:
tools/standalone-key.sh). A micro is therefore built again only when one of those changes. This page tells you how to run
that workflow on runners of your own (see ci-runner.md to install them), and what GitHub's machines gave you
for free that yours may not.
Run it
Forge > the repository > Actions > standalone > Run workflow, or from a terminal (gh is the forge's one in a JumPHP project):
gh workflow run standalone.yml -f extensions=tools/app-extensions.txt -f macos=false -f linux=false
| Input | Values | |
|---|---|---|
extensions |
tools/standalone-extensions.txt (games: SDL, OpenGL, OpenAL), tools/app-extensions.txt (desktop apps, the IDE), tools/hybrid-extensions.txt |
the micro made = its own key |
linux |
true / false |
false: no Linux micro (see "Docker" below); export:standalone then builds the Linux one on the user's computer |
macos |
true / false |
false: no Mac micro (desktop apps only); without a macOS runner the jobs would wait forever |
The Windows job takes about 10 minutes with the downloads cached, 30-60 the very first time. Its result:
https://<forge>/<owner>/<repo>/releases/download/standalone-<key>/micro-windows-x86_64.sfx.
What GitHub's machines had, and yours may not
On GitHub the same workflow "just worked" because windows-latest and ubuntu-latest are images prepared by GitHub. A runner of your
own is a bare machine. Everything below is handled by the workflow, or told here:
| GitHub's image | A runner of your own | What the workflow / you do |
|---|---|---|
PowerShell 7 (pwsh), PHP, Composer, Git |
often only Windows PowerShell 5.1 and Git | the steps run in Windows PowerShell; PHP 8.4 and Composer are downloaded (php.net, getcomposer.org, hash checked) when missing; Git's usr\bin goes into the PATH |
| Windows in English | your Windows language (French, ...) | VSLANG=1033 makes the Visual Studio tools speak English: PHP's configure.js reads the linker's output and stops with a JScript error otherwise |
| Visual Studio 2022 | you install it: Build Tools 2022, workload "Desktop development with C++" | the one thing a Windows runner must have (with Git for Windows). install-windows-runner.ps1 installs both |
Fast, rarely rate-limited access to api.github.com |
the same API answers 504 or "rate limit exceeded" |
StaticPHP downloads are retried 4 times and kept in %USERPROFILE%\.spc-downloads between runs; Composer installs from sources (--prefer-source) |
actions/upload-artifact@v4, download-artifact@v4 |
Forgejo does not support them ("not currently supported on GHES") | on a forge the Windows job publishes the micro itself to the release (the job's github.token, the forge API); the release job only runs on GitHub |
| Docker in the Linux job | the job runs in a container without Docker | see below |
| LF line endings | Git for Windows converts to CRLF | git config --global core.autocrlf false before cloning StaticPHP (a patch of its files matches their text) |
Docker: where it is needed, where it is not
- The Windows job builds natively with Visual Studio. It does not use Docker and a Windows runner cannot run it for you (Linux containers on Windows need WSL2). Nothing to install for that.
- The Linux job runs
docker build docker/standalonethendocker runof StaticPHP. Inside a job container there is no Docker unless the runner gives it one: mount the host's (or the runner's dind) Docker socket into the job (container.options/valid_volumesin the runner'sconfig.yml), or use the WSL2 Linux runner (ci-runner.md section 4), which is a real Linux with Docker. Without that, run withlinux=false:bin/jumphp export:standalone <id> --linuxbuilds the Linux micro on the computer that exports (about 15 minutes, then kept in~/.jumphp/standalone/). - Whatever the runner, never copy or rename a micro under another key: it would be a PHP without the right extensions, and the
executables of your users would crash (
Call to undefined function SDL_Init()). If the key changed, the micro must be rebuilt.
Troubleshooting
Job logs are read on the forge's page of the run (job > the red step); the forge's API does not return them.
| Symptom | Cause / fix |
|---|---|
The job key fails in 30 s, right after "Fetching the repository" |
the job's container cannot resolve the forge: the runner's Docker-in-Docker has no outside DNS. Give it some: dns: [1.1.1.1, 9.9.9.9] on the dind service of the runner's compose file. Test: docker run --network <a new network> node:20-bookworm getent hosts <forge> |
Cannot find: pwsh in PATH |
the workflow asks Windows PowerShell (shell: powershell); an old copy of the workflow asked pwsh. Update it |
configure.js ... Microsoft JScript runtime error after "Checking for link.exe" |
Visual Studio's tools print in the language of Windows. VSLANG=1033 (in the workflow since this page) |
ERROR: bison is required |
seen after a half-done earlier build in the same folder: StaticPHP keeps the msys2 tools but does not put them in the PATH again. Delete the workspace's spc/pkgroot, spc/source, spc/buildroot and run again (a clean workspace, as a new job has, works) |
| A patch of StaticPHP "not patched (StaticPHP changed)" or "Failed patch module" | CRLF line endings (core.autocrlf false and clone again), or a source folder patched by an earlier attempt (delete spc/source/php-src) |
Failed to get GitHub release API info for madler/zlib / HTTP/2 504 |
api.github.com is rate-limiting or failing for your address. The workflow retries; the first run on a new machine may need a second try. Downloads are kept, so each retry goes further |
GHESNotSupportedError: upload-artifact@v4 ... not currently supported |
you use Forgejo: use the workflow of this repository (it publishes without artifacts) |
| The macOS jobs stay "waiting" and the run never ends | no macOS runner: -f macos=false |
Cannot find path ...\buildroot\bin\micro.sfx |
the build failed before: read the lines above it (they are the cause) |
For AI agents
You may be asked to "make the standalone workflow work on my runner". Read the failing step on the run's page (ask the user to paste it if
you cannot reach it), change the workflow (it must stay valid on GitHub too: test github.server_url), not the user's machine, unless
what is missing is a prerequisite above (Git, Visual Studio Build Tools, Docker for the Linux job): then tell the user and install it
only when they say yes. Never register a runner, never write a token in a file, never publish a micro that you did not build from the
current files with this workflow's own commands, never move a release under another key. After a successful run, check the asset
(gh release view standalone-<key>, a download answering 200) and, for a Windows micro, run a script with it in the runner's machine
(copy /b micro.sfx + test.php test.exe, then test.exe: PHP version, extension_loaded('ffi')...).