Publicar una versión
En el ecosistema, la versión se declara y el tag se deriva. Una persona sube VERSION (o la version de package.json), empuja, y si los tests pasan la CI crea el tag y el registro publica.
Por qué así
Antes, un bump-patch.yml copiado en 22 repositorios autoincrementaba un tag en cada push a master sin correr un solo test. Además leía la última versión con git tag --sort=creatordate, que ordena por fecha y no por semver, y bastaba un #major mencionado de pasada en un mensaje de commit para publicar una versión mayor sin quererlo.
Con el modelo actual:
- La versión es una decisión explícita, en un archivo que se revisa en el diff.
- Los tests son la puerta: un push con un test roto no publica nada.
- Un tag que ya existe no se vuelve a crear: empujar sin tocar la versión no publica nada, y una versión publicada no se sobrescribe.
Paquetes PHP
- Haz el cambio y comprueba en local (ver la lista).
- Sube
VERSIONsegún semver y describe el cambio enCHANGELOG.md. - Empuja a
master(omain). Testscorre la suite, la auditoría y los trabajos del repositorio.- Si pasa,
ReleaseleeVERSIONy crea el tag sin prefijov(2.1.1). - Packagist publica al recibir el tag.
cat VERSION # 2.1.1
git push origin master
gh run watch # sigue la ejecución en curso
git ls-remote --tags origin 2.1.1 # el tag existe
composer show --all innoboxrr/support | grep versionsEl release.yml de cada repositorio:
name: Release
on:
workflow_run:
workflows: ['Tests']
types: [completed]
branches: [main, master]
workflow_dispatch:
jobs:
release:
permissions:
contents: write
uses: innoboxrr/.github/.github/workflows/php-release.yml@mainPeligro
Sin permissions: contents: write en ese archivo, un repositorio con el permiso por defecto en sólo lectura no arranca el workflow: startup_failure, sin log.
Atención
Lanzar Release a mano (workflow_dispatch) se salta la puerta de los tests: el job corre aunque Tests esté en rojo. Úsalo sólo para reintentar un release cuyo Tests ya pasó.
No pongas "version" en composer.json. Composer descarta cada tag que no coincide con ella, así que la versión nueva quedaría invisible. larapack:audit lo marca como error (composer-version).
Paquetes npm
- Sube
versionenpackage.jsony describe el cambio enCHANGELOG.md. - Empuja a
master. Testscorre la matriz de Node.- Si pasa,
Releaseactualiza npm, vuelve a instalar y probar, publica con provenance y después crea el tagv<versión>(v3.1.1).
node -p "require('./package.json').version"
git push origin master
gh run watch
npm view innoboxrr-vue-datatable versionTrusted publishing (OIDC)
La publicación no usa ningún token: npm confía en el repositorio y en su workflow.
Una vez por paquete, en npmjs.com → el paquete → Settings → Trusted Publisher: GitHub Actions, con el repositorio, el workflow release.yml y el permiso de publicar. El job necesita id-token: write, y node-release.yml ya lo declara.
Peligro
No pases NODE_AUTH_TOKEN ni NPM_TOKEN. Cuando npm ve un token se autentica con él en lugar de usar OIDC, y la publicación acaba pidiendo un código de dos factores que en la CI no hay quien teclee: la provenance se firma bien y el publish falla justo después.
- Un paquete nuevo necesita que su dueño configure el trusted publisher en npmjs.com antes de que la CI pueda publicarlo.
- El npm tiene que ser reciente. El de Node 22 es anterior al soporte de OIDC; por eso
node-release.ymlejecutanpm install -g npm@latestantes de publicar. - El registro puede tardar en listar la versión nueva aunque el log muestre el publish con provenance. Comprueba el log y el tag antes de volver a publicar.
Nota
Los release.yml npm del ecosistema no declaran permissions: los declara el reutilizable. Si un repositorio tiene el permiso por defecto del token en sólo lectura, pasa lo mismo que en PHP. En ese caso, declara en el job que llama contents: write e id-token: write.
Convenciones de commits
- En español, y explicando por qué, no qué hace el diff: «No mandar el token CSRF en la query de las peticiones GET».
- Uno por cambio conceptual. Un cambio de
laraimport.jsony su regeneración van juntos; la lógica de negocio que se escribe después, en otro. .larapack/manifest.jsonse versiona con el código que describe.- La versión se publica con su propio commit, que sube
VERSIONy elCHANGELOG: «Publicar la 6.1.0: volver de una suplantación es un POST con token CSRF». También puede ir en el mismo commit que el cambio; lo que cuenta es que nada se publica hasta que cambia la versión. - Se empuja a
master: la puerta son los tests, no una rama de release. - Sin líneas de atribución de un agente (
Co-Authored-Byde una IA) en los repositorios del ecosistema.
CHANGELOG
Cada versión cuenta qué cambió, por qué, y qué tiene que hacer quien actualice. El formato de LaraPack:
## 7.10.2
Lo que encontró el piloto de la aplicación base al exportar dentro de una
aplicación, y un aviso falso en cada importación. Lo que se genera en un paquete
no cambia.
- **La exportación renderiza en una aplicación.** Pedía su vista como
`app::excel.<modelo>` con `config('app.excel_view')`: nadie registra las vistas
`app::` y cada exportación fallaba con "No hint path defined for [app]". Ahora
pide `excel.<modelo>`, la vista que genera en `resources/views/excel`.
### Para proyectos existentes
Una aplicación generada con 7.10.0 o 7.10.1 tiene que regenerar con `--force` los
archivos de exportación de `app/Exports` y `app/Notifications`. Un paquete no tiene
que hacer nada.- Un encabezado
## X.Y.Zpor versión, la más nueva arriba. - Un párrafo de contexto y viñetas que empiezan con el cambio en negrita y siguen con el porqué.
### Para proyectos existentescuando hay algo que hacer. Si son muchos pasos, van en la guía de actualización del README («De 7.10.1 a 7.10.2») y el CHANGELOG la enlaza.
Algunos paquetes, como laravel-auth, usan el formato Keep a Changelog, con fecha y secciones como «Security» o «Cambio incompatible». Vale igual: lo que no puede faltar es el porqué y lo que tiene que hacer quien actualiza.
Lista de comprobación
Paquete PHP
- El árbol está limpio y al día con
origin/master. vendor/bin/phpunitpasa. En Windows sin SQLite:php -d extension=pdo_sqlite -d extension=sqlite3 vendor/bin/phpunit.- Si usa LaraPack:
php vendor/bin/builder larapack:verifysin errores. php vendor/innoboxrr/larapack-generator/builder larapack:audit .sin errores. Si necesitas un mínimo por encima de la línea base, usaconflict.- Si tiene el trabajo
quality:vendor/bin/pint --testyvendor/bin/phpstan analyse. - Si tiene pruebas de interfaz:
npm installynpx vitest runen cadatests/Frontend/<ui>. VERSIONsubida según semver, y ningunaversionencomposer.json.CHANGELOG.mdcon el porqué y, si hace falta, «Para proyectos existentes»; la guía de actualización del README, si hay pasos.- Empujado.
TestsyReleaseen verde, el tag existe y Packagist lo lista. - Los paquetes que dependan de esta versión nueva actualizan su
requireo suconflictdespués de que exista el tag.
Paquete npm
npm installynpm testpasan, a ser posible con npm 10 (Node 20 o 22), que es el de la CI.versionsubida enpackage.json;engines.nodees>=20; estánname,license,type,exports,filesysideEffects.CHANGELOG.mdactualizado.- Trusted publisher configurado en npmjs.com (imprescindible en un paquete nuevo), y ningún
NODE_AUTH_TOKENen el workflow ni en los secretos que recibe. - Empujado.
TestsyReleaseen verde, y existe el tagv<versión>. npm view <paquete> versionmuestra la nueva; puede tardar.- Si los módulos generados tienen que pedir la versión nueva, se actualiza
internalNpmenecosystem.jsony se publica LaraPack.