Article

El composer.lock que solo compila en su máquina

Un repositorio de tipo path ignorado por git, que enlaza simbólicamente un módulo del registro a una copia local, escribe un dist de tipo path en composer.lock. Haga commit de ese lock y todos los trabajos de CI y compilaciones de imágenes fallarán, porque el directorio hermano solo existe en su máquina. Regenere el lock con la anulación apartada y añada una protección en CI que rechace un dist de tipo path.
July 14, 2026
Topics:Dependency ManagementCI/CD
Tags:ComposerPHP

Usted desarrolla un módulo contribuido contra una copia local, hace commit, y CI se pone en rojo en todos los trabajos, o peor, la compilación de la imagen de producción falla. El culpable es una línea en composer.lock que solo tiene sentido en su portátil.

La configuración

Para trabajar en un módulo que está publicado en un registro, es habitual apuntar Composer a una copia local con un repositorio path en un archivo de anulación ignorado por git:

// composer.local.json (git-ignored)
"repositories": { "my_module": { "type": "path", "url": "../my_module" } }

Composer enlaza simbólicamente el módulo desde el directorio hermano. Excelente para el desarrollo. La trampa es lo que escribe en el archivo lock.

La trampa

Con la anulación activa, composer.lock registra el módulo con un dist de tipo path que apunta a ../my_module:

"dist": { "type": "path", "url": "../my_module" }

Esa ruta existe solo en su máquina. Haga commit del lock y todos los entornos que ejecuten composer install a partir de él —CI, la compilación de la imagen, un compañero de equipo— buscarán un directorio hermano que no está ahí, y fallarán. La versión del registro nunca se instala, porque el lock dice que use la ruta.

La solución

Regenere el lock con la anulación apartada, para que registre el dist del registro:

mv composer.local.json composer.local.json.aside
composer update my_module --no-install   # relock from the registry
mv composer.local.json.aside composer.local.json

Confirme que el lock ahora muestra un dist real del registro ("type": "zip", una URL https), no una ruta. Luego haga commit solo del lock, nunca de la anulación.

Protéjalo en CI

Esto es fácil de hacer por accidente, así que haga que sea imposible de fusionar. Una comprobación de una línea que hace fallar la compilación cuando el lock contiene un dist de tipo path detecta todos los casos antes de que lleguen a la rama principal:

grep -q '"type": "path"' composer.lock && { echo 'path dist in lock'; exit 1; } || true

Conclusión

Una anulación local por ruta es una comodidad de desarrollo que nunca debe llegar al lock confirmado. Vuelva a generar el lock con la anulación apartada, verifique que el dist sea una URL del registro y añada una protección del archivo lock para que "funciona en mi máquina" no pueda convertirse en "rompe todas las compilaciones".