Saltar al contenido principal

Automatización de versiones

Las versiones de Libre WebUI se crean desde la raíz del repositorio mediante el script de publicación. El script lee el historial real de Git desde la etiqueta de versión anterior, actualiza las versiones de los paquetes, escribe el registro de cambios, ejecuta las comprobaciones, crea el commit de publicación y genera la etiqueta. GitHub es el origen de la compilación y de los binarios; los metadatos de la versión y los enlaces con nombre a los artefactos se replican en el repositorio Forgejo del proyecto.

Configuración local inicial

Instala las dependencias y activa los hooks del repositorio:

npm install
npm run setup-hooks

La configuración de hooks define:

  • .githooks/commit-msg para validar Conventional Commits
  • .githooks/pre-commit para comprobar el formato
  • .gitmessage como plantilla local de mensajes de commit

Crear una versión

Ejecuta el script desde un árbol de trabajo limpio en la rama que pretendas etiquetar:

# Patch release
npm run release

# Minor release
npm run release:minor

# Major release
npm run release:major

El script realiza automáticamente lo siguiente:

  1. Comprueba que el árbol de trabajo esté limpio y que la siguiente etiqueta local esté disponible.
  2. Recopila pruebas de commits, archivos, dependencias, locales y cambios aún no publicados.
  3. Genera las notas de versión a partir de esas pruebas.
  4. Actualiza package.json, los archivos de paquetes del workspace, package-lock.json, las versiones del chart Helm y de la aplicación y CHANGELOG.md.
  5. Ejecuta npm run release:check, incluidos formato, lint, compilaciones, pruebas, auditoría de seguridad y simulación de publicación de npm.
  6. Solo después de superar todas las comprobaciones crea el commit y la etiqueta anotada.

Generar el registro de cambios

Previsualiza la siguiente sección sin modificar archivos:

npm run changelog

Actualiza manualmente CHANGELOG.md con la sección generada:

npm run changelog -- update

De forma predeterminada, el generador puede pedir a un modelo local compatible con Ollama un borrador pulido y validarlo después frente a las pruebas recopiladas de Git. Si la IA no está disponible o el resultado parece inseguro, el script recurre a un generador determinista.

Sustituciones útiles:

CHANGELOG_AI=0 npm run release:minor
CHANGELOG_AI_MODEL=glm-5.2:cloud npm run changelog
OLLAMA_BASE_URL=http://127.0.0.1:11434 npm run release

Enviar una versión

Tras crear el commit y la etiqueta anotada, publica únicamente el commit de rama y la etiqueta exactos que muestre el script. La rama de producción se envía primero a Forgejo y después a GitHub, con las etiquetas seguidas desactivadas de forma explícita:

git -c push.followTags=false push \
https://git.kroonen.ai/libre-webui/libre-webui.git \
HEAD:refs/heads/main
git ls-remote \
https://git.kroonen.ai/libre-webui/libre-webui.git \
refs/heads/main

git -c push.followTags=false push \
https://github.com/libre-webui/libre-webui.git \
HEAD:refs/heads/main
git ls-remote \
https://github.com/libre-webui/libre-webui.git \
refs/heads/main

Los SHA devueltos de ambas ramas deben coincidir con el commit local de publicación previsto. Espera a que terminen correctamente los workflows de GitHub necesarios para ese commit exacto antes de publicar la etiqueta.

Confirma que la etiqueta no exista aún en ninguno de los dos servicios y envía solo esa etiqueta, primero a Forgejo y después a GitHub:

git ls-remote \
https://git.kroonen.ai/libre-webui/libre-webui.git \
'refs/tags/vX.Y.Z' 'refs/tags/vX.Y.Z^{}'
git ls-remote \
https://github.com/libre-webui/libre-webui.git \
'refs/tags/vX.Y.Z' 'refs/tags/vX.Y.Z^{}'

git -c push.followTags=false push \
https://git.kroonen.ai/libre-webui/libre-webui.git \
refs/tags/vX.Y.Z:refs/tags/vX.Y.Z
git -c push.followTags=false push \
https://github.com/libre-webui/libre-webui.git \
refs/tags/vX.Y.Z:refs/tags/vX.Y.Z

git ls-remote \
https://git.kroonen.ai/libre-webui/libre-webui.git \
'refs/tags/vX.Y.Z' 'refs/tags/vX.Y.Z^{}'
git ls-remote \
https://github.com/libre-webui/libre-webui.git \
'refs/tags/vX.Y.Z' 'refs/tags/vX.Y.Z^{}'

Sustituye vX.Y.Z por la etiqueta de versión. En una etiqueta anotada, verifica tanto el SHA del objeto etiqueta como el SHA del commit al que apunta. No uses nunca git push --tags, que podría publicar etiquetas locales no relacionadas.

Ruta de publicación en CI

Enviar una etiqueta v* ejecuta el workflow de publicación de GitHub, que:

  • Ejecuta npm run release:check
  • Compila artefactos Electron para macOS, Windows y Linux
  • Crea la versión de GitHub desde la sección correspondiente de CHANGELOG.md
  • Replica el registro de versión y los enlaces con nombre a Forgejo
  • Compila imágenes Docker
  • Publica el chart Helm con la misma versión que la etiqueta
  • Publica el paquete npm mediante NPM_TOKEN

La misma comprobación puede ejecutarse localmente antes de etiquetar:

npm run release:check

Réplica de versiones en Forgejo

La réplica usa un token de acceso personal de Forgejo guardado como secreto cifrado de GitHub Actions FORGEJO_TOKEN. Concede al token únicamente el ámbito write:repository, asegúrate de que su propietario pueda escribir en libre-webui/libre-webui y no confirmes ni imprimas nunca el token.

La réplica es deliberadamente idempotente. Busca versiones por etiqueta, crea solo los registros que faltan, concilia sus metadatos con la versión de GitHub e ignora los enlaces de artefactos existentes. Reintentar tras un fallo de red o workflow completa por tanto el trabajo pendiente sin duplicar versiones ni recursos.

Los recursos de Forgejo son enlaces externos con nombre al browser_download_url público correspondiente de GitHub. GitHub sigue alojando los binarios, mientras Forgejo muestra los mismos nombres descargables sin duplicar decenas de gigabytes de artefactos de escritorio. Los archivos de código fuente se generan por separado a partir de la etiqueta exacta en cada servicio.

Previsualizar o completar una versión

Inspecciona qué cambiaría sin escribir en Forgejo:

node scripts/mirror-forgejo-releases.mjs --tag vX.Y.Z --dry-run

Tras cargar FORGEJO_TOKEN y GITHUB_TOKEN en el entorno del proceso desde el gestor de secretos, replica esa versión:

node scripts/mirror-forgejo-releases.mjs --tag vX.Y.Z

La etiqueta exacta debe existir ya en GitHub y Forgejo y resolverse al mismo objeto etiqueta y commit antes de replicar una versión.

Previsualizar o completar todas las versiones

Audita todas las versiones de GitHub frente a Forgejo:

node scripts/mirror-forgejo-releases.mjs --all --dry-run

Completa todas las versiones de Forgejo ausentes o incompletas:

node scripts/mirror-forgejo-releases.mjs --all

GITHUB_TOKEN es obligatorio para --all, incluso en simulaciones, porque comprobar la paridad exacta de etiquetas y descubrir recursos exige más solicitudes de las permitidas por la API anónima de GitHub. FORGEJO_TOKEN también es necesario cuando no se utiliza --dry-run.

La ruta --all pagina ambas API y considera objetos GitHub Release, no todas las etiquetas Git. Una etiqueta que intencionadamente no tenga una versión de GitHub seguirá siendo solo una etiqueta en Forgejo. Repite la simulación después de completar las versiones; no debería quedar ningún cambio pendiente.

Política de etiquetas inmutables

Las etiquetas de versión publicadas son inmutables. Cuando una etiqueta existe en cualquier remoto:

  • No la elimines.
  • No la envíes a la fuerza.
  • No la muevas a un commit corregido.
  • No reutilices su versión semántica para otro contenido.

Si el contenido publicado es incorrecto, corrige el código y el registro y publica la siguiente versión de parche. Si solo falta una página o enlace externo, vuelve a ejecutar la réplica idempotente sin tocar la etiqueta.

La etiqueta v0.8.6 de Forgejo se realineó una única vez con aprobación explícita al introducir la doble réplica. Corrigió dos objetos históricos que describían árboles de código idénticos pero seguían historiales de commits distintos. Esa migración auditada no sienta precedente para mover etiquetas publicadas.

Política de versiones de Helm

La version del chart Helm, su appVersion, la versión del paquete raíz y la etiqueta usan intencionadamente la misma versión semántica. El script las avanza juntas y CI rechaza discrepancias.

El chart solo se publica desde una etiqueta v* inmutable. No publiques contenido modificado bajo una versión existente. Todo cambio del chart debe pasar por la siguiente versión de la aplicación.

La versión 0.14.1 del chart incluye una sustitución excepcional del digest porque es anterior a las etiquetas Docker semánticas. El digest identifica la imagen multiarquitectura 0.14.1 verificada. El script elimina la sustitución al crear la siguiente versión y después la imagen predeterminada se resuelve al appVersion del chart.

El workflow Docker publica esa etiqueta semántica en GHCR y Docker Hub desde la misma etiqueta v*. La publicación Helm espera hasta 20 minutos la imagen pública correspondiente en Docker Hub y falla en lugar de publicar un chart cuya imagen predeterminada no exista. La imagen Ollama incluida sigue siendo configurable por separado y usa de forma predeterminada la etiqueta upstream latest.

Conventional Commits

Los mensajes de commit deben usar el formato Conventional Commit:

<type>[optional scope]: <description>

Tipos habituales:

  • feat: función visible para el usuario
  • fix: corrección de errores
  • docs: actualización de documentación
  • refactor: reestructuración interna del código
  • perf: mejora de rendimiento
  • test: cobertura de pruebas
  • chore: mantenimiento, publicación o compilación

Los cambios incompatibles usan !:

git commit -m "feat!: remove deprecated endpoint"
git commit -m "fix(auth)!: change token validation"

Solución de problemas

El directorio de trabajo no está limpio

Confirma o guarda temporalmente los cambios antes de publicar:

git status --short
git add .
git commit -m "fix: resolve pending changes"

No hay cambios publicables

Consulta los commits desde la etiqueta anterior:

git log $(git describe --tags --abbrev=0)..HEAD --oneline

El registro necesita edición manual

Edita CHANGELOG.md y confirma la corrección antes de publicar la etiqueta:

git add CHANGELOG.md
git commit -m "docs: refine changelog"

Revertir un commit de publicación local

Si no se han enviado ni el commit ni la etiqueta:

git tag -d v0.12.0
git reset --soft HEAD~1

Si cualquier remoto ya contiene la etiqueta, no la elimines ni sustituyas. Corrige el problema en main, crea la siguiente versión de parche y publica la nueva etiqueta inmutable mediante toda la barrera.

La réplica de Forgejo está incompleta

Comprueba primero que coincidan los SHA del objeto etiqueta y el commit apuntado en ambos remotos. Después previsualiza y reintenta la versión afectada:

node scripts/mirror-forgejo-releases.mjs --tag vX.Y.Z --dry-run
node scripts/mirror-forgejo-releases.mjs --tag vX.Y.Z

Un fallo de autorización indica que FORGEJO_TOKEN falta, ha caducado, pertenece a un usuario sin acceso al repositorio o carece de write:repository. Una etiqueta remota ausente o distinta debe investigarse por separado; la réplica nunca crea ni mueve etiquetas Git.

Archivos para mantenedores

  • .gitmessage - plantilla de mensaje de commit
  • .githooks/commit-msg - validación de Conventional Commit
  • .githooks/pre-commit - comprobación preliminar de formato
  • scripts/release.js - coordinación de publicaciones
  • scripts/mirror-forgejo-releases.mjs - réplica idempotente y completado de versiones de Forgejo
  • scripts/generate-changelog.js - comando de previsualización y actualización del registro
  • scripts/lib/releaseNotes.js - recopilación de pruebas y generación del registro
  • .github/workflows/release.yml - workflow de CI impulsado por etiquetas
  • .github/workflows/helm-publish.yml - validación de Helm y publicación de etiquetas

Para obtener más información sobre Conventional Commits, visita https://www.conventionalcommits.org/.