Files
platform-templates/pipelines/archetype-nextjs-frontend
devops a3c022c024 docs: READMEs completos, estructura final de arquetipos
Mueve los reusable workflows a .gitea/workflows/ (restriccion real de
Gitea: workflow_call no puede vivir en una ruta arbitraria, confirmado
en vivo). Corrige todos los 'uses:' cross-repo a URL absoluta
(https://gitea.cruzcloud.net/...) -- la forma corta de GitHub se
resuelve contra github.com en esta instancia, confirmado en vivo con un
test real (reusable workflow + composite action ejecutando gitleaks de
punta a punta). Limpia los archivos de prueba.
2026-08-17 00:23:24 -05:00
..

Arquetipo: Next.js frontend (standalone)

Cuándo usar este arquetipo: tu app es un frontend Next.js que compila a output: 'standalone' y sirve HTML renderizado en servidor (SSR/RSC), no un sitio 100% estático. Si es 100% estático, usá archetype-static-site en cambio — es más liviano.

Qué asume de tu repo:

  • Un Dockerfile en app_dir basado en (o compatible con) dockerfiles/nextjs.Dockerfile — específicamente, que next.config.* tiene output: 'standalone'.
  • Un endpoint /api/health que devuelva 200 — lo usan tanto el HEALTHCHECK del Dockerfile como las probes de k8s-manifests/base/deployment.yaml.
  • cosign.pub commiteado en app_dir (par de la llave privada que firma en el pipeline).
  • Un manifiesto K8s (manifest_file) con una línea image: <tu-imagen>:vX.Y.Z que el pipeline actualiza automáticamente tras cada build exitoso (promoción GitOps).

Dónde vive el archivo real

Importante, no es donde dice el nombre de esta carpeta: el reusable workflow en sí (workflow_call) tiene que vivir bajo .gitea/workflows/ por una restricción real de Gitea Actions — no se puede invocar un workflow_call desde una ruta arbitraria como pipelines/algo/x.yaml (confirmado en vivo, error real del servidor: "uses:" path "..." must be under a configured workflow directory). El archivo real es:

.gitea/workflows/archetype-nextjs-frontend.yaml

Esta carpeta (pipelines/archetype-nextjs-frontend/) es solo documentación — el README que estás leyendo.

Cómo usarlo desde tu repo

En .gitea/workflows/build.yaml de tu propio repo:

name: Build and Push

on:
  push:
    branches: [main]
    paths:
      - 'app/**'
      - '.gitea/workflows/build.yaml'

jobs:
  build:
    uses: https://gitea.cruzcloud.net/devops/platform-templates/.gitea/workflows/archetype-nextjs-frontend.yaml@main
    with:
      app_dir: app
      image_name: gitea.cruzcloud.net/devops/mi-app
      manifest_file: workloads/mi-app/deployment.yaml
      # semgrep_configs y trivy_ignorefile son opcionales, tienen default
    secrets:
      REGISTRY_USER: ${{ secrets.REGISTRY_USER }}
      REGISTRY_PASSWORD: ${{ secrets.REGISTRY_PASSWORD }}
      COSIGN_PRIVATE_KEY: ${{ secrets.COSIGN_PRIVATE_KEY }}
      COSIGN_PASSWORD: ${{ secrets.COSIGN_PASSWORD }}

OJO con el uses: — tiene que ser la URL completa https://gitea.cruzcloud.net/..., no la forma corta devops/platform-templates/... (esa se resuelve contra github.com por default en esta instancia, no contra Gitea local — confirmado en vivo, es la razón real por la que este repo usa URLs absolutas en todos los uses: internos también, no solo acá).

@main en vez de un tag/commit fijo: significa que tu pipeline siempre usa la ÚLTIMA versión del arquetipo. Cómodo para no tener que actualizar cada repo consumidor a mano, pero un cambio incompatible acá te rompe el pipeline sin aviso. Si preferís control explícito, fijá un tag (@v1.0.0) o un commit SHA en vez de @main — a costa de tener que actualizarlo vos cuando quieras el cambio nuevo.

Semgrep: por qué este ruleset

p/typescript,p/react,p/nextjs,p/security-audit — cubre el lenguaje, el framework de UI, Next.js específicamente (rutas, SSR), y reglas generales de seguridad. Si tu app usa algo más (GraphQL, un ORM específico), agregá el ruleset correspondiente al semgrep_configs del with:.

Modo auditoría por default

Igual que los 3 pipelines reales de los que sale este arquetipo: Semgrep y Trivy IaC corren pero NO bloquean por default (primera vuelta para revisar hallazgos antes de decidir qué debería bloquear). Trivy imagen (CRITICAL) sí bloquea siempre, no es opcional.