ES

Compilar el micro de PHP en tus propios runners (el workflow standalone)

bin/jumphp export:standalone y app:export pegan un juego o una aplicación a un micro: PHP compilado de forma estática (StaticPHP) con las extensiones que necesita JumPHP. Los micros los compila el workflow .github/workflows/standalone.yml y se publican como la release standalone-<clave> (la clave es un hash de la versión de PHP, la lista de extensiones, el commit de StaticPHP y el registro y los parches de JumPHP: tools/standalone-key.sh). Por tanto, un micro se compila de nuevo solo cuando cambia alguno de ellos. Esta página explica cómo ejecutar ese workflow en runners propios (consulta ci-runner.md para instalarlos) y qué te daban gratis las máquinas de GitHub que las tuyas quizá no tengan.

Ejecutarlo

Forja > el repositorio > Actions > standalone > Run workflow, o desde un terminal (gh es el de la forja en un proyecto JumPHP):

gh workflow run standalone.yml -f extensions=tools/app-extensions.txt -f macos=false -f linux=false
Entrada Valores
extensions tools/standalone-extensions.txt (juegos: SDL, OpenGL, OpenAL), tools/app-extensions.txt (aplicaciones de escritorio, el IDE), tools/hybrid-extensions.txt el micro fabricado = su propia clave
linux true / false false: sin micro de Linux (ver « Docker » más abajo); export:standalone compila entonces el de Linux en el equipo del usuario
macos true / false false: sin micro de Mac (solo aplicaciones de escritorio); sin un runner de macOS los jobs esperarían para siempre

El job de Windows tarda unos 10 minutos con las descargas en caché, 30-60 la primerísima vez. Su resultado: https://<forja>/<propietario>/<repo>/releases/download/standalone-<clave>/micro-windows-x86_64.sfx.

Lo que tenían las máquinas de GitHub y quizá no las tuyas

En GitHub el mismo workflow « funcionaba sin más » porque windows-latest y ubuntu-latest son imágenes preparadas por GitHub. Un runner propio es una máquina desnuda. Todo lo que sigue lo gestiona el workflow, o se indica aquí:

Imagen de GitHub Un runner propio Qué hacen el workflow / tú
PowerShell 7 (pwsh), PHP, Composer, Git a menudo solo Windows PowerShell 5.1 y Git los pasos se ejecutan en Windows PowerShell; PHP 8.4 y Composer se descargan (php.net, getcomposer.org, hash verificado) si faltan; el usr\bin de Git se añade al PATH
Windows en inglés el idioma de tu Windows (francés, ...) VSLANG=1033 hace que las herramientas de Visual Studio hablen inglés: el configure.js de PHP lee la salida del enlazador y, si no, se detiene con un error de JScript
Visual Studio 2022 lo instalas tú: Build Tools 2022, carga de trabajo « Desarrollo de escritorio con C++ » lo único que debe tener un runner de Windows (junto con Git for Windows). install-windows-runner.ps1 instala ambos
Acceso rápido y rara vez limitado a api.github.com la misma API responde 504 o « rate limit exceeded » las descargas de StaticPHP se reintentan 4 veces y se conservan en %USERPROFILE%\.spc-downloads entre ejecuciones; Composer instala desde las fuentes (--prefer-source)
actions/upload-artifact@v4, download-artifact@v4 Forgejo no los admite (« not currently supported on GHES ») en una forja el job de Windows publica el micro él mismo en la release (el github.token del job, la API de la forja); el job release solo se ejecuta en GitHub
Docker en el job de Linux el job se ejecuta en un contenedor sin Docker ver más abajo
Fines de línea LF Git for Windows convierte a CRLF git config --global core.autocrlf false antes de clonar StaticPHP (un parche de sus archivos coincide con su texto)

Docker: dónde hace falta y dónde no

  • El job de Windows compila de forma nativa con Visual Studio. No usa Docker y un runner de Windows no puede ejecutarlo por ti (los contenedores Linux en Windows necesitan WSL2). Nada que instalar para eso.
  • El job de Linux ejecuta docker build docker/standalone y luego docker run de StaticPHP. Dentro de un contenedor de job no hay Docker salvo que el runner se lo dé: monta el socket de Docker del host (o el del dind del runner) en el job (container.options / valid_volumes en el config.yml del runner), o usa el runner Linux en WSL2 (ci-runner.md sección 4), que es un Linux real con Docker. Sin eso, ejecuta con linux=false: bin/jumphp export:standalone <id> --linux compila el micro de Linux en el equipo que exporta (unos 15 minutos, luego se conserva en ~/.jumphp/standalone/).
  • Sea cual sea el runner, nunca copies ni renombres un micro bajo otra clave: sería un PHP sin las extensiones correctas y los ejecutables de tus usuarios se bloquearían (Call to undefined function SDL_Init()). Si la clave cambió, hay que recompilar el micro.

Solución de problemas

Los logs de los jobs se leen en la página de la ejecución en la forja (job > el paso en rojo); la API de la forja no los devuelve.

Síntoma Causa / solución
El job key falla en 30 s, justo después de « Fetching the repository » el contenedor del job no resuelve la forja: el Docker-in-Docker del runner no tiene DNS exterior. Dale uno: dns: [1.1.1.1, 9.9.9.9] en el servicio dind del compose del runner. Prueba: docker run --network <una red nueva> node:20-bookworm getent hosts <forja>
Cannot find: pwsh in PATH el workflow pide Windows PowerShell (shell: powershell); una copia antigua del workflow pedía pwsh. Actualízala
configure.js ... Microsoft JScript runtime error tras « Checking for link.exe » las herramientas de Visual Studio escriben en el idioma de Windows. VSLANG=1033 (en el workflow desde esta página)
ERROR: bison is required visto tras una compilación anterior a medias en la misma carpeta: StaticPHP conserva las herramientas msys2 pero no las vuelve a poner en el PATH. Elimina spc/pkgroot, spc/source, spc/buildroot del espacio de trabajo y ejecuta de nuevo (un espacio limpio, como el de un job nuevo, funciona)
Un parche de StaticPHP « not patched (StaticPHP changed) » o « Failed patch module » fines de línea CRLF (core.autocrlf false y clonar de nuevo), o una carpeta de fuentes parcheada por un intento anterior (elimina spc/source/php-src)
Failed to get GitHub release API info for madler/zlib / HTTP/2 504 api.github.com limita o falla para tu dirección. El workflow reintenta; la primera ejecución en una máquina nueva puede necesitar un segundo intento. Las descargas se conservan, así que cada reintento avanza más
GHESNotSupportedError: upload-artifact@v4 ... not currently supported usas Forgejo: usa el workflow de este repositorio (publica sin artifacts)
Los jobs de macOS se quedan en « waiting » y la ejecución nunca termina no hay runner de macOS: -f macos=false
Cannot find path ...\buildroot\bin\micro.sfx la compilación falló antes: lee las líneas anteriores (son la causa)

Para agentes de IA

Pueden pedirte « haz que el workflow standalone funcione en mi runner ». Lee el paso que falla en la página de la ejecución (pide al usuario que lo pegue si no puedes acceder), cambia el workflow (debe seguir siendo válido también en GitHub: prueba github.server_url), no la máquina del usuario, salvo que lo que falte sea un requisito previo de los anteriores (Git, Visual Studio Build Tools, Docker para el job de Linux): entonces díselo al usuario e instálalo solo si dice que sí. Nunca registres un runner, nunca escribas un token en un archivo, nunca publiques un micro que no hayas compilado a partir de los archivos actuales con los comandos propios de este workflow, nunca muevas una release bajo otra clave. Tras una ejecución correcta, comprueba el asset (gh release view standalone-<clave>, una descarga que responda 200) y, para un micro de Windows, ejecuta un script con él en la máquina del runner (copy /b micro.sfx + test.php test.exe, luego test.exe: versión de PHP, extension_loaded('ffi')...).