---
name: swl:release
description: Gestión del ciclo de release del proyecto. Genera versión siguiendo SemVer, crea changelog automático desde commits con Conventional Commits, valida que los tests pasan, crea tag de git y genera release notes. Flags: --tipo=patch|minor|major, --dry-run, --skip-tests.
allowed_tools: ["Read", "Write", "Edit", "Bash", "Glob", "Grep"]
evolved: true
evolved-from: "5.10.5"
evolved-at: "2026-04-20"
evolved-by: "aprender"
evolved-note: "Paso 10 integra scripts/verificar-release.js como gate anti-gap obligatoria tras 3 releases consecutivos donde el release-manager-swl omitio archivos"
---

# /swl:release — Gestión del ciclo de release

Eres el gestor de releases del proyecto. Orquestas el proceso completo de crear una nueva versión: calcular el número de versión, recopilar cambios, validar estado publicable y crear artefactos de release.

**Carga**: `Skill("release-semver")` — contiene las reglas de SemVer, Conventional Commits, estrategia de tags y proceso detallado de release. Delega toda lógica de versionado al skill.

## Cuándo usar este comando

- Al completar un conjunto de features o fixes listos para producción
- Al final de un sprint cuando hay cambios acumulados
- Para hotfixes críticos (patch release)
- Antes de una demo o entrega a cliente

## Flags soportados

```
--tipo=patch     Incrementa PATCH (0.0.X) — bugs y correcciones menores
--tipo=minor     Incrementa MINOR (0.X.0) — features nuevas sin breaking changes
--tipo=major     Incrementa MAJOR (X.0.0) — breaking changes
--dry-run        Muestra qué haría sin ejecutar nada
--skip-tests     Omite tests. Requiere justificación y confirmación explícita.
```

Si no se pasa `--tipo`, se determina automáticamente según los commits (ver skill).

## Paso 0 — Verificación de prerrequisitos

```bash
git rev-parse --is-inside-work-tree 2>&1
git branch --show-current
git status --porcelain
git remote -v
```

- Si hay cambios sin commitear, DETENER y listar archivos pendientes.
- Si la rama no es la principal, advertir y pedir confirmación.

## Paso 1 — Leer versión actual

```bash
cat package.json 2>/dev/null | grep '"version"' | head -1
cat pyproject.toml 2>/dev/null | grep "^version" | head -1
cat VERSION 2>/dev/null
git describe --tags --abbrev=0 2>/dev/null || echo "Sin tags previos"
```

Si hay múltiples fuentes, pedir al usuario que confirme la canónica. Sin versión en ningún lugar: `0.0.0`.

## Paso 2 — Recopilar y clasificar commits

```bash
LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null)
if [ -z "$LAST_TAG" ]; then
  git log --oneline --format="%H %s"
else
  git log --oneline --format="%H %s" ${LAST_TAG}..HEAD
fi
```

Clasifica cada commit según Conventional Commits (tipos y su impacto en versión definidos en `Skill("release-semver")`).

## Paso 3 — Calcular tipo de versión

Si no se especificó `--tipo`, usar reglas del skill:
- Breaking change en algún commit -> MAJOR
- feat: sin breaking changes -> MINOR
- Cualquier otro caso -> PATCH

Si el usuario pasó `--tipo` y hay discrepancia (ej: breaking changes con --tipo=patch), advertir y pedir confirmación.

## Paso 4 — Calcular nueva versión

Aplica reglas SemVer del skill: MAJOR resets MINOR y PATCH a 0, MINOR resets PATCH a 0.

Si `--dry-run`, mostrar preview del changelog y terminar sin modificar nada.

## Paso 5 — Ejecutar tests

Si NO se pasó `--skip-tests`, detectar runner y ejecutar:

```bash
ls package.json pytest.ini setup.cfg pyproject.toml Makefile 2>/dev/null
npm test 2>&1 || pytest 2>&1 || make test 2>&1
```

Si fallan, DETENER. Si `--skip-tests`, pedir confirmación explícita ("confirmo").

## Paso 6 — Actualizar archivos de versión

Actualiza la versión en TODOS los archivos que la contienen. Para proyectos SWL-SES, la checklist obligatoria es:

```
[ ] package.json
[ ] package-lock.json (2 ubicaciones: líneas 3 y 9)
[ ] plugin.json
[ ] CLAUDE.md
[ ] README.md
[ ] AGENTS.md
[ ] COMANDOS.md
[ ] MANUAL_USO.md
[ ] INSTALACION.md
[ ] SALUD.md
[ ] INVENTARIO.md
[ ] CHANGELOG.md (entrada nueva)
[ ] .planning/COMPACTACION.md
[ ] .planning/ESTADO.md
[ ] .swl-install-state.json (si existe)
```

Para proyectos no-SWL: actualiza los archivos detectados en Paso 1 (package.json, pyproject.toml, VERSION).

En ambos casos, verificar consistencia después de actualizar con `grep -r "versión-anterior" .` para detectar referencias olvidadas.

## Paso 7 — Generar CHANGELOG

Lee CHANGELOG.md existente (o créalo). Agrega entrada al inicio con formato Keep a Changelog:

- Secciones: Funcionalidades nuevas, Correcciones, Mejoras de rendimiento, Cambios internos, Breaking Changes, Estadísticas.
- Descripciones legibles por humanos (sin prefijo feat:/fix:).
- Omitir commits style: y test: del changelog público.

## Paso 8 — Commit de release y tag

```bash
git add package.json pyproject.toml setup.py VERSION CHANGELOG.md 2>/dev/null
git commit -m "chore(release): versión [nueva-versión]"
git tag -a "v[nueva-versión]" -m "Release v[nueva-versión]"
```

Usar tags anotados siempre (regla del skill).

## Paso 9 — Generar RELEASE-NOTES

Crea `RELEASE-NOTES-v[nueva-versión].md` con: resumen, cambios, instrucciones de actualización y guía de migración si hay breaking changes.

## Paso 10 — Verificación final

### 10.1 Gate automática anti-gap (OBLIGATORIA antes del push)

Ejecutar `scripts/verificar-release.js` que valida que la versión nueva esté reflejada en las 14 ubicaciones canónicas de la checklist (y avisa sobre MANUAL_USO opcional):

```bash
node scripts/verificar-release.js
```

Exit codes:
- `0` — todas las ubicaciones obligatorias con la versión correcta, puedes continuar al push
- `1` — al menos un archivo quedó en versión anterior. **NO hacer push hasta corregir**. El reporte indica el archivo y el problema específico
- `2` — error de invocación (package.json ausente, versión inválida)

Ejemplo de output en éxito:
```
[OK] package.json: version=5.10.5
[OK] plugin.json: version=5.10.5
[OK] package-lock.json: version=5.10.5, packages[""].version=5.10.5
...
[OK] CHANGELOG.md: seccion [5.10.5] presente con fecha
Resultado: 14/15 OK, 1 WARN opcional(es)
```

Ejemplo de output en fallo que obliga a corregir:
```
[FALLA] .planning/MAPEO_SKILLS_AGENTES.md: solo 0 ocurrencia(s) de 5.10.5 (minimo 1)
[FALLA] README.md: primera linea no menciona 5.10.5 — actual: "# swl-software-engineering-system v5.10.4"
Resultado: 13/15 OK, 2 FALLA(S) obligatoria(s)
```

Esta gate existe porque el agente `release-manager-swl` ha omitido archivos en 3 releases consecutivos (5.10.3, 5.10.4, 5.10.5 — ver APRENDIZAJES.md) pese a tener la checklist documentada en su frontmatter. Un checklist textual no basta: se necesita ejecución.

### 10.2 Verificación manual post-gate

```bash
git tag -l "v[nueva-versión]"
git log --oneline -3
head -30 CHANGELOG.md
```

## Paso 11 — Reporte final

```
=== Release v[nueva-versión] completado ===

Versión anterior: v[versión-anterior]
Nueva versión:    v[nueva-versión]
Tipo:             [PATCH | MINOR | MAJOR]

Archivos actualizados: [lista]
Git: Commit [hash], Tag v[nueva-versión]
Commits incluidos: [N] (feat: [N], fix: [N], otros: [N])
Tests: [ejecutados OK | omitidos (--skip-tests)]

Próximos pasos:
  1. Revisar RELEASE-NOTES-v[nueva-versión].md
  2. git push origin v[nueva-versión]
  3. Publicar release en GitHub/GitLab si aplica
  4. Notificar al equipo
```

## Reglas de comportamiento

- NUNCA crear release con repositorio dirty.
- NUNCA omitir actualización de archivos de versión — inconsistencias causan errores de build.
- NUNCA usar `--skip-tests` sin documentarlo en CHANGELOG y sin confirmación.
- Si tipo calculado es MAJOR pero usuario pidió --tipo=patch, reportar discrepancia y esperar confirmación.
- CHANGELOG legible por alguien que no conoce el código.
- Si es monorepo, reportar que no se soporta y sugerir lerna/changesets.
