Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions .github/workflows/PLAN_CORRECCION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Plan de corrección de workflows de GitHub Actions

Este plan resume las acciones necesarias para corregir y optimizar los workflows bajo `.github/workflows/`, priorizando triggers completos (`push`, `pull_request`, `workflow_dispatch`), permisos mínimos, caching de dependencias, matrices de pruebas y controles de seguridad.

## Principios generales
- **Triggers consistentes**: cada workflow debe soportar `push`, `pull_request` y `workflow_dispatch` salvo que exista una restricción explícita.
- **Permisos mínimos**: definir `permissions` explícitos a nivel de workflow con el mínimo necesario (p. ej., `contents: read`, `pull-requests: write` solo cuando aplique).
- **Caching**: habilitar `actions/cache` o cachés nativas (pip/npm) según el stack para reducir tiempos.
- **Matrices de pruebas**: cubrir versiones soportadas (Python 3.10-3.12, Node 18-20) y SO donde aplique.
- **Seguridad**: fijar versiones de acciones (SHA/digest cuando aplique), evitar secretos inline y añadir `concurrency` para evitar solapes.
- **Observabilidad**: añadir upload de artefactos y resultados (coverage, logs) cuando aporte valor al debug.

## Estrategia por ambiente (producción, QA y desarrollo)
- **Workflows por entorno**: definir tres pipelines alineados a ramas y entornos (`main` → producción, `release/*` o `qa/*` → QA, `develop` → desarrollo). Cada pipeline debe heredar los principios generales anteriores.
- **Configuración diferenciada**:
- **Producción**: jobs protegidos con `environment: production`, `concurrency` por tag o ref, `required_reviewers`/`protection rules`, y despliegue mediante MCP/Codex; ejecución en `push` a `main` + `workflow_dispatch` con inputs para rollback.
- **QA**: `environment: qa` con despliegue a entornos de staging, tests extendidos (smoke + integración), matrices completas de versiones, y `concurrency` por rama de release; triggers en `push` a `qa/*` y `workflow_dispatch` para validaciones manuales.
- **Desarrollo**: `environment: development` orientado a feedback rápido (lint + unit + cobertura), caching agresivo y matrices mínimas; triggers en `push`/`pull_request` hacia `develop` y `workflow_dispatch` opcional.
- **Notificaciones**: usar comentarios en PR/commit status en lugar de Slack; habilitar `actions/github-script` para anotar fallos por entorno.
- **Variables y secretos**: centralizar variables comunes en `env` y secretos por entorno en `environment secrets`; validar su presencia con `if: env.SECRET != ''` antes de usarlos.
- **Plantillas reutilizables**: crear un workflow reusable (p. ej., `.github/workflows/reusable-ci.yml`) con matrices, caching y permisos mínimos, que reciba como inputs el entorno (`environment`), la rama y el modo (`deploy`/`validate`).

## Acciones transversales
1. Añadir plantilla base reutilizable para permisos mínimos y estrategia de caching (composite o reusable workflow).
2. Incorporar `concurrency` para despliegue, incident-response y pipelines largos.
3. Revisar secretos: documentar requeridos y validar existencia antes de usarlos (ej. `if: env.SECRET != ''`).
4. Añadir validaciones de seguridad ligeras (Semgrep/Trivy) en ramas principales si no duplican CodeQL.
5. Documentar en README de workflows los triggers esperados y variables.

## Acciones por workflow
- **actionlint.yml**: fijar digest del contenedor y añadir cache para dependencias de verificación si aplica.
- **agents-ci.yml**: añadir `permissions` mínimos; declarar `CODECOV_TOKEN` como `env` opcional con guardas; revisar que `bandit` falle en hallazgos críticos y habilitar cache pip.
- **backend-ci.yml**: agregar `workflow_dispatch`; definir permisos mínimos; usar secretos no triviales para MySQL y cerrar puerto con `ports: ["3306:3306"]` solo si es estrictamente necesario; cache pip y matriz de Python 3.10-3.12; añadir `concurrency` por ref.
- **code-quality.yml**: incluir `push` y `workflow_dispatch`; permisos mínimos; cache según herramienta (npm/pip); revisar matrices si hay múltiples linters.
- **codeql.yml**: agregar `workflow_dispatch`; permisos mínimos (`security-events: write`, `contents: read`); cache de dependencias del lenguaje y fijar versiones de `actions/checkout`/`setup-*` por SHA.
- **dependency-review.yml**: añadir `push` y `workflow_dispatch`; permisos mínimos (`contents: read`); documentar política de bloqueo.
- **deploy.yml**: habilitar `pull_request` (dry-run), permisos mínimos; reusar artefactos de build con checksum; cache de dependencias; añadir `concurrency` por entorno y validaciones previas.
- **docs-validation.yml**: sumar `workflow_dispatch`; permisos mínimos; cache pip y Sphinx; paralelizar validaciones si posible.
- **docs.yml**: incorporar cache de dependencias y `concurrency` por ref; revisar publicación segura (sin write innecesario).
- **emoji-validation.yml**: añadir `workflow_dispatch` y permisos mínimos; cache de dependencias y fijar versiones de acciones.
- **frontend-ci.yml**: agregar `workflow_dispatch` y permisos mínimos; cache npm/pnpm; matriz Node 18-20; considerar `concurrency` por ref.
- **incident-response.yml**: sumar `push`/`pull_request` si aplica; permisos mínimos; cache de herramientas; añadir `concurrency` para evitar ejecuciones paralelas.
- **infrastructure-ci.yml**: añadir `workflow_dispatch`; permisos mínimos; cache de proveedores/Terraform; proteger `terraform apply` con `environment`; validar backend remoto.
- **lint.yml**: agregar `workflow_dispatch`; permisos mínimos; cache de dependencias; fijar versiones de acciones.
- **meta-architecture-check.yml**: definir permisos mínimos; cache de dependencias; fijar versiones.
- **migrations.yml**: añadir `workflow_dispatch`; permisos mínimos; eliminar credenciales inline (`testpass`); cerrar puertos o usar servicios internos; cache pip; considerar matrices de DB si soportadas.
- **pr-review.yml**: evaluar añadir `push`/`pull_request` o mantener sólo comentario pero con filtro `if: github.event.issue.pull_request` para limitar; cache dependencias; revisar permisos mínimos.
- **python_ci.yml**: definir permisos mínimos; cache pip; añadir `concurrency`; ampliar matriz Python 3.10-3.12.
- **release.yml**: incluir `pull_request` (dry-run); permisos explícitos; verificar integridad de artefactos; cache dependencias; añadir `concurrency` por versión/tag.
- **requirements_index.yml**: añadir cache pip y matriz Python adicional; mantener permisos explícitos.
- **requirements_validate_traceability.yml**: definir permisos mínimos; cache pip; fijar acciones.
- **security-scan.yml**: sumar `workflow_dispatch`; permisos mínimos; cache cuando sea seguro; fijar versiones y limitar scope de escaneos.
- **sync-docs.yml**: agregar `push`/`pull_request`; permisos mínimos; validar PAT/SSH presentes; cache dependencias; añadir `concurrency`.
- **test-pyramid.yml**: añadir `workflow_dispatch`; permisos mínimos; cache pip; ampliar matriz Python; fijar acciones.
- **validate-guides.yml**: definir permisos mínimos; cache dependencias; fijar versiones de acciones.

## Entregables
- PRs incrementales por workflow o por categoría (permisos, triggers, caching) para reducir riesgo.
- Documentación de cambios y secretos requeridos en cada PR.
81 changes: 81 additions & 0 deletions .github/workflows/SELF_HOSTED_RUNNER.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# Guía para configurar y operar un self-hosted runner

Esta guía resume **ventajas**, **requisitos** y un **procedimiento endurecido** para instalar un runner autoalojado de GitHub Actions en Linux (ARM64 o x86_64), partiendo de los pasos iniciales que compartiste y agregando controles de seguridad y operatividad.

## Ventajas clave
- **Aislamiento y control**: eliges el sistema operativo, endureces el host (AppArmor/SELinux, firewall) y mantienes los secretos fuera de la infraestructura de GitHub.
- **Dependencias precargadas**: instala toolchains pesados (Android SDK, Docker, CUDA, browsers) y evita reinstalarlos en cada job, reduciendo tiempos y variabilidad.
- **Reducción de costos**: aprovecha hardware propio o reservado, optimiza cachés (npm/pip/gradle), y minimiza minutos facturados en runners hospedados.
- **Conectividad interna**: habilita pruebas y despliegues contra recursos privados (bases de datos, brokers, servicios internos) sin exponerlos a internet.
- **Previsibilidad de performance**: hardware dedicado evita throttling; puedes fijar límites de CPU/RAM por job con cgroups.
- **Flexibilidad de etiquetado**: usa labels (`self-hosted`, `arm64`, `gpu`, `infra`) para enrutar jobs a capacidades específicas.

## Requisitos previos
- Usuario de sistema exclusivo para el runner (sin privilegios de login interactivo ni sudo innecesario).
- Acceso de red saliente a `github.com` y `objects.githubusercontent.com`; sin puertos entrantes abiertos.
- `curl`, `tar`, `shasum`, `systemd` (para servicio), y permisos para abrir puertos salientes 443.
- Token de registro efímero generado desde GitHub (**Settings → Actions → Runners → New self-hosted runner**) con caducidad corta.
- Espacio en disco para cachés (recomendado ≥ 20 GB) y, si usas Docker, cgroups v2 habilitado.

## Instalación paso a paso (Linux)
1. **Preparar usuario y carpeta**
```bash
sudo useradd --create-home --shell /usr/sbin/nologin ghactions
sudo mkdir -p /opt/actions-runner && sudo chown ghactions:ghactions /opt/actions-runner
cd /opt/actions-runner
```
2. **Descargar binarios del runner** (ajusta la versión según [releases oficiales](https://github.com/actions/runner/releases)). Ejemplo ARM64:
```bash
curl -o actions-runner-linux-arm64-2.329.0.tar.gz -L \
https://github.com/actions/runner/releases/download/v2.329.0/actions-runner-linux-arm64-2.329.0.tar.gz
Comment on lines +27 to +30
Copy link

Copilot AI Nov 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The checksum provided appears to be for a specific runner version (v2.329.0). However, this checksum should be verified against the official GitHub releases page before use. Additionally, consider adding a note that users should always verify checksums match the official release notes for the version they're downloading.

Suggested change
2. **Descargar binarios del runner** (ajusta la versión según [releases oficiales](https://github.com/actions/runner/releases)). Ejemplo ARM64:
```bash
curl -o actions-runner-linux-arm64-2.329.0.tar.gz -L \
https://github.com/actions/runner/releases/download/v2.329.0/actions-runner-linux-arm64-2.329.0.tar.gz
2. **Descargar binarios del runner** (ajusta la versión según [releases oficiales](https://github.com/actions/runner/releases)). Ejemplo ARM64:
> ⚠️ **IMPORTANTE:** Antes de ejecutar la verificación de checksum, obtén el valor SHA256 correspondiente a la versión elegida desde la [página oficial de releases](https://github.com/actions/runner/releases) y reemplaza el ejemplo de abajo. No uses el checksum sin verificar que coincide con el binario descargado.
```bash
curl -o actions-runner-linux-arm64-2.329.0.tar.gz -L \
https://github.com/actions/runner/releases/download/v2.329.0/actions-runner-linux-arm64-2.329.0.tar.gz
# Reemplaza el siguiente checksum por el publicado en la release oficial para tu versión:

Copilot uses AI. Check for mistakes.
echo "56768348b3d643a6a29d4ad71e9bdae0dc0ef1eb01afe0f7a8ee097b039bfaaf actions-runner-linux-arm64-2.329.0.tar.gz" | \
shasum -a 256 -c
tar xzf actions-runner-linux-arm64-2.329.0.tar.gz
```
3. **Configurar el runner con token efímero** (reemplaza `<TOKEN>`):
```bash
sudo -u ghactions ./config.sh \
--url https://github.com/<ORG>/<REPO> \
--token <TOKEN> \
--name "iact-arm64-01" \
--labels "self-hosted,arm64,ci" \
--unattended
```
5. **Endurecimiento recomendado**
- Limita permisos del usuario `ghactions` (sin sudo; agrega a `docker` solo si es necesario).
- Habilita firewall saliente con allow-list a GitHub; bloquea puertos entrantes.
- Activa actualizaciones automáticas del runner (`./svc.sh install` ya habilita `svc.sh self-update`).
- Limpia artefactos y cachés periódicamente (`actions-runner/_work/_tool`, `actions-runner/_work/*`).
- Si usas Docker, habilita `--mtu` correcto y `--log-driver json-file --log-opt max-size=100m` para evitar llenado de disco.

## Uso en workflows
Ejemplo de job apuntando al runner etiquetado:
```yaml
jobs:
tests:
runs-on: [self-hosted, arm64, ci]
steps:
- uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Run tests
run: make test
```

## Operación y mantenimiento
- **Auto-update**: revisar `systemctl status ...` y logs en `/opt/actions-runner/_diag/`. Reinstala si la versión queda obsoleta.
- **Rotación de token**: si comprometes el host, revoca el runner en GitHub y regenera token.
- **Observabilidad**: expone métricas con `promtail`/`node_exporter` si el entorno lo permite; monitorea disco (`df -h`) y memoria.
- **Resiliencia**: usa al menos dos runners por etiqueta crítica para evitar cuellos de botella; considera `--ephemeral` si necesitas aislamiento fuerte por job.

## Limpieza/Desregistro
Para quitar el runner:
```bash
sudo systemctl stop actions.runner.2-Coatl-IACT.iact-arm64-01.service
Copy link

Copilot AI Nov 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The service name in the systemctl commands is hardcoded with "2-Coatl-IACT". This should be replaced with a placeholder to match the previous recommendation, ensuring users understand they need to substitute their actual organization and repository names.

Copilot uses AI. Check for mistakes.
sudo ./svc.sh uninstall
sudo -u ghactions ./config.sh remove --token <TOKEN>
```

> Mantén este archivo junto a los workflows para que cualquier operador pueda replicar la instalación siguiendo prácticas seguras y actualizadas.
74 changes: 74 additions & 0 deletions WORKFLOW_AUDIT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# GitHub Actions Workflow Audit

## Inventory
| Workflow | Triggers | Jobs | Cache (actions/cache) | Explicit permissions |
| --- | --- | ---: | :---: | :---: |
| actionlint.yml | push, pull_request, workflow_dispatch | 1 | No | Yes |
| agents-ci.yml | push, pull_request, workflow_dispatch | 7 | No | No |
| backend-ci.yml | push, pull_request | 6 | Yes | No |
| code-quality.yml | pull_request, workflow_dispatch | 1 | No | No |
| codeql.yml | push, pull_request, schedule | 1 | No | No |
| dependency-review.yml | pull_request | 1 | No | No |
| deploy.yml | push, workflow_dispatch | 7 | No | No |
| docs-validation.yml | pull_request, push | 6 | No | No |
| docs.yml | push, pull_request, workflow_dispatch | 3 | No | Yes |
| emoji-validation.yml | pull_request, push | 1 | No | No |
| frontend-ci.yml | push, pull_request | 8 | No | No |
| incident-response.yml | workflow_dispatch | 5 | No | No |
| infrastructure-ci.yml | push, pull_request | 7 | No | No |
| lint.yml | pull_request, push | 1 | No | No |
| meta-architecture-check.yml | pull_request, push, workflow_dispatch | 2 | No | No |
| migrations.yml | pull_request, push | 5 | No | No |
| pr-review.yml | issue_comment | 1 | No | Yes |
| python_ci.yml | push, pull_request, workflow_dispatch | 5 | No | No |
| release.yml | push, workflow_dispatch | 7 | No | Yes |
| requirements_index.yml | push, pull_request, workflow_dispatch | 1 | No | Yes |
| requirements_validate_traceability.yml | pull_request, push, workflow_dispatch | 1 | No | No |
| security-scan.yml | push, pull_request, schedule | 11 | No | No |
| sync-docs.yml | schedule, workflow_dispatch | 2 | No | No |
| test-pyramid.yml | push, pull_request, schedule | 3 | No | No |
| validate-guides.yml | pull_request, push, workflow_dispatch | 5 | No | No |

## Quick findings
- Total workflows: 25.
- Workflows with `workflow_dispatch`: 13/25.
- Missing `workflow_dispatch`: backend-ci.yml, codeql.yml, dependency-review.yml, docs-validation.yml, emoji-validation.yml, frontend-ci.yml, infrastructure-ci.yml, lint.yml, migrations.yml, pr-review.yml, security-scan.yml, test-pyramid.yml
- Missing `push` trigger: code-quality.yml, dependency-review.yml, incident-response.yml, pr-review.yml, sync-docs.yml
- Missing `pull_request` trigger: deploy.yml, incident-response.yml, pr-review.yml, release.yml, sync-docs.yml
- Lacking explicit top-level `permissions`: agents-ci.yml, backend-ci.yml, code-quality.yml, codeql.yml, dependency-review.yml, deploy.yml, docs-validation.yml, emoji-validation.yml, frontend-ci.yml, incident-response.yml, infrastructure-ci.yml, lint.yml, meta-architecture-check.yml, migrations.yml, python_ci.yml, requirements_validate_traceability.yml, security-scan.yml, sync-docs.yml, test-pyramid.yml, validate-guides.yml
- Workflows without `actions/cache`: actionlint.yml, agents-ci.yml, code-quality.yml, codeql.yml, dependency-review.yml, deploy.yml, docs-validation.yml, docs.yml, emoji-validation.yml, frontend-ci.yml, incident-response.yml, infrastructure-ci.yml, lint.yml, meta-architecture-check.yml, migrations.yml, pr-review.yml, python_ci.yml, release.yml, requirements_index.yml, requirements_validate_traceability.yml, security-scan.yml, sync-docs.yml, test-pyramid.yml, validate-guides.yml

## Recommendations
- Add `workflow_dispatch` to workflows that currently only run on PR/push to enable manual runs during incidents or hotfix validation.
- Define explicit, least-privilege `permissions` blocks to avoid default write scopes (e.g., contents: read, pull-requests: write only where needed).
- Introduce dependency caching where missing (pip, npm, etc.) to speed up jobs; most workflows reinstall dependencies from scratch.
- Expand test matrices for Python/Node where appropriate (e.g., backend/agents run single Python 3.11, frontend fixed to Node 18).
- Consider a lightweight security gate (e.g., Semgrep or Trivy) on push to main/develop to complement existing CodeQL and security scans.
- Add concurrency keys to long-running workflows (deploy, incident-response) to prevent overlapping runs per ref/environment.

## Per-workflow issues and gaps
- **actionlint.yml**: Uses explicit permissions and manual trigger is present, but there is no caching and the Docker action is not pinned to a digest.
- **agents-ci.yml**: Lacks an explicit permissions block, requires `CODECOV_TOKEN` to run coverage uploads, and the Bandit step ignores findings by design (`|| true`).
- **backend-ci.yml**: Missing `workflow_dispatch`; no permissions block; database service uses default MySQL root credentials and exposes 3306.
- **code-quality.yml**: Only runs on `pull_request` and `workflow_dispatch` is absent; no explicit permissions; no dependency caching.
- **codeql.yml**: Lacks `workflow_dispatch`; permissions not explicitly narrowed for code scanning upload; no cache for Python setup.
- **dependency-review.yml**: Only trigger is `pull_request`; no manual trigger; permissions block present but default read/write not narrowed to minimal contents/read.
- **deploy.yml**: Does not run on `pull_request`; no permissions block; re-runs full test suite without caching, slowing deployments.
- **docs-validation.yml**: Missing `workflow_dispatch` and explicit permissions; no caching for Python or Sphinx deps.
- **docs.yml**: Triggers are complete and permissions are explicit, but there is no dependency cache and no concurrency control for doc publishes.
- **emoji-validation.yml**: Missing manual trigger; no permissions block; re-installs dependencies every run.
- **frontend-ci.yml**: Missing `workflow_dispatch`; no permissions block; npm/node dependencies are not cached and only Node 18 is covered.
- **incident-response.yml**: Manual-only trigger with no `push`/`pull_request`; lacking permissions block and dependency caching.
- **infrastructure-ci.yml**: Missing `workflow_dispatch` and permissions block; Terraform steps lack a backend/cache and may need environment protection.
- **lint.yml**: Missing `workflow_dispatch` and permissions block; no caching for lint dependencies.
- **meta-architecture-check.yml**: Triggers present, but no permissions block and no dependency caching.
- **migrations.yml**: Missing `workflow_dispatch`; no permissions block; seeds data with inline secrets (`testpass`) and exposes MySQL port 3306.
- **pr-review.yml**: Triggered only by `issue_comment` with no `push`/`pull_request`; permissions are constrained but there is no validation to limit to PR comments; no caching.
- **python_ci.yml**: Triggers present but lacks permissions block; no cache for Python dependencies and no concurrency control.
- **release.yml**: No `pull_request` trigger; permissions rely on defaults; reuses build artifacts without checksum verification.
- **requirements_index.yml**: Triggers present and permissions explicit, but there is no cache and the Python job runs only on a single version.
- **requirements_validate_traceability.yml**: Triggers present but no permissions block; no dependency caching.
- **security-scan.yml**: Missing `workflow_dispatch` and permissions block; no caching and uses broad third-party actions without digests.
- **sync-docs.yml**: Missing `push`/`pull_request` triggers; no permissions block; relies on PAT/SSH secrets without validation and lacks caching.
- **test-pyramid.yml**: Missing `workflow_dispatch`; no permissions block; Python jobs reuse `pip install` without cache and matrix lacks latest versions.
- **validate-guides.yml**: Triggers are complete, but permissions are not explicit and there is no dependency caching.
Loading