# 📦 Fase 5 — Publicación
## 🤔 ¿Qué hago? ¿Cómo lo hago? ¿Y para qué lo hago?
### ¿Qué hago?
Publico Klaus-antipatterns-search como **herramienta de distribución open-source**: binarios pre-compilados para todas las plataformas disponibles en GitHub Releases, `action.yml` actualizado para descargar el binario en vez de compilar desde fuente, y documentación de instalación lista para usuarios externos.
### ¿Cómo lo hago?
1. 🏗️ **GoReleaser** — `.goreleaser.yml` cross-compila para linux/darwin/windows × amd64/arm64, genera archives tar.gz/zip y publica en GitHub Releases con checksums SHA-256.
2. 🔁 **Release workflow** — `.github/workflows/release.yml` se dispara con cualquier tag `v*`, ejecuta tests antes de publicar y llama a GoReleaser.
3. ⬇️ **action.yml renovado** — el paso de build (`setup-go` + `go build`) se sustituye por un paso de descarga que: detecta OS/arch, resuelve la versión correcta, descarga el archive, verifica el checksum y extrae el binario al PATH.
4. 📚 **README** — nueva sección "Instalación" con instrucciones para GitHub Action, binario curl y `go install`.
### ¿Para qué lo hago?
- **Velocidad en CI**: descargar un binario de ~5 MB tarda ~2 segundos; compilar desde fuente con `go build` puede tardar 30-60 segundos incluyendo `setup-go` y descarga de módulos.
- **Reproducibilidad**: la acción pinada a `@v1.0.0` ejecuta exactamente ese binario, no lo que estuviera en `main` cuando alguien hizo push.
- **Adopción externa**: cualquier organización puede usar la herramienta sin tener Go instalado.
---
## 🏗️ Arquitectura de publicación
```mermaid
graph TD
DEV["👨💻 Developer\ngit tag v1.0.0\ngit push --tags"] --> GHA["⚙️ GitHub Actions\nrelease.yml"]
GHA --> TEST["🧪 go test -race ./..."]
TEST -->|✅ pasa| GR["🚀 GoReleaser"]
TEST -->|❌ falla| STOP["🛑 Release bloqueada"]
GR --> BUILD["🔨 go build\nCGO_ENABLED=0"]
BUILD --> L1["linux/amd64"]
BUILD --> L2["linux/arm64"]
BUILD --> D1["darwin/amd64"]
BUILD --> D2["darwin/arm64"]
BUILD --> W1["windows/amd64"]
L1 & L2 & D1 & D2 --> TAR["📦 .tar.gz\n(antipatterns + README + LICENSE)"]
W1 --> ZIP["📦 .zip"]
TAR & ZIP --> CHKSUM["🔐 SHA-256 checksums.txt"]
TAR & ZIP & CHKSUM --> RELEASE["🏷️ GitHub Release\nvX.Y.Z"]
RELEASE --> ACTION["🎬 action.yml\nconsumidores"]
RELEASE --> CURL["💻 curl install\nusuarios directos"]
RELEASE --> GOINST["🐹 go install\ndesarrolladores Go"]
```
---
## 🔁 Release workflow — `.github/workflows/release.yml`
| Paso | Descripción |
| --- | --- |
| `actions/checkout@v4` | Clone completo (`fetch-depth: 0`) para changelog automático |
| `actions/setup-go@v5` | Go 1.22 con caché activado |
| `go test -race ./...` | Gate de calidad: si fallan tests, no hay release |
| `goreleaser/goreleaser-action@v6` | Compila, empaqueta y publica en GitHub Releases |
```yaml
on:
push:
tags:
- 'v[0-9]*' # Solo tags de versión
permissions:
contents: write # Necesario para crear GitHub Release
```
> 🚨 **Nunca** hacer push de un tag sin haber mergeado el código a `main`. El tag debe apuntar a un commit en `main` revisado y aprobado.
---
## ⚙️ GoReleaser — `.goreleaser.yml`
### Targets de compilación
| OS | Arch | Archivo |
| --- | --- | --- |
| linux | amd64 | `antipatterns_X.Y.Z_linux_amd64.tar.gz` |
| linux | arm64 | `antipatterns_X.Y.Z_linux_arm64.tar.gz` |
| darwin | amd64 | `antipatterns_X.Y.Z_darwin_amd64.tar.gz` |
| darwin | arm64 | `antipatterns_X.Y.Z_darwin_arm64.tar.gz` |
| windows | amd64 | `antipatterns_X.Y.Z_windows_amd64.zip` |
> `CGO_ENABLED=0` — compilación puramente estática, sin dependencias del sistema en runtime.
### Artefactos publicados por release
```text
antipatterns_1.0.0_linux_amd64.tar.gz
antipatterns_1.0.0_linux_arm64.tar.gz
antipatterns_1.0.0_darwin_amd64.tar.gz
antipatterns_1.0.0_darwin_arm64.tar.gz
antipatterns_1.0.0_windows_amd64.zip
antipatterns_1.0.0_checksums.txt ← SHA-256 de todos los anteriores
```
### Inyección de versión
```text
-X main.version={{.Version}}
```
Disponible en runtime vía `antipatterns version`.
---
## ⬇️ `action.yml` — Estrategia de descarga
### Lógica de resolución de versión
```mermaid
graph TD
START["⬇️ Download step"] --> REF{"action_ref\n= vX.Y.Z?"}
REF -->|sí| PINTAG["VERSION = ref\nPinned tag"]
REF -->|no| INP{"inputs.version\n≠ 'latest'?"}
INP -->|sí| PINVER["VERSION = inputs.version"]
INP -->|no| API["GitHub API\n/releases/latest"]
API --> LATEST["VERSION = tag_name\n(latest release)"]
PINTAG & PINVER & LATEST --> DL["curl archive + checksums"]
DL --> VERIFY["sha256sum --check"]
VERIFY -->|✅| EXTRACT["tar -xzf → RUNNER_TEMP"]
VERIFY -->|❌| FAIL["exit 1\nChecksum mismatch"]
EXTRACT --> PATH["echo RUNNER_TEMP >> GITHUB_PATH"]
```
### Cambios respecto a Fase 3
| Fase 3 | Fase 5 |
| --- | --- |
| `setup-go@v5` (descarga Go ~300 MB) | ❌ eliminado |
| `go build ./cmd/antipatterns` (~30-60s) | ❌ eliminado |
| Sin verificación de integridad | ✅ checksum SHA-256 |
| Input `go-version` | → Input `version` |
### Compatibilidad
```yaml
# Forma recomendada — pinned tag, descarga esa versión exacta:
- uses: Ka0s-Klaus/Klaus-antipatterns-search@v1.0.0
# Con version explícita (override):
- uses: Ka0s-Klaus/Klaus-antipatterns-search@main
with:
version: '1.0.0'
# Siempre la última release (no recomendado en producción):
- uses: Ka0s-Klaus/Klaus-antipatterns-search@main
with:
version: 'latest'
```
---
## 📚 Instalación para usuarios
### GitHub Action (CI/CD)
```yaml
jobs:
quality:
runs-on: ubuntu-latest
permissions:
contents: read
security-events: write
pull-requests: write
steps:
- uses: actions/checkout@v4
- uses: Ka0s-Klaus/Klaus-antipatterns-search@v1.0.0
with:
path: .
upload-sarif: 'true'
comment-pr: 'true'
```
### Binario directo (curl)
```bash
# linux/amd64
VERSION=$(curl -sSf https://api.github.com/repos/Ka0s-Klaus/Klaus-antipatterns-search/releases/latest \
| jq -r '.tag_name | ltrimstr("v")')
curl -sSfL \
"https://github.com/Ka0s-Klaus/Klaus-antipatterns-search/releases/download/v${VERSION}/antipatterns_${VERSION}_linux_amd64.tar.gz" \
| tar -xzf - antipatterns
sudo mv antipatterns /usr/local/bin/
# Verificar
antipatterns version
```
### `go install`
```bash
go install github.com/Ka0s-Klaus/Klaus-antipatterns-search/cmd/antipatterns@latest
```
---
## 🏷️ Convención de versiones
Este proyecto sigue [Semantic Versioning 2.0.0](https://semver.org):
| Tipo | Cuándo | Ejemplo |
| --- | --- | --- |
| **Patch** (Z) | Bug fixes, mejoras menores de detectores | `v1.0.1` |
| **Minor** (Y) | Nuevos detectores, nuevas features sin breaking change | `v1.1.0` |
| **Major** (X) | Cambios en la API del CLI, modelo Finding, action inputs | `v2.0.0` |
### Proceso de release
```bash
# 1. Asegurarse de estar en main con todo mergeado
git checkout main && git pull
# 2. Crear y subir el tag
git tag v1.0.0 -m "Release v1.0.0 — publicación inicial"
git push origin v1.0.0
# 3. El workflow release.yml se dispara automáticamente
# 4. Verificar en: https://github.com/Ka0s-Klaus/Klaus-antipatterns-search/releases
```
---
## 🔒 Seguridad
- **No hay token hardcodeado** en ningún artefacto — `GITHUB_TOKEN` lo inyecta GitHub Actions automáticamente.
- **Checksum SHA-256** verificado en `action.yml` antes de ejecutar el binario descargado.
- **CGO_ENABLED=0** — binarios sin dependencias nativas, sin vectores de ataque de dynamic linking.
- **Tests obligatorios antes del release** — si algún test falla, el pipeline se detiene antes de publicar.
- **`prerelease: auto`** en goreleaser — tags con `-alpha`, `-beta`, `-rc` se marcan como pre-release automáticamente.
---
## 🧪 Validación post-publicación (Fase 6)
Tras publicar `v1.0.0`, se añadió un **integration test end-to-end** que verifica que la action funciona correctamente en un runner real de GitHub:
- **Thresholds calibrados** en `.antipatterns.yml`: `function_loc: 80 → 40`, `cyclomatic: 15 → 10`
- **Auto-escaneo** del propio repo contra `Ka0s-Klaus/Klaus-antipatterns-search@v1.0.0` — 16 findings detectados
- **SARIF validado** por `github/codeql-action/upload-sarif@v4` (actualizado desde v3)
- Workflow: `.github/workflows/test-action.yml`
Ver [Fase 6 — Integration Test](fase-6-integration-test.md) para el detalle completo.
---
## 🔗 Documentos relacionados
- [Multi-org Scanner (Fase 4)](fase-4-multi-org.md) — `scan-org` que consume el binario publicado
- [SARIF + GitHub Action (Fase 3)](fase-3-sarif-action.md) — versión anterior de `action.yml` (referencia)
- [Integration Test (Fase 6)](fase-6-integration-test.md) — validación end-to-end de la action publicada
- [README principal](../README.md) — instrucciones de instalación para usuarios finales